🔙 Quay lại trang tải sách pdf ebook Think Java: Cách Suy Nghĩ Như Nhà Khoa Học Máy Tính
Ebooks
Nhóm Zalo
Think Java: Cách suy nghĩ nh nhà khoa h c ư ọ máy tính
Phiên bản 5.1.2
Xem thêm ở Facebook.
Think Java là cuốn sách giới thiệu về lập trình Java cho
người mới học. Nó được soạn riêng cho học viên chuẩn bị
thi Computer Science Advanced Placement (AP) Exam,
nhưng cũng dành cho bất kì ai muốn học Java.
• Think Java rất ngắn gọn. Sách chỉ dùng một bộ phận nhỏ
của ngôn ngữ Java đủ để giúp học viên thực hiện những bài
tập lớn mà không bị sa đà vào những tiểu tiết của ngôn ngữ
lập trình.
• Think Java dạy cách phát triển và gỡ lỗi chương trình;
những chủ đề này được thảo luận trong suốt cuốn sách
và được tóm tắt trong hai phụ lục.
• Think Java bao gồm cả nghiên cứu cụ thể GridWorld vốn là
một phần của đề thi AP. Cuốn sách này cung cấp kiến thức
cơ sở cần để làm quen với GridWorld, cùng với những bài
tập phụ thêm để thực hành.
• Think Java được viết theo cuốn sách gốc How to Think
Like a Computer Scientist, một cuốn sách trực tuyến quen
thuộc với những phiên bản cho lập trình Python, C++ và
OCaml, cùng với những bản dịch sang tiếng Tây Ban Nha,
tiếng Pháp và những thứ tiếng khác.
Think Java là sách giáo trình t do đ c phát hành theo gi y phép ự ượ ấ Creative Commons Attribution NonCommercial-ShareAlike 3.0 Unported License. B n đ c có th tùy ý sao chép và phân ph i n i ạ ọ ể ố ộ dung trong sách; đ ng th i cũng tùy ý s a đ i đ phù h p v i yêu c u c th , và đ phát tri n n i dung ồ ờ ử ổ ể ợ ớ ầ ụ ể ể ể ộ
gi ng d y m i. ả ạ ớ
M c l c ụ ụ
Chương 1: Lối đi của chương trình máy tính Chương 2: Biến, biểu thức và câu lệnh Chương 3: Phương thức rống
Chương 4: Câu lệnh điều kiện và đệ quy Chương 5: GridWorld: Phần 1
Chương 6: Phương thức trả giá trị Chương 7: Lặp
Chương 8: Chuỗi kí tự
Chương 9: Đối tượng có thể biến đổi Chương 10: GridWorld: Phần 2
Chương 11: Tự tạo nên những đối tượng riêng Chương 12: Mảng
Chương 13: Mảng các đối tượng
Chương 14: Đối tượng chứa các mảng Chương 15: Lập trình hướng đối tượng Chương 16: Grid World: Phần 3
Phụ lục A: Đồ họa
Phụ lục B: Nhập và xuất dữ liệu ở Java Phụ lục C: Phát triển chương trình
Phụ lục D: Gỡ lỗi
Ch ng 0. L i nói đ u ươ ờ ầ
““Khi đ c h ng nh ng Thành qu l n t Phát minh c a ng i khác, ta nên vui v đó ượ ưở ữ ả ớ ừ ủ ườ ẻ nh n C h i đ giúp đ ng i khác b ng Phát minh c a ta, và vi c này nên làm m t cách t ậ ơ ộ ể ỡ ườ ằ ủ ệ ộ ự ý và hào phóng.”
—Benjamin Franklin, trích t cu n ừ ố Benjamin Franklin c a tác gi Edmund S. Morgan. ủ ả Lý do mà tôi vi t cu n sách này ế ố
Đây là n b n th năm c a cu n sách mà tôi đã b t đ u vi t t năm 1999, khi còn d y tr ng Colby ấ ả ứ ủ ố ắ ầ ế ừ ạ ở ườ College. Tôi d d y m t l p h c nh p môn khoa h c máy tính b ng ngôn ng Java, nh ng ch a tìm ẫ ạ ộ ớ ọ ậ ọ ằ ữ ư ư đ c m t cu n giáo trình v a ý. M t trong nh ng lý do là, chúng quá dày! Không có cách nào mà sinh ượ ộ ố ừ ộ ữ viên có th đ c h t cu n sách dày c 800 trang, đ y nh ng ki n th c kĩ thu t, k c tôi có yêu c u h ể ọ ế ố ỡ ầ ữ ế ứ ậ ể ả ầ ọ th c hi n. Mà tôi ch ng mu n th . Ph n l n nh ng gì vi t trong sách đ u quá c th —nh ng chi ti t v ự ệ ẳ ố ế ầ ớ ữ ế ề ụ ể ữ ế ề Java cùng các th vi n c a nó mà s l c h u ngay khi h c kì k t thúc, đ ng th i nh ng th đó s làm lu ư ệ ủ ẽ ạ ậ ọ ế ồ ờ ữ ứ ẽ m nh ng ki n th c mà tôi th c s mu n sinh viên h c. ờ ữ ế ứ ự ự ố ọ
M t v n đ khác mà tôi th y, đó là ph n gi i thi u l p trình h ng đ i t ng là quá đ t ng t. Nhi u ộ ấ ề ấ ầ ớ ệ ậ ướ ố ượ ộ ộ ề sinh viên đáng ra đã h c suôn s r i nh ng khi b t đ u vào ph n “đ i t ng” là b v p, b t k ph n này ọ ẻ ồ ư ắ ầ ầ ố ượ ị ấ ấ ể ầ đ c đ a vào đâu trong giáo trình. ượ ư
Vì v y tôi b t tay vào vi t. M i ngày tôi vi t m t ch ng, liên t c trong 13 ngày đ u. R i ngày th 14 tôi ậ ắ ế ỗ ế ộ ươ ụ ầ ồ ứ biên t p l i. Sau đó tôi đi phô-tô và đóng bìa. Bu i h c đ u tiên khi phân phát giáo trình, tôi d n sinh ậ ạ ổ ọ ầ ặ viên m i tu n ph i đ c m t ch ng. Nói cách khác, h c n đ c ch m h n 7 l n so v i t c đ vi t c a ỗ ầ ả ọ ộ ươ ọ ầ ọ ậ ơ ầ ớ ố ộ ế ủ tôi.
Tri t lý n sau cu n sách ế ẩ ố
Sau đây là m t s ý t ng đ nh hình cho cu n sách: ộ ố ưở ị ố
• Thu t ng là quan tr ng. Sinh viên c n ph i trao đ i đ c v ch ng trình máy tính và hi u đ c đi u ậ ữ ọ ầ ả ổ ượ ề ươ ể ượ ề tôi gi ng. Tôi c g ng gi i thi u m t s t i thi u các thu t ng , đ đ nh nghĩa đ c rõ ràng khi dùng l n ả ố ắ ớ ệ ộ ố ố ể ậ ữ ể ị ượ ầ đ u, và đ t ch c l i thành m c “Thu t ng ” cu i t ng ch ng. Trên l p, tôi có đ a nh ng câu h i liên ầ ể ổ ứ ạ ụ ậ ữ ố ừ ươ ớ ư ữ ỏ quan đ n thu t ng vào đ ki m tra, đ thi, và yêu c u sinh viên ph i dùng thu t ng thích h p đ vi t ế ậ ữ ề ể ề ầ ả ậ ữ ợ ể ế vào đáp án.
• Đ vi t m t ch ng trình, sinh viên c n ph i hi u đ c thu t toán, bi t ngôn ng l p trình, và có kh ể ế ộ ươ ầ ả ể ượ ậ ế ữ ậ ả năng g l i. Tôi nghĩ r ng quá nhi u quy n sách b qua khâu g l i. Cu n sách này có m t ph l c vi t ỡ ỗ ằ ể ể ỏ ỡ ỗ ố ộ ụ ụ ế v g l i và m t ph l c v phát tri n ch ng trình (giúp tránh đ c g l i). Tôi khuy n khích sinh viên ề ỡ ỗ ộ ụ ụ ề ể ươ ượ ỡ ỗ ế s m đ c ngay nh ng ph n này và th ng xuyên tham kh o đ n chúng. ớ ọ ữ ầ ườ ả ế
• M t s khái ni m ph i m t th i gian m i l ng đ ng l i đ c. M t s ch khó trong sách, nh đ quy, s ộ ố ệ ả ấ ờ ớ ắ ọ ạ ượ ộ ố ỗ ư ệ ẽ xu t hi n vài l n. B ng cách nêu l i nh ng đi m này, tôi c g ng t o cho sinh viên c h i đ ôn l i và ấ ệ ầ ằ ạ ữ ể ố ắ ạ ơ ộ ể ạ c ng c , ho c n u l n đ u h không n m đ c, thì đó là c h i đ theo k p. ủ ố ặ ế ầ ầ ọ ắ ượ ơ ộ ể ị
• Tôi c g ng dùng càng ít Java càng t t đ đ t đ c công hi u l p trình t i đa. M c đích c a cu n sách ố ắ ố ể ạ ượ ệ ậ ố ụ ủ ố này là d y l p trình và m t s ý t ng c b n v khoa h c máy tính, ch không ph i d y Java. Tôi b ạ ậ ộ ố ưở ơ ả ề ọ ứ ả ạ ỏ qua m t s đ c đi m c a ngôn ng này, nh l nh ộ ố ặ ể ủ ữ ư ệ switch, v n không c n thi t, và tránh h u h t các th ố ầ ế ầ ế ư
vi n ch ng trình, đ c bi t nh ng th vi n nh AWT v n đã thay đ i quá nhanh ho c có xu h ng l i ệ ươ ặ ệ ữ ư ệ ư ố ổ ặ ướ ỗ th i, ph i thay th . ờ ả ế
Ph ng pháp ti p c n theo xu h ng “t i thi u” nh v y có m t s u đi m. T ng ch ng ch dài ươ ế ậ ướ ố ể ư ậ ộ ố ư ể ừ ươ ỉ kho ng 10 trang, không k bài t p. Trên l p, tôi yêu c u sinh viên đ c m i ch ng tr c khi th o lu n, ả ể ậ ớ ầ ọ ỗ ươ ướ ả ậ và th y đ c r ng h s n sàng th c hi n và n m b t đ c l ng ki n th c. S chu n b tr c c a sinh ấ ượ ằ ọ ẵ ự ệ ắ ắ ượ ượ ế ứ ự ẩ ị ướ ủ viên đã giúp dành kho ng th i gian trên l p đ th o lu n nh ng n i dung tr u t ng h n, đ làm bài ả ờ ớ ể ả ậ ữ ộ ừ ượ ơ ể t p trên l p, và nh ng ch đ thêm không có trong sách. ậ ớ ữ ủ ề
Nh ng xu h ng “t i thi u” cũng có nh ng nh c đi m. Không có nhi u ch thú v v b n ch t. Đa s ư ướ ố ể ữ ượ ể ề ỗ ị ề ả ấ ố các ví d trong sách nh m minh h a cho cách s d ng c b n nh t c a ngôn ng , và nhi u bài t p có ụ ằ ọ ử ụ ơ ả ấ ủ ữ ề ậ liên quan đ n thao tác chu i kí t và khái ni m toán h c. Tôi nghĩ m t s bài thì thú v , song nh ng th ế ỗ ự ệ ọ ộ ố ị ữ ứ làm sinh viên thích ngành khoa h c máy tính, nh đ h a, âm thanh và ng d ng m ng, l i ch đ c ọ ư ồ ọ ứ ụ ạ ạ ỉ ượ gi i thi u qua loa. ớ ệ
V n đ n m ch ph n l n các đ c đi m thú v nh v y thì liên quan t i chi ti t v t mà ít liên quan đ n ấ ề ằ ở ỗ ầ ớ ặ ể ị ư ậ ớ ế ặ ế khái ni m. Xét trên khía c nh giáo d c, đi u này có nghĩa là nhi u công s c b ra đ thu đ c ít. Nh ệ ạ ụ ề ề ứ ỏ ể ượ ư v y có m t s tráo đ i gi a n i dung mà sinh viên a thích và n i dung mang đ m tri th c. Vi c gi cân ậ ộ ự ổ ữ ộ ư ộ ậ ứ ệ ữ b ng h p lý, tôi nh ng l i cho giáo viên đ ng l p. Đ giúp ph n nào, cu n sách này có ph l c đ c p ằ ợ ườ ạ ứ ớ ể ầ ố ụ ụ ề ậ đ n đ h a, nh p li u t bàn phím và t t p tin. ế ồ ọ ậ ệ ừ ừ ậ
L p trình h ng đ i t ng ậ ướ ố ượ
M t s quy n sách gi i thi u ngay khái ni m đ i t ng; l i có quy n d o đ u b ng phong cách l p trình ộ ố ể ớ ệ ệ ố ượ ạ ể ạ ầ ằ ậ th t c và d n d n xây d ng phong cách h ng đ i t ng. Cu n sách này thì theo l i “gi i thi u đ i ủ ụ ầ ầ ự ướ ố ượ ố ố ớ ệ ố t ng sau”. ượ
Nhi u đ c đi m h ng đ i t ng c a Java kh i ngu n t các v n đ đ t ra cho ngôn ng đi tr c, và ề ặ ể ướ ố ượ ủ ở ồ ừ ấ ề ặ ữ ướ cách th c hi n nh ng đ c đi m này ch u nh h ng b i quá trình l ch s . M t s đ c đi m r t khó gi i ự ệ ữ ặ ể ị ả ưở ở ị ử ộ ố ặ ể ấ ả thích n u ng i h c không th o nh ng bài toán c n gi i. ế ườ ọ ạ ữ ầ ả
Vi c hoãn l i kĩ thu t l p trình h ng đ i t ng không ph i là ch ý c a tôi. Trái l i, tôi c g ng t i đó ệ ạ ậ ậ ướ ố ượ ả ủ ủ ạ ố ắ ớ càng nhanh càng t t, song b h n ch b i ý mu n gi i thi u l n l t t ng khái ni m m t, th t rõ ràng, ố ị ạ ế ở ố ớ ệ ầ ượ ừ ệ ộ ậ theo cách mà sinh viên có th th c hành riêng t ng khái ni m tr c khi chuy n ti p. Nh ng cũng ph i ể ự ừ ệ ướ ể ế ư ả th a nh n r ng ph i m t m t th i gian h c m i đ n đ c ph n h ng đ i t ng. ừ ậ ằ ả ấ ộ ờ ọ ớ ế ượ ầ ướ ố ượ
Kì thi Computer Science AP
Theo l th ng, khi đ c bi t r ng H i đ ng tuy n sinh (College Board) công b r ng n i dung thi AP ẽ ườ ượ ế ằ ộ ồ ể ố ằ ộ s chuy n sang dùng Java, tôi đã có k ho ch c p nh t phiên b n Java c a cu n sách này. Đ i chi u v i ẽ ể ế ạ ậ ậ ả ủ ố ố ế ớ đ c ng AP đ c đ a ra, tôi th y r ng b ph n nh c a Java dùng đ thi r t gi ng v i b ph n mà tôi ề ươ ượ ư ấ ằ ộ ậ ỏ ủ ể ấ ố ớ ộ ậ đã ch n. ọ
Trong tháng 1 năm 2003, tôi đã so n n b n th 4 c a cu n sách, v i nh ng s a đ i sau: ạ ấ ả ứ ủ ố ớ ữ ử ổ
• Tôi đã thêm vào các m c nh m bao quát đ c n i dung trong đ c ng thi AP. ụ ằ ượ ộ ề ươ • Tôi hoàn thi n các ph l c v g l i và phát tri n ch ng trình. ệ ụ ụ ề ỡ ỗ ể ươ
• Tôi đi t p h p l i nh ng bài t p, câu đ , và câu h i thi đã ra trên l p r i đ a vào cu i các ch ng, ngoài ậ ợ ạ ữ ậ ố ỏ ớ ồ ư ố ươ ra còn so n thêm m t s câu h i giúp chu n b kì thi AP. ạ ộ ố ỏ ẩ ị
Cu i cùng, vào tháng 8-2011, tôi vi t xong n b n th 5, bao quát đ c ph n nghiên c u c th ố ế ấ ả ứ ượ ầ ứ ụ ể GridWorld là n i dung trong kì thi AP. ộ
Sách phát hành t do ự
Ngay t đ u, cu n sách này đã theo gi y phép mà b n đ c đ c quy n sao chép, phân ph i và s a ch a ừ ầ ố ấ ạ ọ ượ ề ố ử ữ n i dung. Đ c gi có th t i sách v v i nhi u đ nh d ng khác nhau và có th đ c trên màn hình ho c in ộ ộ ả ể ả ề ớ ề ị ạ ể ọ ặ ra gi y. Giáo viên có th in bao nhiêu b n tùy ý. Và m i ng i đ u có th s a đ i sách theo nhu c u. ấ ể ả ọ ườ ề ể ử ổ ầ
Đã có ng i chuy n n i dung cu n sách sang cho nh ng ngôn ng l p trình khác (nh Python và Eiffel), ườ ể ộ ố ữ ữ ậ ư và nh ng th ti ng khác (nh Tây Ban Nha, Pháp, và Đ c). Trong s đó, nhi u phiên b n đ c đăng ữ ứ ế ư ứ ố ề ả ượ theo hình th c t do. ứ ự
V i đ ng l c t Ph n m m ngu n m , tôi đã đón nh n tri t lý phát hành sách th t s m và c p nh t ớ ộ ự ừ ầ ề ồ ở ậ ế ậ ớ ậ ậ th ng xuyên. Tôi đã c g ng h t s c đ gi m thi u các l i, nh ng cũng nh b n đ c giúp s c. ườ ố ắ ế ứ ể ả ể ỗ ữ ờ ạ ọ ứ
Tinh hình ph n h i th t tuy t. G n nh ngày nào tôi cũng nh n đ c thông tin t b n đ c, v i s a ả ồ ậ ệ ầ ư ậ ượ ừ ạ ọ ớ ự ư thích cu n sách đ n n i h g i h n m t “danh sách li t kê l i”. Thông th ng tôi ch a m t l i m t vài ố ế ỗ ọ ử ẳ ộ ệ ỗ ườ ữ ộ ỗ ấ phút và sau đó c p nh t ngay b n th o qua s a đ i. Tôi coi cu n sách nh m t tác ph m đang trong quá ậ ậ ả ả ử ổ ố ư ộ ẩ trình hoàn thi n, s đ c c i ti n ít m t m i khi tôi có th i gian so n l i, ho c khi b n đ c g i ph n h i. ệ ẽ ượ ả ế ộ ỗ ờ ạ ạ ặ ạ ọ ử ả ồ
À, còn v tiêu đ ề ề
Tôi đã th t bu n phi n v tiêu đ cu n sách Không ph i ai cũng hi u đ c r ng ch y u đó ch là cách ậ ồ ề ề ề ố ả ể ượ ằ ủ ế ỉ nói đùa. Có th sau khi đ c cu n sách này, b n ch a t duy đ c nh nhà khoa h c máy tính. Đi u đó ể ọ ố ạ ư ư ượ ư ọ ề c n th i gian, kinh nghi m, và có th ph i qua m y l p h c n a. ầ ờ ệ ể ả ấ ớ ọ ữ
Nh ng có m t đi m c t lõi có th t tiêu đ này: cu n sách này không ph i vi t v Java, và nó ch m t ư ộ ể ố ậ ở ề ố ả ế ề ỉ ộ ph n là v l p trình. N u có chăng, s thành công cu n sách là n m ch m t cách nghĩ m i. Nhà khoa ầ ề ậ ế ự ở ố ằ ỗ ộ ớ h c ọ máy tính luôn có m t cách ti p c n đ gi i quy t v n đ , và m t cách đ nh hình l i gi n, r t đ c ộ ế ậ ể ả ế ấ ề ộ ị ờ ả ấ ộ đáo, linh ho t và m nh m . Tôi hi v ng r ng cu n sách này giúp b n hình dung đ c ph ng pháp đó ạ ạ ẽ ọ ằ ố ạ ượ ươ là gì, và nh ng lúc nào đó b n s t th y mình có t duy nh nhà khoa h c máy tính. ở ữ ạ ẽ ự ấ ư ư ọ
Allen B. Downey
Needham Massachusett, Hoa Kì
13-7-2011
Danh sách b n đ c đã đóng góp n i dung ạ ọ ộ
Khi b t đ u vi t sách th lo i t do, tôi v n ch a có ý đ nh l p danh sách đóng góp t phía b n đ c. R i ắ ầ ế ể ạ ự ẫ ư ị ậ ừ ạ ọ ồ Jeff Elkner đ xu t, và rõ ràng tôi đã t ra lúng túng vì thi u sót này. Danh sách d i đây tính t n b n ề ấ ỏ ế ướ ừ ấ ả th 4, vì v y nó không có tên nhi u ng i đã đóng góp, s a đ i t tr c đó. ứ ậ ề ườ ử ổ ừ ướ
N u b n có b t kì nh n xét nào thêm, hãy g i th v đ i ch ế ạ ấ ậ ử ư ề ạ ỉ [email protected] • Ellen Hildreth đã dùng sách này đ d y môn h c C u trúc d li u tr ng Wellesley College, và cô đã ể ạ ọ ấ ữ ệ ở ườ
g i m t lo t nh ng ch c n đính chính, kèm theo m t s đ xu t hay. ử ộ ạ ữ ỗ ầ ộ ố ề ấ
• Tania Passfield ch ra r ng ph n Thu t ng cu i Ch ng 4 đã ghi th a m t s m c không có trong sách. ỉ ằ ầ ậ ữ ố ươ ừ ộ ố ụ • Elizabeth Wiethoff nh n th y cách tôi khai tri n exp(− ậ ấ ể x2) là sai. Cô cũng đã so n ra m t phiên b n sách ạ ộ ả dùng ngôn ng l p trình Ruby! ữ ậ
• Matt Crawford đã g i m t file “b n vá” đ y nh ng ch c n s a! ử ộ ả ầ ữ ỗ ầ ử
• Chi-Yu Li ch ra m t l i typo và m t l i trong mã l nh ví d . ỉ ộ ỗ ộ ỗ ệ ụ
• Doan Thanh Nam ch a l i m t ví d Ch ng 3. ữ ạ ộ ụ ở ươ
• Stijn Debrouwere phát hi n m t typo trong bi u th c toán. ệ ộ ể ứ
• Muhammad Saied d ch cu n sách sang ti ng A-r p, và phát hi n m t s l i. ị ố ế ậ ệ ộ ố ỗ
• Marius Margowski phát hi n m t đi m không nh t quán trong mã l nh ví d . ệ ộ ể ấ ệ ụ
• Guy Driesen phát hi n m t s l i typo. ệ ộ ố ỗ
• Leslie Klein phát hi n m t ch sai khác trong cách khai tri n exp(− ệ ộ ỗ ể x2), phát hi n các typo trong hình v ệ ẽ bi u di n m ng ch a các quân bài, và có đ xu t hay giúp cho bài t p đ c rõ ràng h n. ể ễ ả ứ ề ấ ậ ượ ơ
Sau cùng, tôi xin đ c cám n Chris Mayfield đã đóng góp đáng k cho phiên b n 5.1 c a sách. Qua vi c ượ ơ ể ả ủ ệ ph n bi n c n th n, ông đã ch ra h n m t trăm ch c n s a và b sung. M t s đ c đi m m i g m có ả ệ ẩ ậ ỉ ơ ộ ỗ ầ ử ổ ộ ố ặ ể ớ ồ liên k t đ n các trang web và liên k t chéo gi a các m c trong sách, s trình bày nh t quán v hình th c ế ế ế ữ ụ ự ấ ề ứ cho các bài t p, và tô màu mã l nh Java [ch có sách g c]. ậ ệ ỉ ở ố
Ch ng 1: L i đi c a ch ng trình máy ươ ố ủ ươ tính
Tr v ở ề M c l c ụ ụ cu n sách ố
M c đích c a cu n sách này là h ng d n b n suy nghĩ nh là m t nhà khoa h c máy tính. Tôi thích l i ụ ủ ố ướ ẫ ạ ư ộ ọ ố suy nghĩ c a nh ng nhà khoa h c máy tính vì đó có s k t h p nh ng đ c đi m hay nh t c a ủ ữ ọ ở ự ế ợ ữ ặ ể ấ ủ toán h c, ọ kĩ thu t, và khoa h c t nhiên. Cũng nh nh ng nhà toán h c, nh ng nhà khoa h c máy tính dùng ậ ọ ự ư ữ ọ ữ ọ nh ng ngôn ng có quy cách đ di n đ t ý t ng (đ c bi t là tính toán). Gi ng nh nh ng kĩ s , h ữ ữ ể ễ ạ ưở ặ ệ ố ư ữ ư ọ cũng làm công vi c thi t k , g n k t các thành ph n t o nên m t h th ng và đánh giá nh ng u khuy t ệ ế ế ắ ế ầ ạ ộ ệ ố ữ ư ế gi a các ph ng án khác nhau. Gi ng nh nh ng nhà khoa h c, h kh o sát các đ ng thái c a h th ng ữ ươ ố ư ữ ọ ọ ả ộ ủ ệ ố ph c t p, đ ra các gi thi t, và ki m đ nh nh ng tính toán. ứ ạ ề ả ế ể ị ữ
Kĩ năng quan tr ng nh t c a nhà khoa h c máy tính là ọ ấ ủ ọ gi i quy t v n đ ả ế ấ ề. Gi i quy t v n đ chính là ả ế ấ ề cách t o l p v n đ , suy nghĩ gi i pháp m t cách sáng t o, và trình bày gi i pháp m t cách rõ ràng và ạ ậ ấ ề ả ộ ạ ả ộ chính xác. Nh b n s th y, vi c h c l p trình chính là m t c h i tuy t v i đ b n luy n t p nh ng kĩ ư ạ ẽ ấ ệ ọ ậ ộ ơ ộ ệ ờ ể ạ ệ ậ ữ năng gi i quy t v n đ . Đó là lí do t i sao ch ng này l i có tên là “L i đi c a ch ng trình máy tính”. ả ế ấ ề ạ ươ ạ ố ủ ươ M t m t, b n s đ c h c cách l p trình, v n b n thân nó là m t kĩ năng h u d ng. M t khác, b n s ộ ặ ạ ẽ ượ ọ ậ ố ả ộ ữ ụ ặ ạ ẽ dùng l p trình nh m t ph ng ti n đ gi i quy t v n đ . Đi u này b n s d n d n làm đ c trong quá ậ ư ộ ươ ệ ể ả ế ấ ề ề ạ ẽ ầ ầ ượ trình h c. ọ
1.1 Ngôn ng l p trình là gì? ữ ậ
Ngôn ng l p trình mà b n s h c là Java, v n là m t ngôn ng t ng đ i m i (phiên b n đ u tiên do ữ ậ ạ ẽ ọ ố ộ ữ ươ ố ớ ả ầ Sun phát hành vào tháng 5-1995). Java là m t ví d trong s các ộ ụ ố ngôn ng l p trình b c cao ữ ậ ậ ; m t s ộ ố ngôn ng l p trình b c cao khác mà b n có th bi t đ n g m có Python, C, C++, và Perl. ữ ậ ậ ạ ể ế ế ồ Nh c đ n “ngôn ng l p trình b c cao”, có l b n cũng suy đoán đ c r ng còn nh ng ắ ế ữ ậ ậ ẽ ạ ượ ằ ữ ngôn ng l p ữ ậ trình b c th p ậ ấ , đôi khi mà ta g i là “ngôn ng máy” ho c “h p ng ”. Nói nôm na, máy tính ch có th ọ ữ ặ ợ ữ ỉ ể th c hi n các ch ng trình đ c vi t b ng ngôn ng b c th p. Vì v y nh ng ch ng trình đ c vi t ự ệ ươ ượ ế ằ ữ ậ ấ ậ ữ ươ ượ ế b ng m t ngôn ng b c cao c n đ c x lý tr c khi chúng có th ch y đ c. B c ph tr này s t n ằ ộ ữ ậ ầ ượ ử ướ ể ạ ượ ướ ụ ợ ẽ ố thêm th i gian, đây là m t nh c đi m nh c a các ngôn ng b c cao. ờ ộ ượ ể ỏ ủ ữ ậ
Tuy v y, các u đi m là r t l n. Th nh t, vi c l p trình b ng ngôn ng b c cao d h n ậ ư ể ấ ớ ứ ấ ệ ậ ằ ữ ậ ễ ơ nhi uề . Ch ng ươ trình đ c vi t b ng ngôn ng b c cao đ c vi t nhanh h n, n i dung ch ng trình ng n h n, d đ c ượ ế ằ ữ ậ ượ ế ơ ộ ươ ắ ơ ễ ọ h n, và nhi u kh năng là chúng chính xác. Th hai, các ngôn ng b c cao có tính ơ ề ả ứ ữ ậ kh chuy n ả ể theo nghĩa ch y đ c trên nhi u h máy tính khác nhau mà ít ho c không c n ph i s a đ i. Các ch ng trình ạ ượ ề ệ ặ ầ ả ử ổ ươ b c th p ch có th ch y trên m t lo i máy tính và ph i đ c vi t l i n u mu n ch y trên các h máy ậ ấ ỉ ể ạ ộ ạ ả ượ ế ạ ế ố ạ ệ khác.
B i các u đi m nêu trên, h u h t các ch ng trình đ u đ c l p trình b ng ngôn ng b c cao. Các ở ư ể ầ ế ươ ề ượ ậ ằ ữ ậ ngôn ng b c th p ch đ c dùng cho m t s ít nh ng ng d ng đ c bi t. ữ ậ ấ ỉ ượ ộ ố ữ ứ ụ ặ ệ
Hai lo i ch ng trình có nhi m v chuy n đ i các ngôn ng b c cao v d ng ngôn ng b c th p: ạ ươ ệ ụ ể ổ ữ ậ ề ạ ữ ậ ấ trình thông d chị và trình biên d chị . Trình thông d ch là m t ch ng trình máy tính, có nhi m v đ c m t ị ộ ươ ệ ụ ọ ộ ch ng trình b c cao và th c hi n nó theo đúng nh ng gì mà ch ng trình ch đ nh. Nó x lý ch ng ươ ậ ự ệ ữ ươ ỉ ị ử ươ trình m t cách d n d n, nghĩa là đ c câu l nh đ n đâu thì th c hi n tính toán t i đó. ộ ầ ầ ọ ệ ế ự ệ ớ Còn trình biên d ch thì có nhi m v đ c ch ng trình và d ch nó hoàn toàn tr c khi th c hi n b t kì ị ệ ụ ọ ươ ị ướ ự ệ ấ
m t câu l nh nào trong ch ng trình. Th ng thì b n th c hi n b c biên d ch ch ng trình tr c, sau ộ ệ ươ ườ ạ ự ệ ướ ị ươ ướ đó m i ch y mã l nh đã biên d ch. Khi đó, ch ng trình b c cao đ c g i là ớ ạ ệ ị ươ ậ ượ ọ mã ngu nồ , và ch ng ươ trình sau khi đ c d ch g i là ượ ị ọ mã đ i t ng ố ượ , ho cặ ch ng trình ch y ươ ạ .
Ch ng trình Java v a đ c biên d ch l n thông d ch. Thay vì vi c chuy n ch ng trình sang ngôn ng ươ ừ ượ ị ẫ ị ệ ể ươ ữ máy, trình biên d ch Java phát sinh ra ị mã byte. Mã byte d thông d ch (và thông d ch cũng nhanh), ễ ị ị gi ng nh mã máy; song nó còn kh chuy n, nh m t ngôn ng b c cao. Vì v y, ta có th biên d ch m t ố ư ả ể ư ộ ữ ậ ậ ể ị ộ ch ng trình trên máy này, đ a mã byte sang máy khác, sau đó thông d ch mã byte này trên máy m i. ươ ư ị ớ
Kh năng này là m t l i th c a Java so v i nhi u ngôn ng b c cao khác. ả ộ ợ ế ủ ớ ề ữ ậ
M c dù quá trình này có v ph c t p, nh ng đa s các môi tr ng phát tri n ch ng trình đ u giúp b n ặ ẻ ứ ạ ư ố ườ ể ươ ề ạ t đ ng th c hi n các b c k trên. Thông th ng b n s ch ph i vi t m t ch ng trình r i n m t nút ự ộ ự ệ ướ ể ườ ạ ẽ ỉ ả ế ộ ươ ồ ấ ộ ho c gõ vào m t câu l nh đ biên d ch và ch y. M t khác, ta v n c n bi t nh ng b c nào đang đ c ặ ộ ệ ể ị ạ ặ ẫ ầ ế ữ ướ ượ máy th c hi n ng m, đ nh có tr c tr c thì có th hình dung ra sai khâu nào. ự ệ ầ ể ỡ ụ ặ ể ở
1.2 Ch ng trình là gì? ươ
Ch ng trình ươ là m t danh sách các ch d n cách th c hi n tính toán. ộ ỉ ẫ ự ệ 1 Vi c tính toán có th là phép ệ ể thao tác toán h c, ch ng h n gi i h ph ng trình ho c tìm nghi m đa th c, nh ng cũng có th là ọ ẳ ạ ả ệ ươ ặ ệ ứ ư ể nh ng phép tính trên các kí hi u, ch ng h n tìm ki m và thay th ch trong m t văn b n, ho c (kì l ữ ệ ẳ ạ ế ế ữ ộ ả ặ ạ h n) là biên d ch m t ch ng trình. ơ ị ộ ươ
Nh ng ch d n, mà ta g i là nh ng ữ ỉ ẫ ọ ữ câu l nh ệ , s khác nhau tùy lo i ngôn ng l p trình, nh ng chung ẽ ạ ữ ậ ư quy l i có m t s ít các phép thao tác mà nhi u ngôn ng th c hi n: ạ ộ ố ề ữ ự ệ
nh p s li u: ậ ố ệ
Là vi c l y s li u t bàn phím, file, ho c m t thi t b khác. ệ ấ ố ệ ừ ặ ộ ế ị
xu t k t qu : ấ ế ả
Hi n th k t qu trên màn hình ho c g i k t qu ra file ho c m t thi t b khác. ể ị ế ả ặ ử ế ả ặ ộ ế ị tính toán:
Th c hi n các phép toán c b n nh c ng và nhân. ự ệ ơ ả ư ộ
ki m tra: ể
Ki m tra m t đi u ki n c th và th c hi n danh sách câu l nh t ng ng v i đi u ki n đó. ể ộ ề ệ ụ ể ự ệ ệ ươ ứ ớ ề ệ tính l p: ặ
Th c hi n l p l i công vi c nhi u l n, th ng là v i m t s thay đ i gi a các l n l p. ự ệ ặ ạ ệ ề ầ ườ ớ ộ ố ổ ữ ầ ặ Nh v y đã t ng đ i đ y đ . M i ch ng trình mà b n đã t ng dùng qua, b t k nó ph c t p đ n đâu, ư ậ ươ ố ầ ủ ỗ ươ ạ ừ ấ ể ứ ạ ế đ uề đ c h p thành t nh ng câu l nh th c hi n tính toán. Vì v y, m t cách mô t l p trình, đó là quá ượ ợ ừ ữ ệ ự ệ ậ ộ ả ậ trình chia m t bài toán l n, ph c t p thành nhi u bài toán nh h n cho đ n khi t ng bài toán nh này ộ ớ ứ ạ ề ỏ ơ ế ừ ỏ đ n gi n đ n m c có th đ c th c hi n theo m t trong các ch d n trên đây. ơ ả ế ứ ể ượ ự ệ ộ ỉ ẫ
1.3 G l i là gì? ỡ ỗ
Vi c l p trình r t hay m c ph i l i. Vi c theo dõi, phân tích nguyên nhân gây ra l i đ c g i là ệ ậ ấ ắ ả ỗ ệ ỗ ượ ọ g l i ỡ ỗ . Có ba lo i l i có th xu t hi n trong ch ng trình: l i cú pháp, l i ch y và l i ng nghĩa. Đ nhanh ạ ỗ ể ấ ệ ươ ỗ ỗ ạ ỗ ữ ể chóng tìm ra l i ta c n phân bi t đ c chúng. ỗ ầ ệ ượ
1.3.1 L I CÚ PHÁP Ỗ
Trình biên d ch ch có th chuy n đ i đ c ch ng trình n u nh nó đúng đ n v cú pháp; còn n u ị ỉ ể ể ổ ượ ươ ế ư ắ ề ế không, vi c biên d ch s th t b i và b n s không ch y đ c ch ng trình. ệ ị ẽ ấ ạ ạ ẽ ạ ượ ươ Cú pháp nghĩa là c u trúc ấ c a ch ng trình và các quy t c v c u trúc đó. ủ ươ ắ ề ấ
Ch ng h n, trong ti ng Anh, m t câu vi t ph i b t đ u b ng ch in hoa và k t thúc b ng d u ch m. câu ẳ ạ ế ộ ế ả ắ ầ ằ ữ ế ằ ấ ấ này có m t l i cú pháp. Và câu này cũng v y ộ ỗ ậ
Đa ph n ban đ c th ng không đ tâm đ n m t s ít l i cú pháp, vì v y ta có th đ c th c a tác gi e e ầ ọ ườ ể ế ộ ố ỗ ậ ể ọ ơ ủ ả cummings mà không th t ra l i thông báo l i nào. ố ờ ỗ
Các trình biên d ch thì không nh v y. Ch c n trong ch ng trình có l i cú pháp b t c đâu, trình ị ư ậ ỉ ầ ươ ỗ ở ấ ứ biên d ch s hi n th thông báo l i và k t thúc, và b n s không th ch y ch ng trình. ị ẽ ể ị ỗ ế ạ ẽ ể ạ ươ
T h n n a là trong Java có nhi u quy t c cú pháp h n là trong ti ng Anh, và th ng thì nh ng thông ệ ơ ữ ề ắ ơ ế ườ ữ báo l i mà b n nh n đ c t trình biên d ch đ u không giúp ích gì nhi u. ỗ ạ ậ ượ ừ ị ề ề N u b n m i nh p môn l p ế ạ ớ ậ ậ trình đ c vài tu n, r t có th b n ph i dành nhi u th i gian dò tìm l i. Khi kinh nghi m tăng d n lên, ượ ầ ấ ể ạ ả ề ờ ỗ ệ ầ b n s tránh đ c l i t t h n và n u m c thì cũng phát hi n ra l i nhanh h n. ạ ẽ ượ ỗ ố ơ ế ắ ệ ỗ ơ
1.3.2 L I TH C THI Ỗ Ự
Lo i l i th hai là l i th c thi; chúng có tên nh v y b i vì ch xu t hi n khi ch ng trình đã b t đ u ạ ỗ ứ ỗ ự ư ậ ở ỉ ấ ệ ươ ắ ầ ch y. Trong Java, l i th c thi x y ra khi trình thông d ch đang ch y mã byte và có đi u gì đó tr c tr c. ạ ỗ ự ả ị ạ ề ụ ặ
Java có xu h ng là ngôn ng ướ ữ an toàn, theo nghĩa trình biên d ch s b t r t nhi u l i. Do v y l i th c ị ẽ ắ ấ ề ỗ ậ ỗ ự
thi s hi m, đ c bi t là nh ng ch ng trình đ n gi n. ẽ ế ặ ệ ở ữ ươ ơ ả
Trong Java, l i th c thi đ c g i là ỗ ự ượ ọ bi t l ệ ệ, và h u h t các môi tr ng l p trình, chúng xu t hi n d i ở ầ ế ườ ậ ấ ệ ướ hình th c c a s ho c h p tho i ghi rõ nh ng thông tin v tình tr ng đã di n ra và lúc đó thì ch ng ứ ủ ổ ặ ộ ạ ữ ề ạ ễ ươ trình đang th c hi n nh ng gì. Thông tin này r t có ích đ i v i vi c g l i. ự ệ ữ ấ ố ớ ệ ỡ ỗ
1.3.3 L I LOGIC VÀ NG NGHĨA Ỗ Ữ
Lo i l i th ba là ạ ỗ ứ l i logic ỗ hay l i ng nghĩa ỗ ữ . Trong tr ng h p có l i ki u này, ch ng trình s v n ườ ợ ỗ ể ươ ẽ ẫ đ c biên d ch và ch y mà không phát ra thông báo l i nào, nh ng s không th c hi n đúng yêu c u ượ ị ạ ỗ ư ẽ ự ệ ầ mong mu n, mà s cho k t qu khác. C th là th c hi n theo đúng nh ng câu l nh mà b n đã ch d n. ố ẽ ế ả ụ ể ự ệ ữ ệ ạ ỉ ẫ V n đ đây là ch ng trình b n vi t s không đúng theo ý mu n c a b n. Ý nghĩa c a ch ng trình b ấ ề ở ươ ạ ế ẽ ố ủ ạ ủ ươ ị sai l ch. Vi c phát hi n các l i ng nghĩa đôi lúc r t khó vì b n c n ph i quay ng c l i và nhìn vào k t ệ ệ ệ ỗ ữ ấ ạ ầ ả ượ ạ ế qu c a ch ng trình đ phán đoán xem b n thân ch ng trình đã th c hi n nh ng gì. ả ủ ươ ể ả ươ ự ệ ữ
1.3.4 G L I TH NGHI M Ỡ Ỗ Ử Ệ
M t trong nh ng kĩ năng quan tr ng nh t mà b n s h c đ c, đó là g l i. M c dù đôi khi b v p váp, ộ ữ ọ ấ ạ ẽ ọ ượ ỡ ỗ ặ ị ấ nh ng vi c g l i r t thú v , ch a đ y th thách và là m t ph n có giá tr trong l p trình. ư ệ ỡ ỗ ấ ị ứ ầ ử ộ ầ ị ậ
G l i gi ng nh vi c đi u tra t i ph m. B n có trong tay các manh m i, ph i suy lu n ra các quá trình ỡ ỗ ố ư ệ ề ộ ạ ạ ố ả ậ và s ki n d n đ n nh ng h u qu đang ch ng ki n. ự ệ ẫ ế ữ ậ ả ứ ế
Vi c g l i cũng gi ng nh khoa h c th c nghi m. M i khi có ý ki n v nguyên nhân d n đ n l i sai, ệ ỡ ỗ ố ư ọ ự ệ ỗ ế ề ẫ ế ỗ b n s a ch a ch ng trình và th c hi n l i. N u gi thi t c a b n là đúng thì b n thu đ c k t qu c a ạ ử ữ ươ ự ệ ạ ế ả ế ủ ạ ạ ượ ế ả ủ công vi c s a ch a, đ ng th i ti n m t b c g n h n t i ch ng trình đúng. Còn n u gi thi t là sai thì ệ ử ữ ồ ờ ế ộ ướ ầ ơ ớ ươ ế ả ế b n c n đ ra m t gi thi t m i. Sherlock Holmes đã ch ra, “Khi b n đã lo i tr t t c nh ng đi u ạ ầ ề ộ ả ế ớ ỉ ạ ạ ừ ấ ả ữ ề không th thì nh ng gì còn l i, dù có m p m đ n đâu, chính là s th t”. (A. Conan Doyle, ể ữ ạ ậ ờ ế ự ậ D u c a b ấ ủ ộ tứ)
Đ i v i m t s ng i, vi c l p trình và g l i là gi ng nhau. Đó là vì l p trình chính là quá trình g l i ố ớ ộ ố ườ ệ ậ ỡ ỗ ố ậ ỡ ỗ d n d n đ n khi b n có đ c ch ng trình mong mu n. Ý t ng đây là b n nên b t đ u v i m t ầ ầ ế ạ ượ ươ ố ưở ở ạ ắ ầ ớ ộ ch ng trình th c hi n đ c ươ ự ệ ượ m t đi u gì đó ộ ề , r i th c hi n các ch nh s a nh , g l i trong quá trình ồ ự ệ ỉ ử ỏ ỡ ỗ phát tri n, đ n khi b n có đ c m t ch ng trình hoàn thi n. ể ế ạ ượ ộ ươ ệ
Ch ng h n, Linux là m t h đi u hành bao g m hàng nghìn dòng l nh, nh ng nó ch b t đ u t m t ẳ ạ ộ ệ ề ồ ệ ư ỉ ắ ầ ừ ộ ch ng trình đ n gi n do Linus Torvalds dùng đ khám phá chip Intel 80386. Theo Larry Greenfield ươ ơ ả ể thì “M t trong nh ng d án tr c đó c a Linus là m t ch ng trình có nhi m v chuy n t vi c in ộ ữ ự ướ ủ ộ ươ ệ ụ ể ừ ệ AAAA thành BBBB. Sau đó nó d n tr thành Linux”. ( ầ ở The Linux Users’ Guide Beta Version 1 / H ng ướ d n s d ng Linux ẫ ử ụ , phiên b n Beta 1). ả
Các ch ng ti p sau đây s nói thêm v vi c g l i và các v n đ th c t trong l p trình. ươ ế ẽ ề ệ ỡ ỗ ấ ề ự ế ậ 1.4 Ngôn ng hình th c và ngôn ng t nhiên ữ ứ ữ ự
Ngôn ng t nhiên ữ ự đ c m i ng i dùng đ giao ti p, ví d Ti ng Anh, Ti ng Tây Ban Nha, Ti ng ượ ọ ườ ể ế ụ ế ế ế Pháp. Chúng t do phát tri n mà không đ nh theo khuôn m u v i b t kì m c đích nào (m c dù có m t ự ể ị ẫ ớ ấ ụ ặ ộ s tr t t ch ng h n nh ng pháp); ố ậ ự ẳ ạ ư ữ
Ngôn ng hình th c ữ ứ đ c con ng i thi t k đ ng d ng trong nh ng lĩnh v c riêng. Ch ng h n, kí ượ ườ ế ế ể ứ ụ ữ ự ẳ ạ hi u toán h c chính là m t ngôn ng hình th c r t h u d ng đ bi u di n m i quan h gi a nh ng bi n ệ ọ ộ ữ ứ ấ ữ ụ ể ể ễ ố ệ ữ ữ ế l ng và con s . Trong hoá h c, m t lo i ngôn ng hình th c khác đ c dùng đ bi u di n c u trúc hoá ượ ố ọ ộ ạ ữ ứ ượ ể ể ễ ấ h c c a các phân t . Và quan tr ng nh t: ọ ủ ử ọ ấ
Ngôn ng l p trình là nh ng ngôn ng hình th c đ c thi t k ph c v m c đích ữ ậ ữ ữ ứ ượ ế ế ụ ụ ụ
di n t quá trình tính toán. ễ ả
Các ngôn ng hình th c th ng có quy đ nh r t ch t ch v cú pháp. Ch ng h n, ữ ứ ườ ị ấ ặ ẽ ề ẳ ạ 3 + 3 = 6 là m t bi u ộ ể th c toán h c đúng, nh ng ứ ọ ư 3 $ = thì không. H2O là m t công th c hoá h c đúng v cú pháp, còn ộ ứ ọ ề 2Zz thì không.
Các quy t c cú pháp có hai d ng, thu c v các ắ ạ ộ ề nguyên tố và c u trúc. Nguyên t là các thành ph n c s ấ ố ầ ơ ở c a ngôn ng , ch ng h n, các t , các con s , và các nguyên t hoá h c. Trong ví d nêu trên, ủ ữ ẳ ạ ừ ố ố ọ ụ 3 $ = có l i ỗ sai vì $ không ph i là m t nguyên t h p l trong toán h c (theo nh tôi đ c bi t). T ng t nh ả ộ ố ợ ệ ọ ư ượ ế ươ ự ư v y, ậ 2Zz không h p l vì không có nguyên t hoá h c nào có kí hi u là ợ ệ ố ọ ệ Zz.
Lo i l i cú pháp th hai thu c v d ng c u trúc c a m t m nh đ ; nghĩa là cách s p x p các nguyên t . ạ ỗ ứ ộ ề ạ ấ ủ ộ ệ ề ắ ế ố M nh đ ệ ề 3 $ = không h p l v c u trúc là vì b n không th đ d u b ng cu i ph ng trình đ c. ợ ệ ề ấ ạ ể ể ấ ằ ở ố ươ ượ T ng t nh v y, trong m t công th c hoá h c thì ch s ph i đ c đ t sau tên nguyên t ch không ươ ự ư ậ ộ ứ ọ ỉ ố ả ượ ặ ố ứ ph i đ t tr c. ả ặ ướ
M i khi đ c m t câu trong ngôn ng t nhiên, ho c trong ngôn ng hình th c, b n c n hình dung đ c ỗ ọ ộ ữ ự ặ ữ ứ ạ ầ ượ c u trúc c a câu đó là gì (m c dù v i ngôn ng t nhiên thì vi c làm này đ c th c hi n m t cách vô ấ ủ ặ ớ ữ ự ệ ượ ự ệ ộ th c). Quá trình này đ c g i là ứ ượ ọ phân tách.
M c dù ngôn ng hình th c và ngôn ng t nhiên có nhi u đ c đi m chung—nguyên t , c u trúc, cú ặ ữ ứ ữ ự ề ặ ể ố ấ pháp, và ng nghĩa—nh ng chúng có m t s khác bi t: ữ ư ộ ố ệ
v s m p m : ề ự ậ ờ
Ngôn ng t nhiên ch a đ ng s m p m theo nghĩa con ng i mu n hi u đúng ph i có suy lu n tuỳ ữ ự ứ ự ự ậ ờ ườ ố ể ả ậ t ng ng c nh. và có thêm các thông tin khác đ b sung. Các ngôn ng hình th c đ c thi t k g n ừ ữ ả ể ổ ữ ứ ượ ế ế ầ nh rõ ràng tuy t đ i, t c là m i m nh đ ch có đúng m t nghĩa, b t k ng c nh nh th nào. ư ệ ố ứ ỗ ệ ể ỉ ộ ấ ể ữ ả ư ế v s d th a: ề ự ư ừ
Đ lo i tr s m p m và tránh gây hi u nh m, ngôn ng t nhiên c n dùng đ n nhi u n i dung b ể ạ ừ ự ậ ờ ể ầ ữ ự ầ ế ề ộ ổ tr làm dài thêm n i dung. Các ngôn ng hình thì g n gàng h n. ợ ộ ữ ọ ơ
v văn phong: ề
Các ngôn ng t nhiên có ch a nhi u thành ng và n d . Các ngôn ng hình th c luôn luôn có nghĩa ữ ự ứ ề ữ ẩ ụ ữ ứ đúng theo nh ng gì đ c vi t ra. ữ ượ ế
Chúng ta dùng ngôn ng t nhiên ngay t thu nh , nên th ng có m t th i gian khó khăn ban đ u khi ữ ự ừ ở ỏ ườ ộ ờ ầ làm quen v i ngôn ng hình th c. V ph ng di n nào đó, s khác bi t gi a ngôn ng hình th c và ớ ữ ứ ề ươ ệ ự ệ ữ ữ ứ ngôn ng t nhiên cung nh khác bi t gi a th ca và văn xuôi, dù h n th n a. ữ ự ư ệ ữ ơ ơ ế ữ
Th ca: ơ
Các t đ c dùng v i c ch c năng âm đi u bên c nh ch c năng ý nghĩa, và toàn b bài th /ca t o ra ừ ượ ớ ả ứ ệ ạ ứ ộ ơ ạ hi u qu c m xúc. Luôn mang tính không rõ ràng, th m chí còn là ch đ nh c a tác gi . ệ ả ả ậ ủ ị ủ ả Văn xuôi:
Coi tr ng ý nghĩa c a câu ch h n, và c u trúc giúp cho vi c di n đ t ý nghĩa. ọ ủ ữ ơ ấ ệ ễ ạ Ch ng trình: ươ
Ý nghĩa c a m t ch ng trình máy tính là rõ ràng và đ c di n đ t hoàn toàn thông qua câu ch , theo ủ ộ ươ ượ ễ ạ ữ đó ta có th hi u đ c tr n ven b ng cách phân tích các nguyên t và c u trúc. ể ể ượ ọ ằ ố ấ Khi đ c ch ng trình (ho c m t ngôn ng hình th c nào khác) b n nên làm nh sau. Tr c h t, hãy ọ ươ ặ ộ ữ ứ ạ ư ướ ế nh r ng ngôn ng hình th c cô đ ng h n ngôn ng t nhiên, nên ph i m t nhi u th i gian đ đ c h n. ớ ằ ữ ứ ọ ơ ữ ự ả ấ ề ờ ể ọ ơ M t khác, c u trúc cũng r t quan tr ng, do đó không nên ch đ c qua m t l t t trên xu ng d i. Thay ặ ấ ấ ọ ỉ ọ ộ ượ ừ ố ướ vì v y, b n nên h c cách phân tách ngôn ng trong trí óc, nh n di n các nguyên t và di n gi i c u trúc. ậ ạ ọ ữ ậ ệ ố ễ ả ấ Cu i cùng, nh ng chi ti t đóng vai trò quan tr ng. Các l i dù là nh nh t trong cách vi t các t ho c d u ố ữ ế ọ ỗ ỏ ấ ế ừ ặ ấ câu trong ngôn ng hình th c s có th gây ra khác bi t l n v ý nghĩa. ữ ứ ẽ ể ệ ớ ề
1.5 Ch ng trình đ u tiên ươ ầ
Theo thông l , ch ng trình đ u tiên mà b n vi t theo m t ngôn ng l p trình m i có tên g i là “Hello, ệ ươ ầ ạ ế ộ ữ ậ ớ ọ World!” vì t t c nh ng gì nó th c hi n ch là làm hi n ra dòng ch “Hello, World!” M t ch ng trình ấ ả ữ ự ệ ỉ ệ ữ ộ ươ nh v y trong Java đ c vi t nh sau: ư ậ ượ ế ư
class Hello {
// main: xuất ra một thông tin đơn giản
public static void main(String[] args) {
System.out.println("Hello, world.");
}
}
Ch ng trình này có nh ng đ c đi m h i khó gi i thích cho ng i m i b t đ u, song nó giúp ta có cái ươ ữ ặ ể ơ ả ườ ớ ắ ầ nhìn bao quát v nh ng ch đ sau này s đ c h c. ề ữ ủ ề ẽ ượ ọ
M t ch ng trình Java đ c h p thành t nh ng l i ộ ươ ượ ợ ừ ữ ờ khai báo l pớ , v n có d ng sau: ố ạ class TENLOP {
public static void main (String[] args) {
CAC_CAU_LENH
}
}
Ở ộ ọ ườ ậ ặ ụ ớ đây TENLOP là m t tên g i do ng i l p trình đ t. Trong ví d trên, tên l p là Hello. main là m t ộ ph ng th c ươ ứ , t c là m t t p h p đ c đ t tên, bao g m các câu l nh. Tên g i main này ứ ộ ậ ợ ượ ặ ồ ệ ọ r t đ c bi t; nó đánh d u đi m kh i đ u c a ch ng trình. Khi ch y ch ng trình, câu l nh đ u tiên ấ ặ ệ ấ ể ở ầ ủ ươ ạ ươ ệ ầ trong main s là đi m b t đ u và k t thúc câu l nh cu i cùng trong đó. ẽ ể ắ ầ ế ở ệ ố
main có th g m nhi u câu l nh, nh ng ví d trên thì ch có m t. Đó là câu l nh in, nghĩa là nó hi n ể ồ ề ệ ư ở ụ ỉ ộ ệ ể thị m t giá tr trên màn hình. Ch này d gây l n, “print” có th mang ý nghĩa “hi n ra trên màn hình” ộ ị ỗ ễ ẫ ể ệ hay “g i n i dung đ n máy in”. Trong cu n sách này, tôi không nói v vi c g i đ n máy in; t t c vi c in ử ộ ế ố ề ệ ử ế ấ ả ệ c a chúng ta là hi n th lên màn hình. L nh in k t thúc b ng m t d u ch m ph y (;). ủ ể ị ệ ế ằ ộ ấ ấ ẩ System.out.println là m t ph ng th c do th vi n c a Java cung c p. M t ộ ươ ứ ư ệ ủ ấ ộ th vi n ư ệ là t p h p ậ ợ g m nh ng l i đ nh nghĩa l p và ph ng th c. ồ ữ ờ ị ớ ươ ứ
Java dùng nh ng c p ngo c nh n ({ và }) đ nhóm thông tin l i v i nhau. C p ngo c nh n ngoài cùng ữ ặ ặ ọ ể ạ ớ ặ ặ ọ ở (các dòng 1 và 8) ch a l i đ nh nghĩa l p, còn c p ngo c nh n phía trong thì ch a l i đ nh nghĩa cho ứ ờ ị ớ ặ ặ ọ ứ ờ ị main.
Dòng 3 b t đ u b ng //. Nh v y dòng này là m t ắ ầ ằ ư ậ ộ l i chú thích ờ , t c là m t đo n ch mà b n có th ứ ộ ạ ữ ạ ể vi t vào ch ng trình, th ng đ gi i thích công d ng c a ch ng trình. Khi trình biên d ch th y //, nó ế ươ ườ ể ả ụ ủ ươ ị ấ
s ph t l nh ng gì k t đó đ n cu i dòng. ẽ ớ ờ ữ ể ừ ế ố
1.6 Thu t ng ậ ữ
gi i quy t v n đ : ả ế ấ ề
Quá trình thi t l p bài toán, tìm l i gi i, và bi u di n l i gi i. ế ậ ờ ả ể ễ ờ ả
ngôn ng b c cao: ữ ậ
Ngôn ng l p trình nh Python đ c thi t k nh m m c đích đ con ng i d đ c và vi t. ữ ậ ư ượ ế ế ằ ụ ể ườ ễ ọ ế ngôn ng b c th p: ữ ậ ấ
Ngôn ng l p trình đ c thi t k nh m m c đích đ máy tính d th c hi n; còn g i là “ngôn ng máy” ữ ậ ượ ế ế ằ ụ ể ễ ự ệ ọ ữ ho c “h p ng ”. ặ ợ ữ
tính kh chuy n: ả ể
Đ c tính c a ch ng trình mà có th ch y trên nhi u lo i máy tính khác nhau. ặ ủ ươ ể ạ ề ạ thông d ch: ị
Th c hi n ch ng trình đ c vi t b ng ngôn ng b c cao b ng cách d ch nó theo t ng dòng m t. ự ệ ươ ượ ế ằ ữ ậ ằ ị ừ ộ biên d ch: ị
D ch m t l t toàn b ch ng trình vi t b ng ngôn ng b c cao sang ngôn ng b c th p, đ chu n b ị ộ ượ ộ ươ ế ằ ữ ậ ữ ậ ấ ể ẩ ị th c hi n sau này. ự ệ
mã ngu n: ồ
Ch ng trình d ng ngôn ng b c cao tr c khi đ c biên d ch. ươ ở ạ ữ ậ ướ ượ ị
mã đ i t ng: ố ượ
S n ph m đ u ra c a trình biên d ch sau khi nó đã d ch ch ng trình. ả ẩ ầ ủ ị ị ươ
ch ng trình ch y: ươ ạ
Tên khác đ t cho mã đ i t ng đã s n sàng đ c th c hi n. ặ ố ượ ẵ ượ ự ệ
d u nh c: ấ ắ
Các kí t đ c hi n th b i trình thông d ch nh m th hi n r ng nó đã s n sàng nh n đ u vào t phía ự ượ ể ị ở ị ằ ể ệ ằ ẵ ậ ầ ừ ng i dùng. ườ
văn l nh: ệ
Ch ng trình đ c l u trong file (th ng chính là ch ng trình s đ c thông d ch). ươ ượ ư ườ ươ ẽ ượ ị ch đ t ng tác: ế ộ ươ
Cách dùng trình thông d ch Python thông qua vi c gõ các câu l nh và bi u th c vào ch d u nh c. ị ệ ệ ể ứ ỗ ấ ắ ch đ văn l nh: ế ộ ệ
Cách dùng trình thông d ch Python đ đ c và th c hi n các câu l nh có trong m t văn l nh. ị ể ọ ự ệ ệ ộ ệ ch ng trình: ươ
Danh sách nh ng ch d n th c hi n tính toán. ữ ỉ ẫ ự ệ
thu t toán: ậ
Quá trình t ng quát đ gi i m t l p các bài toán. ổ ể ả ộ ớ
l i: ỗ
L i trong ch ng trình. ỗ ươ
g l i: ỡ ỗ
Quá trình dò tìm và g b c ba ki u l i trong l p trình. ỡ ỏ ả ể ỗ ậ
cú pháp:
C u trúc c a m t ch ng trình. ấ ủ ộ ươ
l i cú pháp: ỗ
L i trong ch ng trình mà làm cho quá trình phân tách không th th c hi n đ c (và h qu là không ỗ ươ ể ự ệ ượ ệ ả th biên d ch đ c). ể ị ượ
bi t l : ệ ệ
L i đ c phát hi n khi ch ng trình đang ch y. ỗ ượ ệ ươ ạ
ng nghĩa: ữ
Ý nghĩa c a ch ng trình. ủ ươ
l i ng nghĩa: ỗ ữ
L i có trong ch ng trình mà khi n cho ch ng trình th c hi n công vi c ngoài ý đ nh c a ng i vi t. ỗ ươ ế ươ ự ệ ệ ị ủ ườ ế ngôn ng t nhiên: ữ ự
Ngôn ng b t kì đ c con ng i dùng, đ c tr i qua s ti n hóa t nhiên. ữ ấ ượ ườ ượ ả ự ế ự
ngôn ng hình th c: ữ ứ
Ngôn ng b t kì đ c con ng i thi t k nh m m c đích c th , nh vi c bi u di n các ý t ng toán ữ ấ ượ ườ ế ế ằ ụ ụ ể ư ệ ể ễ ưở h c ho c các ch ng trình máy tính; t t c các ngôn ng l p trình đ u là ngôn ng hình th c. ọ ặ ươ ấ ả ữ ậ ề ữ ứ nguyên t : ố
M t trong nh ng thành ph n c b n trong c u trúc cú pháp c a m t ch ng trình, t ng đ ng v i ộ ữ ầ ơ ả ấ ủ ộ ươ ươ ươ ớ m t t trong ngôn ng t nhiên. ộ ừ ữ ự
phân tách:
Vi c ki m tra m t ch ng trình và phân tích c u trúc cú pháp. ệ ể ộ ươ ấ
l nh print: ệ
Câu l nh khi n cho k t qu đ c hi n th lên màn hình. ệ ế ế ả ượ ể ị
1.7 Bài t pậ
BÀI T P 1 Ậ
Các nhà khoa h c máy tính th ng có thói quen dùng nh ng t ti ng Anh thông th ng đ ọ ườ ữ ừ ế ườ ể ch nh ng th khác v i nghĩa ti ng Anh thông d ng c a t đó. Ch ng h n, trong ti ng Anh, ỉ ữ ứ ớ ế ụ ủ ừ ẳ ạ ế “statement” và “comment” đ ng nghĩa v i nhau, nh ng trong ch ng trình thì chúng khác ồ ớ ư ươ h n. ẳ
Ph n thu t ng cu i m i ch ng nh m đi m l i nh ng t và c m t có ý nghĩa riêng ầ ậ ữ ở ố ỗ ươ ằ ể ạ ữ ừ ụ ừ trong ngành khoa h c máy tính. Khi b n th y nh ng t quen thu c, thì đ ng l đi coi nh ọ ạ ấ ữ ừ ộ ừ ờ ư đã bi t nghĩa c a chúng nhé! ế ủ
1. Theo thu t ng máy tính, s khác bi t gi a câu l nh và chú thích nh th nào? ậ ữ ự ệ ữ ệ ư ế 2. Nói m t ch ng trình có tính kh chuy n nghĩa là gì? ộ ươ ả ể
3. M t ch ng trình ch y có nghĩa là gì? ộ ươ ạ
BÀI T P 2 Ậ
Tr c khi ti p t c, b n hãy tìm hi u cách biên d ch và ch y ch ng trình Java trong môi ướ ế ụ ạ ể ị ạ ươ tr ng l p trình c a mình. M t s lo i môi tr ng cung c p s n nh ng ch ng trình m u ườ ậ ủ ộ ố ạ ườ ấ ẵ ữ ươ ẫ t a nh ví d M c 1.5. ự ư ụ ở ụ
1. Gõ vào ch ng trình “Hello, World”, r i biên d ch và ch y nó. ươ ồ ị ạ
2. Thêm m t câu l nh đ in ra m t dòng ch th hai theo sau “Hello, World!”. Có th là câu ộ ệ ể ộ ữ ứ ể đùa vui “How are you?” Hãy biên d ch và ch y l i ch ng trình. ị ạ ạ ươ
3. Thêm m t chú thích vào (b t kì đâu) trong ch ng trình, biên d ch l i, và ch y l i l n n a. ộ ấ ươ ị ạ ạ ạ ầ ữ
L i chú thích m i ph i không làm nh h ng đ n k t qu . ờ ớ ả ả ưở ế ế ả
Bài t p này có v l t v t, song đây chính là đi m kh i đ u cho nhi u ch ng trình mà ta s ậ ẻ ặ ặ ể ở ầ ề ươ ẽ làm vi c v i. Đ ch c tay g l i, b n ph i dùng th o môi tr ng l p trình c a mình. Trong ệ ớ ể ắ ỡ ỗ ạ ả ạ ườ ậ ủ m t s môi tr ng, r t d b m t d u ch ng trình đang ch y, và b n có th r i vào tr ng ộ ố ườ ấ ễ ị ấ ấ ươ ạ ạ ể ơ ườ h p đi g l i m t ch ng trình trong khi vô ý ch y ch ng trình khác. Vi c thêm vào (và ợ ỡ ỗ ộ ươ ạ ươ ệ thay đ i) câu l nh in là m t cách đ n gi n đ đ m b o ch c ch ng trình đang làm vi c là ổ ệ ộ ơ ả ể ả ả ắ ươ ệ ch ng trình mà b n ch y. ươ ạ ạ
BÀI T P 3 Ậ
M t ý t ng hay là hãy ph m càng nhi u l i trong l p trình mà b n có th hình dung đ c, ộ ưở ạ ề ỗ ậ ạ ể ượ đ th y nh ng thông báo l i nào mà trình biên d ch đ a ra. Đôi khi trình biên d ch cho b n ể ấ ữ ỗ ị ư ị ạ bi t chính xác sai ch nào, và b n ch vi c s a nó. Nh ng đôi khi các thông báo l i l i ế ở ỗ ạ ỉ ệ ủ ư ỗ ạ đánh l i h ng. B n s hình thành nên m t tr c giác đ phân bi t lúc nào thì tin c y trình ạ ướ ạ ẽ ộ ự ể ệ ậ biên d ch và lúc nào ph i t hình dung ra l i. ị ả ự ỗ
1. Xóa b t m t trong các d u m ngo c nh n. ớ ộ ấ ở ặ ọ
2. Xóa b t m t trong các d u đóng ngo c nh n. ớ ộ ấ ặ ọ
3. Thay vì main, hãy vi t ế mian.
4. Xóa từ static.
5. Xóa từ public.
6. Xóa từ System.
7. Thay thế println b ng ằ Println.
8. Thay thế println b ng ằ print. Câu h i này đánh đ ch , đây là l i logic ch không ph i ỏ ố ở ỗ ỗ ứ ả l i cú pháp. Câu l nh ỗ ệ System.out.print hoàn toàn h p l , nh ng nó có th có ho c không ợ ệ ư ể ặ làm theo đi u b n d ki n. ề ạ ự ế
9. Xóa m t trong s các ngo c tròn. Thêm vào m t ngo c tròn. ộ ố ặ ộ ặ
1.Đ nh nghĩa này không đúng v i m i ngôn ng l p trình. M t ví d là các ngôn ng đ c t , ị ớ ọ ữ ậ ộ ụ ữ ặ ả xemhttp://en.wikipedia.org/wiki/Declarative_programming. ↩
Ch ng 2: Bi n và ươ ế ki uể
Tr v ở ề M c l c ụ ụ cu n sách ố
2.1 Nói thêm v l nh in ề ệ
B n có th tùy ý đ t bao nhiêu câu l nh vào trong ạ ể ặ ệ main cũng đ c; ượ ch ng h n, ẳ ạ đ in nhi u dòng: ể ề class Hello {
// Generates some simple output.
public static void main(String[] args) {
System.out.println("Hello, world."); // in một dòng
System.out.println("How are you?"); // in dòng nữa
}
}
Nh ví d này đã cho th y, b n có th đ t l i chú thích cu i dòng l nh, ho c đ t nó riêng m t dòng. ư ụ ấ ạ ể ặ ờ ở ố ệ ặ ặ ở ộ
Nh ng c m t ữ ụ ừ đ t ặ gi a hai d u nháy kép ữ ấ đ c g i là ượ ọ chu i ỗ , vì chúng đ c ượ h p thành t m t dãy ợ ừ ộ (chu i) các kí t . Chu i ỗ ự ỗ có th g m b t kì t h p nào t các ch cái, ch s , d u câu, và các kí t ể ồ ấ ổ ợ ừ ữ ữ ố ấ ự đ c ặ bi t khác. ệ
println là tên g i t t c a “print line,” vì sau m i dòng nó thêm vào m t kí t đ c bi t, ọ ắ ủ ỗ ộ ự ặ ệ g i là ọ newline, để đ y con tr xu ng dòng ti p theo trên màn hình. ẩ ỏ ố ế L n t i, khi ầ ớ println đ c g i, các ch m i s xu t ượ ọ ữ ớ ẽ ấ hi nệ ở ế ế dòng k ti p.
Đ hi n th k t qu t nhi u l nh in trên cùng m t dòng, hãy dùng ể ể ị ế ả ừ ề ệ ộ print:
class Hello {
// Phát sinh một số kết quả đơn giản.
public static void main(String[] args) {
System.out.print("Goodbye, ");
System.out.println("cruel world!");
}
}
K t qu xu t hi n trên cùng m t dòng là ế ả ấ ệ ộ Goodbye, cruel world!. Có m t d u cách gi a t “Goodbye” ộ ấ ữ ừ và d u nháy kép ti p theo. D u cách này xu t hi n ấ ế ấ ấ ệ ở ế ả ậ k t qu , vì v y nó ả ưở nh h ng đ n hành vi c a ch ng ế ủ ươ trình.
Nh ng d u cách xu t hi n ngoài c p d u nháy kép thì nói chung không nh h ng gì đ n hành vi c a ữ ấ ấ ệ ặ ấ ả ưở ế ủ ch ng trình. Ch ng h n, tôi đã có th vi t: ươ ẳ ạ ể ế
class Hello {
public static void main(String[] args) {
System.out.print("Goodbye, ");
System.out.println("cruel world!");
}
}
Ch ng trình này s biên d ch và ch y đ c thông su t nh ch ng trình ban đ u. D u ng t cu i ươ ẽ ị ạ ượ ố ư ươ ầ ấ ắ ở ố dòng (d u newline) ấ cũng không ả ưở ớ ủ ươ ậ ể ế nh h ng t i hành vi c a ch ng trình, vì v y tôi cũng có th đã vi t thành:
class Hello { public static void main(String[] args) {
System.out.print("Goodbye, "); System.out.println
("cruel world!");}}
Ch ng trình này cũng ho t đ ng đ c, nh ng nó tr nên ngày càng khó đ c. Các d u ng t dòng và d u ươ ạ ộ ượ ư ở ọ ấ ắ ấ cách r t có ích trong vi c b trí hình th c c a ch ng trình, làm ch ng trình d đ c và d ấ ệ ố ứ ủ ươ ươ ễ ọ ễ đ nh v ị ị l i ỗ h n. ơ
2.2 Bi nế
M t trong nh ng tính năng m nh nh t c a m t ngôn ng l p trình là kh năng thao tác v i các ộ ữ ạ ấ ủ ộ ữ ậ ả ớ bi nế . Bi n là m t tên g i tham chi u đ n m t ế ộ ọ ế ế ộ giá trị. Giá tr là nh ng th có th in ra, l u gi , và (nh ta s ị ữ ứ ể ư ữ ư ẽ th y sau này) thao tác tính toán đ c. Các chu i mà ta đã in đ n gi ( ấ ượ ỗ ế ờ "Hello, World.", "Goodbye, ", v.v.) đ u là nh ng giá tr . ề ữ ị
Đ l u m t giá tr , b n ph i t o ra m t bi n. Vì nh ng giá tr ta mu n l u tr đây là các chu i, nên ta ể ư ộ ị ạ ả ạ ộ ế ữ ị ố ư ữ ở ỗ khai báo bi n m i là m t chu i ế ớ ộ ỗ
String bob;
Đây là câu l nh ệ khai báo, vì nó khai báo r ng bi n ằ ế mang tên bob có ki uể String. M i bi n có m t ki u ỗ ế ộ ể v i tác d ng quy t ớ ụ ế đ nh ị lo i giá tr nào mà bi n ạ ị ế đó có th l u ể ư trữ đ c. Ch ng h n, ki u ượ ẳ ạ ể int có th l u ể ư tr các s nguyên, ữ ố còn ki uể String l u tr chu i. ư ữ ỗ
M t s ki u có tên g i b t đ u b ng ch in và m t s ki u thì b t đ u b ng ch th ng. Ta s h c ý ộ ố ể ọ ắ ầ ằ ữ ộ ố ể ắ ầ ằ ữ ườ ẽ ọ nghĩa c a s phân bi t này v sau, còn bây gi ch c n l u ý đ vi t đúng. Không có ki u nào ủ ự ệ ề ờ ỉ ầ ư ể ế ể g i ọ là Int hay string, và trình biên d ch s ị ẽ bác bỏ n u b n c g ng d ng nên m t cái tên nh v y. ế ạ ố ắ ự ộ ư ậ Đ t o nên m t bi n nguyên, cú pháp là ể ạ ộ ế int bob;, trong đó bob là tên g i tùy ý mà b n đ t cho bi n. Nói ọ ạ ặ ế chung, b n s mu n đ t tên bi n đ ch rõ m c tiêu dùng bi n ạ ẽ ố ặ ế ể ỉ ụ ế đó. Ch ng h n, n u th y các l nh khai ẳ ạ ế ấ ệ
báo bi n sau ế đây:
String firstName;
String lastName;
int hour, minute;
thì b n có th đoán đ c r ng nh ng giá tr nào s đ c l u vào chúng. Ví d này cũng gi i thi u cú ạ ể ượ ằ ữ ị ẽ ượ ư ụ ớ ệ
pháp đ khai báo nhi u bi n v i cùng ki u: ể ề ế ớ ể hour và second đ uề là s nguyên ố (ki uể int). 2.3 L nh gán ệ
Bây gi khi đã t o nên các bi n, ta mu n l u gi nh ng giá tr . ờ ạ ế ố ư ữ ữ ị Ta làm đi u này v i ề ớ l nh gán. ệ bob = "Hello."; // cho bob giá trị "Hello."
hour = 11; // gán giá trị 11 vào hour
minute = 59; // đặt minute là 59
Ví d này có ba l nh gán, và các l i chú thích đi kèm cho th y ba cách khác nhau mà chúng ta đôi khi ụ ệ ờ ấ nói v câu l nh gán. Cách dùng t ề ệ ừ có th gây nh m l n, song ể ầ ẫ ý t ng r t ưở ấ đ n gi n: ơ ả
• Khi khai báo m t bi n, b n t o nên m t ch l u d li u đ c đ t tên. ộ ế ạ ạ ộ ỗ ư ữ ệ ượ ặ
• Khi gán cho m t bi n, b n cho nó m t giá tr . ộ ế ạ ộ ị
M t cách thông d ng đ bi u di n bi n trên gi y là v m t h p v i tên bi n ghi bên ngoài và giá tr bi n ộ ụ ể ể ễ ế ấ ẽ ộ ộ ớ ế ị ế ở ướ ấ ệ beent rong. Hình d i đây cho th y hi u ứ ủ ệ ng c a ba câu l nh gán này:
M t quy t c chung là bi n ph i có cùng ki u v i giá tr mà b n gán cho nó. B n không th l u tr ộ ắ ế ả ể ớ ị ạ ạ ể ư ữ m t ộ String vào trong minute hay m t s nguyên vào ộ ố bob.
M t khác, quy t c này cũng có th gây nh m l n, vì có r t ặ ắ ể ầ ẫ ấ nhi u cách đ b n chuy n giá tr t ki u này ề ể ạ ể ị ừ ể sang ki u khác, và đôi khi Java cũng t đ ng chuy n đ i. Riêng bây gi thì b n nên nh quy t c chung, ể ự ộ ể ổ ờ ạ ớ ắ và sau này ta s nói v nh ng ngo i l . ẽ ề ữ ạ ệ
M t đi u n a d gây nh m đó là có nh ng chu i ộ ề ữ ễ ầ ữ ỗ trông gi ng nh s nguyên nh ng th c ra l i không ố ư ố ư ự ạ ph i. Ch ng h n, ả ẳ ạ bob có thể ch a chu i ứ ỗ "123", v n đ c t o thành t các kí t ố ượ ạ ừ ự 1, 2 và 3, nh ng nó không ư
ph i là ả số 123.
bob = "123"; // hợp lệ
bob = 123; // không hợp lệ
2.4 In các bi nế
Đ hi n th giá tr c a m t bi n, b n có th ể ể ị ị ủ ộ ế ạ ể dùng println ho cặ print:
class Hello {
public static void main(String[] args) {
String firstLine;
firstLine = "Hello, again!";
System.out.println(firstLine);
}
}
Ch ng trình này t o ra ba bi n ươ ạ ế firstLine, gán nó v i giá tr ớ ị "Hello, again!" r i in ồ giá trị đó ra. Khi ta nói “in m t giá tr ,” ộ ị đi u này nghĩa là in ề giá trị c a bi n đó. ủ ế Đ in ể tên c a m t bi n, b n ph i đ t cái tên này ủ ộ ế ạ ả ặ trong c p d u nháy kép. Ch ng h n: ặ ấ ẳ ạ System.out.println("firstLine");
Ví d nh , b n có th vi t ụ ư ạ ể ế
String firstLine; firstLine = "Hello, again!";
System.out.print("The value of firstLine is ");
System.out.println(firstLine);
K t qu c a ch ng trình này là ế ả ủ ươ
The value of firstLine is Hello, again!
Tôi vui m ng thông báo v i b n r ng cú pháp c a l nh in m t bi n thì gi ng nhau b t k ki u c a bi n ừ ớ ạ ằ ủ ệ ộ ế ố ấ ể ể ủ ế đó là gì.
int hour, minute;
hour = 11;
minute = 59;
System.out.print("The current time is ");
System.out.print(hour);
System.out.print(":");
System.out.print(minute);
System.out.println(".");
K t ế qu c a ch ng trình này là ả ủ ươ The current time is 11:59.
C NH BÁO: Đ đ t nhi u giá tr trên cùng m t dòng, cách thông d ng là dùng nhi u l nh Ả ể ặ ề ị ộ ụ ề ệ print và ti p ế theo là println. Nh ng b n ph i nh vi t ư ạ ả ớ ế println ở ố ề ườ ậ ế ả cu i. Trong nhi u môi tr ng l p trình, k t qu c aủ print ch l u gi mà không đ c hi n th đ n t n lúc ỉ ư ữ ượ ể ị ế ậ println đ c g i, khi ượ ọ đó c dòng s xu t hi n ả ẽ ấ ệ cùng lúc. N u b n b m t ế ạ ỏ ấ println, ch ng trình có th k t thúc mà không hi n th k t qu đã đ c l u ươ ể ế ể ị ế ả ượ ư
tr ! ữ
2.5 T khoá ừ
Cách đây vài m c, tôi đã nói r ng b n có th ụ ằ ạ ể đ t m t tên ặ ộ tùy ý cho bi n, nh ng đi u này không h n là ế ư ề ẳ đúng. Có nh ng t nh t đ nh đ c dành riêng trong Java vì chúng đ c trình biên d ch s d ng đ phân ữ ừ ấ ị ượ ượ ị ử ụ ể tách c u trúc c a ch ng trình mà b n vi t; và n u b n dùng nh ng t này đ t cho tên bi n thì trình ấ ủ ươ ạ ế ế ạ ữ ừ ặ ế biên d ch s b l n. Các t nh v y, g i là ị ẽ ị ẫ ừ ư ậ ọ t khóa ừ , bao g m có ồ public, class, void, int, và nhi u t khác. ề ừ B n có th xem danh sách ạ ể đ yầ đ ủ
t i ạ http://download.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html. Trang
này, đ c ượ Oracle cung c p, có ấ đăng tài li u v Java mà ệ ề trong sách này tôi th ng xuyên tham kh o đ n. ườ ả ế 2.6 Toán tử
Toán tử là các kí hi u đ c bi t đ bi u di n các phép tính nh c ng và nhân. H u h t các toán t c a ệ ặ ệ ể ể ễ ư ộ ầ ế ử ủ Java đ u th c hi n theo đúng d ề ự ệ ự đ nh c a b n vì chúng là nh ng kí hi u toán h c thông d ng. Ch ng ị ủ ạ ữ ệ ọ ụ ẳ
h n, toán t c a phép c ng là ạ ử ủ ộ +. Phép tr là ừ -, phép nhân là *, và phép chia là /. 1+1 hour-1 hour*60 + minute minute/60
Các bi u th c có th ch a c tên bi n và con s . Các bi n đ u đ c thay b ng giá tr c a chúng tr c khi ể ứ ể ứ ả ế ố ế ề ượ ằ ị ủ ướ phép tính đ c th c hi n. ượ ự ệ
H n n a, dù phép tr và phép nhân làm đúng đi u b n mu n, song phép chia có th làm b n ng c ơ ữ ừ ề ạ ố ể ạ ạ nhiên. Ch ng h n, ch ng trình này: ẳ ạ ươ
int hour, minute;
hour = 11;
minute = 59;
System.out.print("Number of minutes since midnight: ");
System.out.println(hour*60 + minute);
System.out.print("Fraction of the hour that has passed: "); System.out.println(minute/60);
phát sinh ra k t qu này: ế ả
Number of minutes since midnight: 719
Fraction of the hour that has passed: 0
Dòng đ u tiên thì đúng nh mong đ i, nh ng dòng th hai th t kì qu c. Giá tr c a ầ ư ợ ư ứ ậ ặ ị ủ minute là 59, và 59 chia cho 60 b ng 0.98333, ch không ph i là 0. ằ ứ ả V nấ đề ở đây là Java đã th c hi n phép ự ệ chia nguyên. Khi c hai ả toán h ng ạ đ u là s nguyên (toán h ng là nh ng đ i l ng mà toán t th c hi n tính toán), ề ố ạ ữ ạ ượ ử ự ệ
thì k t qu cũng s là m t s nguyên, và ế ả ẽ ộ ố theo quy đ nh chung, phép chia nguyên ị làm tròn xu ng ố , ngay c trong tr ng h p này khi giá tr sát v i s nguyên phía trên h n. ả ườ ợ ị ớ ố ơ
M t cách làm khác là đi tính ph n trăm thay vì m t phân s : ộ ầ ộ ố
System.out.print("Percentage of the hour that has passed: "); System.out.println(minute*100/60);
K t qu là: ế ả
Percentage of the hour that has passed: 98
M t l n n a k t qu l i đ c làm tròn xu ng, nh ng l n này đáp s đã g n đúng h n. Đ đ c k t qu ộ ầ ữ ế ả ạ ượ ố ư ầ ố ầ ơ ể ượ ế ả chính xác h n, ta có th dùng m t ki u bi n khác, g i là d u ph y đ ng, đ l u tr nh ng giá tr có ơ ể ộ ể ế ọ ấ ẩ ộ ể ư ữ ữ ị ph n th p phân. Ta s ti p t c v n đ này trong ch ng sau. ầ ậ ẽ ế ụ ấ ề ươ
2.7 Th t th c hi n ứ ự ự ệ
Khi trong bi u th c có nhi u h n m t toán t , th t đ nh l ng s tuân theo ể ứ ề ơ ộ ử ứ ự ị ượ ẽ quy t c u tiên ắ ư . Gi i ả thích đ y đ quy t c u tiên này có th ph c t p, nh ng đ b t đ u, b n ch c n nh : ầ ủ ắ ư ể ứ ạ ư ể ắ ầ ạ ỉ ầ ớ • Các phép nhân và chia ph i đ c th c hi n tr c c ng và tr . Vì v y ả ượ ự ệ ướ ộ ừ ậ 2*3-1 b ng 5 ch không ph i 4, ằ ứ ả và 2/3-1 đ c -1, ch không ph i 1 (hãy nh r ng phép chia nguyên ượ ứ ả ớ ằ 2/3 b ng 0). ằ • N u các toán t có cùng đ u tiên thì chúng đ c đ nh l ng t trái sang ph i. Vì v y, trong bi u ế ử ộ ư ượ ị ượ ừ ả ậ ể th cứ minute*100/60, phép nhân đ c th c hi n tr c, cho ra ượ ự ệ ướ 5900/60, và cu i cùng là ố 98. N u các ế phép toán ch y t ph i qua trái, k t qu đã thành ạ ừ ả ế ả 59*1 t c là ứ 59, đi u này là sai. ề
• B t c khi nào mu n v t quy t c u tiên (hay khi b n không ch c quy t c này nh th nào), b n có th ấ ứ ố ượ ắ ư ạ ắ ắ ư ế ạ ể dùng c p ngo c đ n. Bi u th c trong c p ngo c đ n đ c th c hi n tr c, b i v y ặ ặ ơ ể ứ ặ ặ ơ ượ ự ệ ướ ở ậ 2 *(3-1) là 4. B n ạ cũng có th dùng c p ngo c đ n đ bi u th c tr nên d đ c, nh v i ể ặ ặ ơ ể ể ứ ở ễ ọ ư ớ (minute * 100) / 60, ngay c ả
khi không có nó thì k t qu cũng không đ i. ế ả ổ
2.8 Các thao tác v i chu i ớ ỗ
Nói chung, b n không th th c hi n các phép toán đ i v i chu i, ngay c khi chu i trông gi ng nh ạ ể ự ệ ố ớ ỗ ả ỗ ố ư nh ng con s . Vì v y các bi u th c sau đây đ u không h p l : ữ ố ậ ể ứ ề ợ ệ
bob - 1 "Hello"/123 bob * "Hello"
Ti n th , qua nh ng bi u th c trên b n có phân bi t đ c li u ệ ể ữ ể ứ ạ ệ ượ ệ bob là s nguyên hay chu i không? ố ỗ Không. Cách duy nh t đ bi t đ c ki u c a bi n là nhìn vào n i nó đ c khai báo. ấ ể ế ượ ể ủ ể ơ ượ Đi u thú v là toán t ề ị ử + có tác d ng v i chu i, nh ng có l không ho t đ ng theo cách b n mong đ i. ụ ớ ỗ ư ẽ ạ ộ ạ ợ V i các ớ String, toán tử + có nhi m v ệ ụn i ố , nghĩa là ghép n i ti p hai toán h ng v i nhau. B i v y ố ế ạ ớ ở ậ "Hello, " + "world." s cho ra chu i ẽ ỗ "Hello, world." còn bob + "ism" thì thêm đuôi ism vào b t kì ch gì ấ ữ mà bob l u tr , cách đ t tên này này th t ti n trong tay nh ng ng i quen tính bài bác. ư ữ ặ ậ ệ ữ ườ
2.9 K t h p ế ợ
Đ n gi ta đã xem xét nh ng thành ph n c a ngôn ng l p trình—bi n, bi u th c, và câu l nh—m t ế ờ ữ ầ ủ ữ ậ ế ể ứ ệ ộ cách bi t l p, mà ch a nói v cách k t h p chúng. ệ ậ ư ề ế ợ
M t trong nh ng đ c đi m có ích nh t c a ngôn ng l p trình là kh năng t p h p nh ng thành ph n ộ ữ ặ ể ấ ủ ữ ậ ả ậ ợ ữ ầ nh r i ỏ ồ k t h p ế ợ chúng l i. Ch ng h n, ta bi t cách tính nhân và bi t dùng l nh in; nh v y hóa ra là có ạ ẳ ạ ế ế ệ ư ậ
th k t h p chúng l i thành m t câu l nh: ể ế ợ ạ ộ ệ
System.out.println(17 * 3);
B t kì bi u th c nào có s , chu i, và bi n đ u có th dùng trong l nh in. Ta đã th y m t ví d : ấ ể ứ ố ỗ ế ề ể ệ ấ ộ ụ System.out.println(hour*60 + minute);
Nh ng b n cũng có th đ t bi u th c b t kì v ph i c a m t l nh gán: ư ạ ể ặ ể ứ ấ ở ế ả ủ ộ ệ
int percentage;
percentage = (minute * 100) / 60;
Ngay bây gi thì tính năng này xem ra ch a có gì n t ng, nh ng ta s th y nh ng ví d mà cách k t ờ ư ấ ượ ư ẽ ấ ữ ụ ế h p này bi u di n nh ng phép tính ph c t p m t cách g n gàng, ngăn n p. ợ ể ễ ữ ứ ạ ộ ọ ắ
C NH BÁO: V trái c a m t l nh gán ph i là m t tên Ả ế ủ ộ ệ ả ộ bi nế , ch không ph i m t bi u th c. Đó là vì v ứ ả ộ ể ứ ế trái dùng đ ch đ nh v trí l u gi k t qu . Các bi u th c thì không th hi n v trí l u gi này, mà ch th ể ỉ ị ị ư ữ ế ả ể ứ ể ệ ị ư ữ ỉ ể
hi n giá tr . Vì v y cách vi t sau không h p l : ệ ị ậ ế ợ ệ minute+1 = hour;.
2.10 Thu t ng ậ ữ
bi n: ế
Tên đ c tham chi u đ n m t giá tr . ượ ế ế ộ ị
giá tr :ị
M t con s ho c chu i kí t (ho c nh ng th khác sau này đ c đ t tên) mà l u tr đ c vào trong ộ ố ặ ỗ ự ặ ữ ứ ượ ặ ư ữ ượ m t bi n. M i giá tr thu c v m t ki u. ộ ế ỗ ị ộ ề ộ ể
ki u: ể
M t t p h p g m các giá tr . Ki u c a bi n quy t đ nh nh ng giá tr nào có th l u tr trong ộ ậ ợ ồ ị ể ủ ế ế ị ữ ị ể ư ữ bi n đó. Nh ng ki u mà ta đã g p bao g m ki u s nguyên ( ế ữ ể ặ ồ ể ố int trong Java) và chu i ỗ (String trong Java).
t khoá: ừ
T dành riêng cho trình biên d ch đ phân tách m t ch ng trình. B n không th dùng nh ng t ừ ị ể ộ ươ ạ ể ữ ừ khoá nhưpublic, class và void đ đ t tên bi n. ể ặ ế
l nh khai báo: ệ
Câu l nh nh m t o ra m t bi n m i và quy đ nh ki u cho nó. ệ ằ ạ ộ ế ớ ị ể
l nh gán: ệ
L nh đ gán m t giá tr cho m t bi n. ệ ể ộ ị ộ ế
bi u th c: ể ứ
T h p c a các bi n, toán t , và giá tr nh m bi u di n m t giá tr k t qu duy nh t. Bi u th c cũng có ổ ợ ủ ế ử ị ằ ể ễ ộ ị ế ả ấ ể ứ ki u; ki u này đ c quy t đ nh b i các toán t và toán h ng. ể ể ượ ế ị ở ử ạ
toán t : ử
Kí hi u dùng đ bi u di n m t phép tính đ n nh t nh c ng, nhân, ho c n i chu i. ệ ể ể ễ ộ ơ ấ ư ộ ặ ố ỗ toán h ng: ạ
M t trong nh ng giá tr mà toán t th c hi n v i. ộ ữ ị ử ự ệ ớ
ưu tiên:
Th t mà nh ng bi u th c bao g m nhi u toán t và toán h ng đ c đ nh l ng. ứ ự ữ ể ứ ồ ề ử ạ ượ ị ượ n i: ố
Ghép n i ti p hai toán h ng. ố ế ạ
k t h p: ế ợ
Kh năng ghép nh ng bi u th c và câu l nh đ n gi n thành nh ng bi u th c và câu l nh ph c h p đ ả ữ ể ứ ệ ơ ả ữ ể ứ ệ ứ ợ ể
bi u di n g n gàng các thao tác tính toán. ể ễ ọ
2.11 Bài t pậ
BÀI T P 1 Ậ
N u đang đ c quy n sách này trên l p, b n có th thích bài t p này: hãy tìm m t ng i b n ế ọ ể ớ ạ ể ậ ộ ườ ạ đ ch i trò “Stump the Chump”: ể ơ
B t đ u t m t ch ng trình biên d ch và ch y đ c tr n tru. T ng ng i m t quay m t đi ắ ầ ừ ộ ươ ị ạ ượ ơ ừ ườ ộ ặ trong lúc ng i kia gài m t l i vào ch ng trình. Sau đó ng i th nh t quay l i r i c tìm ườ ộ ỗ ươ ườ ứ ấ ạ ồ ố và s a l i. N u tìm đ c l i mà không c n biên d ch, s đ c hai đi m; tìm đ c sau khi ử ỗ ế ượ ỗ ầ ị ẽ ượ ể ượ biên d ch thì đ c 1 đi m; và n u không tìm đ c thì ng i kia s đ c m t đi m. ị ượ ể ế ượ ườ ẽ ượ ộ ể
BÀI T P 2 Ậ
1. Hãy t o ra m t ch ng trình có tên ạ ộ ươ Date.java. Sao chép ho c gõ vào m t ch ng trình ki u ặ ộ ươ ể nh “Hello, World” r i đ m b o ch c r ng b n có th biên d ch và ch y đ c ch ng trình. ư ồ ả ả ắ ằ ạ ể ị ạ ượ ươ 2. Làm theo ví d M c 2.4, hãy vi t m t ch ng trình đ t o ra các ụ ở ụ ế ộ ươ ể ạ
bi nế day, date, month và year. day s ch a ngày trong tu n còn ẽ ứ ầ date thì ch a ngày trong ứ tháng. T ng bi n s có ki u gì? Hãy gán giá tr vào nh ng bi n này đ bi u di n ngày hôm ừ ế ẽ ể ị ữ ế ể ể ễ nay.
3. In giá tr t ng bi n trên m i dòng riêng. Đây là m t b c trung gian và r t c n đ ki m tra ị ừ ế ỗ ộ ướ ấ ầ ể ể
r ng ch ng trình còn ho t đ ng n th a. ằ ươ ạ ộ ổ ỏ
4. S a ch ng trình đ in ra ngày theo d ng chu n Hoa Kỳ: ử ươ ể ạ ẩ Saturday, July 16, 2011.
5. S a l i ch ng trình l n n a đ k t qu thu đ c là: ử ạ ươ ầ ữ ể ế ả ượ
American format:
Saturday, July 16, 2011
European format:
Saturday 16 July, 2011
M c đích c a bài t p này là dùng phép n i chu i đ hi n th các giá tr có ki u khác ụ ủ ậ ố ỗ ể ể ị ị ể nhau (int và String), đ ng th i th c hành kĩ năng phát tri n d n ch ng trình qua vi c m i ồ ờ ự ể ầ ươ ệ ỗ l n ch thêm vào m t vài câu l nh. ầ ỉ ộ ệ
BÀI T P 3 Ậ
1. Hãy t o ra m t ch ng trình m i có tên là ạ ộ ươ ớ Time.java. T gi tr đi, tôi không nh c b n b t ừ ờ ở ắ ạ ắ đ u b ng vi c t o m t ch ng trình nh nh ng ch y đ c; song b n nên làm đi u này. ầ ằ ệ ạ ộ ươ ỏ ư ạ ượ ạ ề 2. T ví d M c 2.6, hãy t o ra các bi n có tên ừ ụ ở ụ ạ ế hour, minute và second, r i gán cho chúng giá ồ
tr bi u di n g n đúng gi hi n t i. Dùng cách đ m s 24 gi , theo đó 2 gi chi u s ng v i ị ể ễ ầ ờ ệ ạ ế ố ờ ờ ề ẽ ứ ớ giá tr c a ị ủ hour b ng 14. ằ
3. Làm cho ch ng trình tính toán r i in ra s giây k t n a đêm. ươ ồ ố ể ừ ử
4. Làm cho ch ng trình tính toán r i in ra s giây t gi đ n ươ ồ ố ừ ờ ế h t ngày hôm nay. ế 5. Làm cho ch ng trình tính toán r i in ra s ph n trăm th i gian đã trôi qua trong ngày hôm ươ ồ ố ầ ờ nay.
6. Thay đ i các giá tr c a ổ ị ủ hour, minute và second đ ph n ánh th i gian hi n t i (coi nh có ể ả ờ ệ ạ ư th i gian trôi qua k t l n ch y tr c), và ki m tra đ đ m b o r ng ch ng trình ho t ờ ể ừ ầ ạ ướ ể ể ả ả ằ ươ ạ đ ng đ c v i nhi u giá tr khác nhau. ộ ượ ớ ề ị
M c đích c a bài t p này là v n d ng m t s phép toán, và b t đ u suy nghĩ v nh ng d ụ ủ ậ ậ ụ ộ ố ắ ầ ề ữ ữ li u ph c h p nh th i gian trong ngày, v n đ c bi u di n b i nhi u giá tr . Đ ng th i, ệ ứ ợ ư ờ ố ượ ể ễ ở ề ị ồ ờ b n cũng có th v p ph i nhi u v n đ khi tính ph n trăm v i các s ạ ể ấ ả ề ấ ề ầ ớ ố int; đây chính là lí do d n đ n vi c dùng s có d u ph y đ ng trong ch ng sau. ẫ ế ệ ố ấ ẩ ộ ươ
G I Ý: có th b n s c n dùng thêm các bi n đ l u gi t m th i nh ng giá tr trong quá Ợ ể ạ ẽ ầ ế ể ư ữ ạ ờ ữ ị trình tính toán. Các bi n ki u này, v n đ c dùng trong tính toán nh ng không bao gi ế ể ố ượ ư ờ đ c in ra, đôi khi đ c g i là bi n trung gian ho c bi n t m. ượ ượ ọ ế ặ ế ạ
Ch ng 3: Ph ng th c ươ ươ ứ r ng ỗ
Tr v ở ề M c l c ụ ụ cu n sách ố
3.1 D u ph y đ ng ấ ẩ ộ
Ở ươ ướ ặ ụ ặ ữ ố ử ộ ạ ợ ch ng tr c ta đã g p tr c tr c khi tính toán nh ng s không nguyên. Ta đã s a m t cách t m b b ng vi c tính s ph n trăm thay vì s th p phân, nh ng m t gi i pháp t ng quát h n s là dùng s có ằ ệ ố ầ ố ậ ư ộ ả ổ ơ ẽ ố d u ph y đ ng, đ bi u di n đ c c s nguyên l n s có ph n th p phân. Trong Java, ki u d u ph y ấ ẩ ộ ể ể ễ ượ ả ố ẫ ố ầ ậ ể ấ ẩ đ ng có tên ộ double, là ch g i t t c a “double-precision” (đ chu n xác kép). ữ ọ ắ ủ ộ ẩ
B n có th t o nên các bi n ph y đ ng r i gán giá tr cho chúng theo cú pháp gi ng nh ta đã làm v i ạ ể ạ ế ẩ ộ ồ ị ố ư ớ nh ng ki u d li u khác. Ch ng h n: ữ ể ữ ệ ẳ ạ
double pi;
pi = 3.14159;
Vi c khai báo m t bi n đ ng th i gán giá tr cho nó cũng h p l : ệ ộ ế ồ ờ ị ợ ệ
int x = 1;
String empty = "";
double pi = 3.14159;
Cú pháp này r t thông d ng; vi c k t h p gi a khai báo và gán đôi khi còn đ c g i là phép ấ ụ ệ ế ợ ữ ượ ọ kh i t o ở ạ .
M c dù các s ph y đ ng r t h u ích nh ng chúng cũng là ngu n gây nên r c r i, vì d ng nh có ph n ặ ố ẩ ộ ấ ữ ư ồ ắ ố ườ ư ầ trùng nhau gi a các s nguyên và s ph y đ ng. Ch ng h n, n u b n có giá tr ữ ố ố ẩ ộ ẳ ạ ế ạ ị 1, thì đó là s nguyên, s ố ố ph y đ ng, hay c hai? ẩ ộ ả
Java phân bi t giá tr s nguyên ệ ị ố 1 v i giá tr ph y đ ng ớ ị ẩ ộ 1.0, dù r ng chúng có v cùng là m t s . Chúng ằ ẻ ộ ố thu c v hai ki u d li u khác nhau, và nói ch t ch thì b n không đ c phép gán giá tr ki u này cho ộ ề ể ữ ệ ặ ẽ ạ ượ ị ể
m t bi n ki u khác. Ch ng h n, câu l nh sau là h p l : ộ ế ể ẳ ạ ệ ợ ệ
int x = 1.1;
vì bi n v trái là ế ở ế int còn giá tr v ph i là ị ở ế ả double. Nh ng r t d quên m t quy t c này, đ c bi t là vì ư ấ ễ ấ ắ ặ ệ
có nh ng n i mà Java s t đ ng chuy n t m t ki u này sang ki u khác. Ch ng h n: ữ ơ ẽ ự ộ ể ừ ộ ể ể ẳ ạ double y = 1;
v lý thì không h p l , nh ng Java v n cho phép đi u này nh cách t đ ng chuy n đ i ề ợ ệ ư ẫ ề ờ ự ộ ể ổ
từ int sang double. S d dãi này khá ti n l i, song có th g p v n đ , ch ng h n: ự ễ ệ ợ ể ặ ấ ề ẳ ạ double y = 1 / 3;
B n có th trông đ i r ng bi n ạ ể ợ ằ ế y nh n giá tr ậ ị 0.333333, v n là m t giá tr ph y đ ng hoàn toàn h p l , ố ộ ị ẩ ộ ợ ệ song th c ra nó nh n đ c ự ậ ượ 0.0. Lý do là bi u th c v ph i là t s gi a hai s nguyên, vì v y Java th c ể ứ ế ả ỉ ố ữ ố ậ ự hi n phép ệ chia nguyên, và cho giá tr s nguyên b ng ị ố ằ 0. Chuy n thành d ng s ph y đ ng, k t qu ể ạ ố ẩ ộ ế ả là 0.0.
M t cách gi i quy t v n đ này (khi b n đã hình dung ra) là làm cho v ph i tr thành m t bi u th c ộ ả ế ấ ề ạ ế ả ở ộ ể ứ ch a s ph y đ ng: ứ ố ẩ ộ
double y = 1.0 / 3.0;
B ng cách này đã đ t ằ ặ y b ng ằ 0.333333, nh d ki n. ư ự ế
Các toán t mà ta đã g p đ n gi —c ng, tr , nhân, và chia—cũng làm vi c đ c v i các giá tr d u ph y ử ặ ế ờ ộ ừ ệ ượ ớ ị ấ ẩ đ ng, m c dù b n có th th y thú v khi bi t đ c r ng c ch bên trong thì khác h n. Th c ra, đa s các ộ ặ ạ ể ấ ị ế ượ ằ ơ ế ẳ ự ố b vi x lý đ u có ph n m m chuyên d ng đ th c hi n các phép tính có d u ph y đ ng. ộ ử ề ầ ề ụ ể ự ệ ấ ẩ ộ
3.2 Chuy n đ i t ể ổ ừ double sang int
Nh tôi đã nói, Java quy đ i các s ư ổ ố int thành double m t cách t đ ng n u th y c n thi t, vì trong quá ộ ự ộ ế ấ ầ ế trình chuy n đ i không b m t thông tin. Ng c l i, chuy n t ể ổ ị ấ ượ ạ ể ừ double sang int l i c n ph i làm tròn s . ạ ầ ả ố Java không t đ ng làm vi c này, đ đ m b o r ng b n, ng i l p trình, cũng bi t đ c r ng ph n th p ự ộ ệ ể ả ả ằ ạ ườ ậ ế ượ ằ ầ ậ phân c a s s b m t đi. ủ ố ẽ ị ấ
Cách đ n gi n nh t đ chuy n m t giá tr s ph y đ ng sang s nguyên là th c hi n vi c ơ ả ấ ể ể ộ ị ố ẩ ộ ố ự ệ ệ đ nh ị ki uể (typecast). S dĩ g i là đ nh ki u vì b ng cách đó ta có th l y m t giá tr thu c ki u này r i “ n ở ọ ị ể ằ ể ấ ộ ị ộ ể ồ ấ đ nh” nó thành ki u khác (nh vi c đ nh hình b ng khuôn đúc kim lo i). ị ể ư ệ ị ằ ạ
Cú pháp c a đ nh ki u là đ t tên ki u gi a c p ngo c tròn r i dùng nó nh m t toán t . Ch ng h n, ủ ị ể ặ ể ữ ặ ặ ồ ư ộ ử ẳ ạ double pi = 3.14159;
int x = (int) pi;
Toán tử (int) có tác d ng chuy n b t kì th gì đi sau nó thành m t s nguyên, b i v y ụ ể ấ ứ ộ ố ở ậ x nh n giá tr ậ ị b ng 3. ằ
Đ nh ki u có quy n u tiên cao h n so v i các toán t s h c, b i v y ví d sau, tr c h t giá tr c a ị ể ề ư ơ ớ ử ố ọ ở ậ ở ụ ướ ế ị ủ
pi đ c chuy n thành s nguyên, và k t qu s là 60.0, ch không ph i 62. ượ ể ố ế ả ẽ ứ ả
double pi = 3.14159;
double x = (int) pi * 20.0;
Vi c chuy n thành s nguyên s luôn làm tròn xu ng, ngay c khi ph n th p phân là 0.99999999. Cách ệ ể ố ẽ ố ả ầ ậ ho t đ ng này (quy n u tiên và vi c làm tròn) có th khi n cho vi c đ nh ki u d gây nên l i. ạ ộ ề ư ệ ể ế ệ ị ể ễ ỗ
3.3 Các ph ng th c Math ươ ứ
Khi làm toán, có l b n đã th y các hàm nh sin và log, đ ng th i cũng bi t cách tính các bi u th c nh ẽ ạ ấ ư ồ ờ ế ể ứ ư sin(π/2) và log(1/x). Đ u tiên, b n l ng giá bi u th c trong c p ngo c tròn, v n đ c g i là ầ ạ ượ ể ứ ặ ặ ố ượ ọ đ i s ố ố c a ủ hàm. Ti p theo b n l ng giá b n thân hàm đó, b ng cách tra b ng ho c tính toán. ế ạ ượ ả ằ ả ặ Công đo n này có th đ c áp d ng l p l i đ l ng giá nh ng bi u th c ph c t p h n nh ạ ể ượ ụ ặ ạ ể ượ ữ ể ứ ứ ạ ơ ư log(1/sin(π/2)). Đ u tiên, b n l ng giá đ i s c a hàm đ ng trong cùng, r i l ng giá b n thân hàm ầ ạ ượ ố ố ủ ứ ồ ượ ả đó, và c nh v y. ứ ư ậ
Java cung c p cho ta các hàm đ th c hi n nh ng phép toán thông d ng nh t. Nh ng hàm này đ c g i ấ ể ự ệ ữ ụ ấ ữ ượ ọ là ph ng th c ươ ứ . Các ph ng th c toán h c đ c kích ho t b ng cách dùng cú pháp t ng t nh câu ươ ứ ọ ượ ạ ằ ươ ự ư
l nh ệ print mà ta đã g p: ặ
double root = Math.sqrt(17.0);
double angle = 1.5;
double height = Math.sin(angle);
Ví d đ u tiên đ t ụ ầ ặ root b ng căn b c hai c a 17. Ví d th hai đi tìm sin c a giá tr ằ ậ ủ ụ ứ ủ ị angle, v n là ố 1.5. Java gi thi t r ng nh ng giá tr b n dùng v i ả ế ằ ữ ị ạ ớ sin và các hàm l ng giác khác ( ượ cos, tan) đ u tính theo ề radian.
Đ chuy n t đ sang radian, b n có th chia cho 360 đ ng th i nhân v i 2π. Th t ti n là Java có cung ể ể ừ ộ ạ ể ồ ờ ớ ậ ệ
c pấ Math.PI:
double degrees = 90;
double angle = degrees * 2 * Math.PI / 360.0;
L u ý r ng ch ư ằ ữ PI đ u vi t in toàn b . Java không nh n ra ề ế ộ ậ Pi, pi, hay pie.
M t ph ng th c h u d ng khác có trong l p ộ ươ ứ ữ ụ ớ Math là round, đ làm tròn m t giá tr s ph y đ ng v s ể ộ ị ố ẩ ộ ề ố
nguyên g n đó nh t r i tr l i m t ầ ấ ồ ả ạ ộ int.
int x = Math.round(Math.PI * 20.0);
Trong tr ng h p này phép nhân x y ra đ u tiên, tr c khi ph ng th c đ c kích ho t. K t qu là 63 ườ ợ ả ầ ướ ươ ứ ượ ạ ế ả (đ c làm tròn lên t 62.8319). ượ ừ
3.4 K t h p ế ợ
Cũng nh v i các hàm toán h c, nh ng ph ng th c trong Java có th đ c ư ớ ọ ữ ươ ứ ể ượ k t h p ế ợ l i, ạ nghĩa là b n ạ có th dùng m t bi u th c làm thành ph n trong bi u th c khác. Ch ng h n, b n có th dùng b t kì ể ộ ể ứ ầ ể ứ ẳ ạ ạ ể ấ bi u th c nào làm đ i s cho m t ph ng th c: ể ứ ố ố ộ ươ ứ
double x = Math.cos(angle + Math.PI/2);
Câu l nh này l y giá tr ệ ấ ị Math.PI, đem chia cho hai r i c ng k t qu thu đ c vào giá tr c a bi n ồ ộ ế ả ượ ị ủ ế angle. Ti p theo, t ng này đ c truy n làm tham s cho ế ổ ượ ề ố cos. (PI là tên c a m t bi n, ch không ph i m t ủ ộ ế ứ ả ộ ph ng th c; b i v y mà không có đ i s nào, th m chí không có c đ i s r ng ươ ứ ở ậ ố ố ậ ả ố ố ỗ ()). B n cũng có th l y k t qu c a m t ph ng th c đ truy n làm đ i s cho ph ng th c khác: ạ ể ấ ế ả ủ ộ ươ ứ ể ề ố ố ươ ứ
double x = Math.exp(Math.log(10.0));
Trong Java, ph ng th c ươ ứ log luôn dùng c s b ng ơ ố ằ e, b i v y câu l nh này tìm loga c s ở ậ ệ ơ ố e c a 10 r i ủ ồ
nâng e lên s mũ đó. K t qu đ c gán cho ố ế ả ượ x; hi v ng r ng b n bi t phép tính này đ làm gì. ọ ằ ạ ế ể 3.5 B sung nh ng ph ng th c m i ổ ữ ươ ứ ớ
Đ n bây gi , chúng ta m i ch dùng nh ng ph ng th c có s n trong Java, song th t ra có th t o ra ế ờ ớ ỉ ữ ươ ứ ẵ ậ ể ạ nh ng ph ng th c m i. ữ ươ ứ ớ Ta đã th y m t l i đ nh nghĩa cho ph ng th c ấ ộ ờ ị ươ ứ main. Ph ng th c tên ươ ứ
là main có ý nghĩa đ c bi t, song cú pháp c a nó cũng gi ng nh các ph ng th c khác: ặ ệ ủ ố ư ươ ứ public static void TÊN( DANH SÁCH THAM SỐ ) { CÁC CÂU LỆNH }
B n có th l y tên b t kì đ đ t cho ph ng th c m i, mi n là không ph i ạ ể ấ ấ ể ặ ươ ứ ớ ễ ả main hay m t t khóa Java ộ ừ nào đó. Theo quy c, các ph ng th c Java b t đ u b ng ch th ng và dùng cách vi t in t ng ch đ u ướ ươ ứ ắ ầ ằ ữ ườ ế ừ ữ ầ c a t (còn g i là “camel caps”), m t tên g i thú v đ ch nh ng cái tên ki u ủ ừ ọ ộ ọ ị ể ỉ ữ ể
như jammingWordsTogetherLikeThis.
Danh sách các tham s thì quy đ nh nh ng thông tin (n u có) mà b n ph i cung c p khi dùng (hay ố ị ữ ế ạ ả ấ kích ho t ạ ) ph ng th c m i này. ươ ứ ớ
Tham s c a ph ng th c ố ủ ươ ứ main là String[] args; đi u này nghĩa là ai mu n kích ho t ề ố ạ main thì ph i cung ả c p m t m ng các chu i (String) (ta s bàn đ n m ng Ch ng ấ ộ ả ỗ ẽ ế ả ở ươ 12). M t s ph ng th c ta t p vi t đ u ộ ố ươ ứ ậ ế ầ
tay thì không có tham s nào, vì v y cú pháp s có d ng nh sau: ố ậ ẽ ạ ư
public static void newLine() {
System.out.println("");
}
Ph ng th c này có tên ươ ứ newLine, và c p ngo c tròn không ch a gì đ ng nghĩa v i vi c ph ng th c này ặ ặ ứ ồ ớ ệ ươ ứ không nh n tham s . Nó ch có m t câu l nh, nh m in m t ậ ố ỉ ộ ệ ằ ộ String r ng, đ c bi u th b i ỗ ượ ể ị ở "". Vi c in ệ m t ộ String mà không có ch nào trong đó d ng nh là vi c vô ích, nh ng vì ữ ườ ư ệ ư println s nh y xu ng ẽ ả ố dòng d i sau khi in, nên câu l nh này có tác d ng xu ng dòng. ướ ệ ụ ố
Trong main ta kích ho t ph ng th c m i này cũng gi ng nh cách ta kích ho t các ph ng th c c a ạ ươ ứ ớ ố ư ạ ươ ứ ủ
Java:
public static void main(String[] args) {
System.out.println("First line.");
newLine();
System.out.println("Second line.");
}
K t qu c a ch ng trình này là ế ả ủ ươ
First line.
Second line.
L u ý đ n dòng tr ng gi a hai dòng ch trên. Ta ph i làm gì n u mu n hai dòng này cách nhau xa h n? ư ế ố ữ ữ ả ế ố ơ Ta có th liên ti p kích ho t ph ng th c m i này: ể ế ạ ươ ứ ớ
public static void main(String[] args) {
System.out.println("First line.");
newLine();
newLine();
newLine();
System.out.println("Second line.");
}
Ho c ta cũng có th vi t m t ph ng th c m i khác, có tên ặ ể ế ộ ươ ứ ớ threeLine, đ in ra ba dòng tr ng: ể ố public static void threeLine() {
newLine(); newLine(); newLine();
}
public static void main(String[] args) {
System.out.println("First line.");
threeLine();
System.out.println("Second line.");
}
B n có th nh n th y vài đi u sau t ch ng trình trên: ạ ể ậ ấ ề ừ ươ
•Có th kích ho t cùng m t ph ng th c nhi u l n. ể ạ ộ ươ ứ ề ầ
•Trong m t ph ng th c, b n có th kích ho t m t ph ng th c khác. tr ng h p này, ộ ươ ứ ạ ể ạ ộ ươ ứ Ở ườ ợ main kích
ho t ạ threeLine còn threeLine thì kích ho t ạ newLine.
•Trong threeLine tôi đã vi t ba câu l nh trên cùng m t dòng; đây là đi u hoàn toàn h p l (hãy nh l i ế ệ ộ ề ợ ệ ớ ạ r ng các d u tr ng và d u xu ng dòng th ng không làm thay đ i ý nghĩa c a ch ng trình). M c dù ta ằ ấ ố ấ ố ườ ổ ủ ươ ặ nên đ t m i câu l nh trên m t dòng riêng, song đôi khi tôi v n phá v nguyên t c này. ặ ỗ ệ ộ ẫ ỡ ắ Có th b n s t h i t i sao l i phi n ph c t o ra nh ng ph ng th c m i nh v y. Có m t vài lí do, mà ể ạ ẽ ự ỏ ạ ạ ề ứ ạ ữ ươ ứ ớ ư ậ ộ hai lí do trong s đó th hi n qua ví d trên là: ố ể ệ ụ
1.Vi c t o ph ng th c m i cho ta c h i đ t tên cho m t nhóm các câu l nh. Nh ng ph ng th c có ệ ạ ươ ứ ớ ơ ộ ặ ộ ệ ữ ươ ứ th làm đ n gi n ch ng trình qua vi c n gi u nh ng thao tác tính toán ph c t p phía sau m t câu ể ơ ả ươ ệ ẩ ấ ữ ứ ạ ộ l nh đ n gi n, và qua vi c dùng nh ng t ti ng Anh thay cho mã l nh bí hi m. Theo b n, cách vi t nào ệ ơ ả ệ ữ ừ ế ệ ể ạ ế rõ ràng h n, ơ newLine hay System.out.println("")?
2.Vi c t o ph ng th c m i có th rút ng n ch ng trình b ng cách lo i b nh ng đo n mã l nh l p đi ệ ạ ươ ứ ớ ể ắ ươ ằ ạ ỏ ữ ạ ệ ặ l p l i. Ch ng h n, đ in chín dòng tr ng liên ti p, b n ch c n kích ho t ặ ạ ẳ ạ ể ố ế ạ ỉ ầ ạ threeLine đúng ba l n. ầ Ở ụ m c 7.6 ta s quay tr l i câu h i này đ ng th i k thêm m t s l i ích khác c a vi c chia nh ch ng ẽ ở ạ ỏ ồ ờ ể ộ ố ợ ủ ệ ỏ ươ trình thành các ph ng th c. ươ ứ
3.6 L p và ph ng th c ớ ươ ứ
Ch p n i l i nh ng đo n mã t m c tr c, ta có l i đ nh nghĩa l p nh sau: ắ ố ạ ữ ạ ừ ụ ướ ờ ị ớ ư
class NewLine {
public static void newLine() {
System.out.println("");
}
public static void threeLine() {
newLine(); newLine(); newLine();
}
public static void main(String[] args) {
System.out.println("First line.");
threeLine();
System.out.println("Second line.");
}
}
Dòng th nh t cho bi t r ng đó là l i đ nh nghĩa m t l p m i có tên ứ ấ ế ằ ờ ị ộ ớ ớ NewLine. L pớ là t p h p các ậ ợ ph ng th c có liên quan đ n nhau. Trong tr ng h p này, l p v i tên g i ươ ứ ế ườ ợ ớ ớ ọ NewLine có ch a 3 ph ng ứ ươ th c tên là ứ newLine, threeLine, và main.
M t l p khác mà ta đã g p là l p ộ ớ ặ ớ Math. Nó g m các ph ng th c có tên ồ ươ ứ sqrt, sin, v.v. Khi kích ho t m t ạ ộ ph ng th c toán h c, ta ph i nêu tên c a l p ( ươ ứ ọ ả ủ ớ Math) và tên c a ph ng th c. Đó là lý do mà v cú ủ ươ ứ ề
pháp, có đi m khác bi t nh gi a các ph ng th c Java và các ph ng th c mà ta vi t: ể ệ ỏ ữ ươ ứ ươ ứ ế Math.pow(2.0, 10.0);
newLine();
Câu l nh th nh t kích ho t ph ng th c ệ ứ ấ ạ ươ ứ pow trong l pớ Math (đ đ a đ i s th nh t lên lũy th a c p ể ư ố ố ứ ấ ừ ấ
c a đ i s th hai). Câu l nh ti p theo kích ho t ph ng th c ủ ố ố ứ ệ ế ạ ươ ứ newLine, mà Java gi s r ng nó có ả ử ằ ở trong l p mà ta đang (t c là l p ớ ứ ớ NewLine).
N u b n th kích ho t nh m m t ph ng th c t l p khác, trình biên d ch s phát sinh m t l i. Ch ng ế ạ ử ạ ầ ộ ươ ứ ừ ớ ị ẽ ộ ỗ ẳ h n, n u b n gõ vào: ạ ế ạ
pow(2.0, 10.0);
Trình biên d ch s nói ki u nh , “Không th tìm th y ph ng th c có tên ị ẽ ể ư ể ấ ươ ứ pow trong l pớ NewLine.” N u ế b n t ng th y l i thông báo này và có l đã t h i r ng t i sao nó ph i tìm ạ ừ ấ ờ ẽ ự ỏ ằ ạ ả pow trong l i đ nh nghĩa l p ờ ị ớ
c a b n, thì bây gi b n đã bi t r i đó. ủ ạ ờ ạ ế ồ
3.7 Ch ng trình có nhi u ph ng th c ươ ề ươ ứ
Khi b n nhìn vào l i đ nh nghĩa m t l p có ch a nhi u ph ng th c, t t s có xu h ng mu n đ c t ạ ờ ị ộ ớ ứ ề ươ ứ ấ ẽ ướ ố ọ ừ trên xu ng d i, nh ng đi u này d gây nh m l n, b i đó không ph i là ố ướ ư ề ễ ầ ầ ở ả th t th c hi n ứ ự ự ệ ch ng ươ trình.
Vi c th c hi n (th c thi) luôn b t đ u t câu l nh th nh t c a ệ ự ệ ự ắ ầ ừ ệ ứ ấ ủ main, b t k nó n m đâu trong ch ng ấ ể ằ ươ trình ( ví d này thì tôi đã c ý đ t cu i cùng). Nh ng câu l nh đ c th c hi n l n l t, theo th t , ở ụ ố ặ ở ố ữ ệ ượ ự ệ ầ ượ ứ ự đ n khi b n g p m t l i g i (kích ho t) ph ng th c. Vi c kích ho t ph ng th c cũng gi ng nh l i r ế ạ ặ ộ ờ ọ ạ ươ ứ ệ ạ ươ ứ ố ư ố ẽ
kh i lu ng th c thi ch ng trình. Thay vì đi ti p đ n câu l nh li n k , b n chuy n đ n dòng l nh đ u ỏ ồ ự ươ ế ế ệ ề ề ạ ể ế ệ ầ tiên đ c kích ho t, th c hi n t t c nh ng câu l nh đó, r i quay l i và ti p t c t i đi m đã r ngang. ượ ạ ự ệ ấ ả ữ ệ ở ồ ạ ế ụ ạ ể ẽ Đi u này nghe th t đ n gi n, song b n v n c n nh r ng m t ph ng th c có th kích ho t ph ng ề ậ ơ ả ạ ẫ ầ ớ ằ ộ ươ ứ ể ạ ươ th c khác. B i v y, khi ta đang đo n gi a c a ứ ở ậ ở ạ ữ ủ main, ta có th bu c ph i d i đi đ th c hi n nh ng câu ể ộ ả ờ ể ự ệ ữ l nh trong ệ threeLine. Nh trong khi th c thi ư ự threeLine, có ba l n ta b gián đo n và ph i d i đi và th c ầ ị ạ ả ờ ự hi nệ newLine.
V ph n mình, ề ầ newLine kích ho t ạ println, và t o thêm m t l i r n a. Th t may là Java r t khéo theo ạ ộ ố ẽ ữ ậ ấ dõi v trí đang th c thi, nên khi ị ự println hoàn thành, công vi c l i đ c tr v đúng ch mà v a r i ệ ạ ượ ả ề ỗ ừ ờ kh i ỏ newLine, và sau đó thì tr l i ở ạ threeLine, r i sau cùng tr l i ồ ở ạ main đ ch ng trình có th k t thúc. ể ươ ể ế Xét v khía c nh kĩ thu t, ch ng trình ch a k t thúc sau ề ạ ậ ươ ư ế main. Thay vì v y, lu ng th c thi tìm đ n ch ậ ồ ự ế ỗ mà nó d i kh i ch ng trình đã kích ho t ờ ỏ ươ ạ main, t c là trình thông d ch Java. Trình thông d ch này đ m ứ ị ị ả nhi m các vi c nh xóa c a s và d n d p nói chung, r i ệ ệ ư ử ổ ọ ẹ ồ sau đó ch ng trình m i k t thúc. ươ ớ ế V y nghĩa lí c a toàn b nh ng th l ng nh ng này là gì? Khi đ c m t ch ng trình, b n đ ng đ c t ậ ủ ộ ữ ứ ằ ằ ọ ộ ươ ạ ừ ọ ừ trên xu ng d i, mà ph i đ c theo lu ng th c thi. ố ướ ả ọ ồ ự
3.8 Tham s và đ i s ố ố ố
Có nh ng ph ng th c ta đã dùng yêu c u ph i có ữ ươ ứ ầ ả đ i s ố ố, v n là nh ng giá tr mà b n c n cung c p đ ố ữ ị ạ ầ ấ ể có th kích ho t đ c chúng. Ch ng h n, đ tìm sin c a m t s , b n ph i cung c p s đó. Nh ể ạ ượ ẳ ạ ể ủ ộ ố ạ ả ấ ố ư v y, ậ sin đã nh n đ i s là m t ậ ố ố ộ double. Đ in ra m t chu i, b n ph i cung c p chu i đó, vì ể ộ ỗ ạ ả ấ ỗ v yậ println nh n đ i s là m t ậ ố ố ộ String.
L i có nh ng ph ng th c nh n nhi u đ i s ; ch ng h n, ạ ữ ươ ứ ậ ề ố ố ẳ ạ pow nh n hai ậ double, đó là c s và s mũ. ơ ố ố Khi b n dùng m t ph ng th c, b n ph i cung c p đ i s . Khi b n vi t m t ph ng th c, b n cung c p ạ ộ ươ ứ ạ ả ấ ố ố ạ ế ộ ươ ứ ạ ấ m t danh sách các tham s (hay tham bi n). M t ộ ố ế ộ tham số là m t bi n đ ch a m t đ i s . Danh sách ộ ế ể ứ ộ ố ố các tham bi n ch đ nh r ng c n ph i có nh ng đ i s nào. ế ỉ ị ằ ầ ả ữ ố ố
Ch ng h n, ẳ ạ printTwice ch đ nh m t tham s duy nh t, ỉ ị ộ ố ấ s, v n có ki u ố ể String. Tôi đ t tên nó là ặ s đ g i ể ợ
nh r ng đó là m t ớ ằ ộ String, song tôi cũng có th đ t b t kì tên bi n h p l nào cho nó. ể ặ ấ ế ợ ệ public static void printTwice(String s) {
System.out.println(s);
System.out.println(s);
}
Khi kích ho t ạ printTwice, ta ph i cung c p m t đ i s duy nh t có ki u ả ấ ộ ố ố ấ ể String.
printTwice("Don't make me say this twice!");
Khi b n kích ho t m t ph ng th c, đ i s mà b n cung c p đ c dùng đ gán cho các tham s . Trong ạ ạ ộ ươ ứ ố ố ạ ấ ượ ể ố tr ng h p này, đ i s ườ ợ ố ố "Don’t make me say this twice!" đ c gán cho tham s ượ ố s. Quá trình này đ c g i ượ ọ là truy n tham s ề ố vì giá tr đ c truy n t bên ngoài ph ng th c vào bên trong. ị ượ ề ừ ươ ứ M t đ i s có th là bi u th c b t kì, vì v y n u b n có m t bi n ộ ố ố ể ể ứ ấ ậ ế ạ ộ ế String thì có th dùng chính bi n này ể ế
làm đ i s : ố ố
String argument = "Never say never.";
printTwice(argument);
Giá tr mà b n cung c p làm đ i s s ph i có cùng ki u v i tham s . Ch ng h n, n u b n th dòng l nh ị ạ ấ ố ố ẽ ả ể ớ ố ẳ ạ ế ạ ử ệ sau:
printTwice(17);
B n s nh n đ c thông báo l i ki u nh “cannot find symbol” (không tìm th y kí hi u); thông báo này ạ ẽ ậ ượ ỗ ể ư ấ ệ không m y h u ích. Lí do là Java đang tìm m t ph ng th c có tên ấ ữ ộ ươ ứ printTwice mà có th nh n đ i s là ể ậ ố ố s nguyên. Vì ch ng có ph ng th c nào nh v y nên nó không th tìm th y “kí hi u” đó. ố ẳ ươ ứ ư ậ ể ấ ệ System.out.println ch p nh n đ c tham s thu c ki u d li u b t kì. Nh ng ph ng th c này ch là ấ ậ ượ ố ộ ể ữ ệ ấ ư ươ ứ ỉ
m t ngo i l ; đ i đa s các ph ng th c thì không d tính nh v y. ộ ạ ệ ạ ố ươ ứ ễ ư ậ
3.9 Bi u đ ngăn x p ể ồ ế
Các tham s và nh ng bi n khác ch t n t i trong ph ng th c riêng c a chúng. Trong ph m vi ố ữ ế ỉ ồ ạ ươ ứ ủ ạ c aủ main, không có cái gì g i là ọ s. N u b n th dùng bi n này, trình biên d ch s ph n đ i. T ng t , ế ạ ử ế ị ẽ ả ố ươ ự trong printTwice không có th gì g i là ứ ọ argument c . ả
M t cách theo dõi xem nh ng bi n nào đ c s d ng đâu là dùng m t ộ ữ ế ượ ử ụ ở ộ bi u đ ngăn x p ể ồ ế . V i ví d ớ ụ
trên, bi u đ ngăn x p s nh sau: ể ồ ế ẽ ư
M i ph ng th c đ u có m t h p màu xám g i là ỗ ươ ứ ề ộ ộ ọ khung., trong đó ch a các tham s và bi n c a ứ ố ế ủ ph ng th c. Tên c a ph ng th c đ c ghi bên ngoài khung. Nh th ng l , giá tr c a m i bi n l i ươ ứ ủ ươ ứ ượ ư ườ ệ ị ủ ỗ ế ạ
đ c vi t trong m t h p cùng v i tên bi n ghi bên c nh. ượ ế ộ ộ ớ ế ạ
3.10 Ph ng th c có nhi u tham s ươ ứ ề ố
Có m t lý do th ng gây ra l i khi l p trình: đó chính là cú pháp đ miêu t và kích ho t ph ng th c ộ ườ ỗ ậ ể ả ạ ươ ứ g m nhi u tham s . Tr c h t, hãy nh r ng b n ph i khai báo ki u c a t ng tham s . Ch ng h n ồ ề ố ướ ế ớ ằ ạ ả ể ủ ừ ố ẳ ạ
public static void printTime(int hour, int minute) {
System.out.print(hour);
System.out.print(":");
System.out.println(minute);
}
R t d b lôi cu n theo cách vi t ấ ễ ị ố ế int hour, minute, nh ng cách này ch đúng v i vi c khai báo bi n, ch ư ỉ ớ ệ ế ứ không ph i v i danh sách tham s . ả ớ ố
M t lý do khác gây nh m l n là b n không c n ph i khai báo ki u c a đ i s . Vi t nh d i đây là sai! ộ ầ ẫ ạ ầ ả ể ủ ố ố ế ư ướ int hour = 11;
int minute = 59;
printTime(int hour, int minute); // SAI!
Trong tr ng h p này, Java có th t bi t ki u c a ườ ợ ể ự ế ể ủ hour và minute khi nhìn vào đo n khai báo c a ạ ủ chúng. Ta không c n ph i kèm thêm ki u c a bi n khi truy n chúng làm đ i s . Cú pháp đúng ph i là ầ ả ể ủ ế ề ố ố ả
printTime(hour, minute).
3.11 Các ph ng th c tr l i k t qu ươ ứ ả ạ ế ả
M t s ph ng th c ta đang dùng, nh các ph ng th c c a l p ộ ố ươ ứ ư ươ ứ ủ ớ Math, đ u tr l i k t qu . Nh ng ề ả ạ ế ả ữ ph ng th c khác, nh ươ ứ ư println và newLine, đ u th c hi n m t thao tác nh ng không tr l i k t qu ề ự ệ ộ ư ả ạ ế ả nào. Đi u này n y sinh m t s câu h i sau: ề ả ộ ố ỏ
•Đi u gì s x y ra n u n u b n kích ho t m t ph ng th c mà không làm gì v i k t qu (nghĩa là b n ề ẽ ả ế ế ạ ạ ộ ươ ứ ớ ế ả ạ không gán nó vào m t bi n hay không dùng k t qu này làm b ph n trong m t bi u th c l n h n)? ộ ế ế ả ộ ậ ộ ể ứ ớ ơ •Đi u gì s x y ra n u b n dùng m t ph ng th c ề ẽ ả ế ạ ộ ươ ứ print nh m t ph n c a bi u th c l n h n, ch ng ư ộ ầ ủ ể ứ ớ ơ ẳ h n ạ System.out.println("boo!") + 7?
•Ta có th vi t nh ng ph ng th c đ tr l i giá tr không, hay ch loanh quanh v i nh ng ph ng th c ể ế ữ ươ ứ ể ả ạ ị ỉ ớ ữ ươ ứ ki u nh ể ư newLine và printTwice?
L i gi i đáp đ i v i câu h i th ba là “Có, b n có th vi t nh ng ph ng th c đ tr l i giá tr ,” mà ta s ờ ả ố ớ ỏ ứ ạ ể ế ữ ươ ứ ể ả ạ ị ẽ th y cách làm sau m t vài ch ng n a. Tôi s đ cho b n t tr l i hai câu h i còn l i b ng cách th c ấ ộ ươ ữ ẽ ể ạ ự ả ờ ỏ ạ ằ ự hành tr c ti p. Th t ra, b t kì lúc nào b n đ t ra câu h i v s h p l hay không h p l c a thao tác ự ế ậ ấ ạ ặ ỏ ề ự ợ ệ ợ ệ ủ trong Java, thì m t cách hay đ tìm hi u là đi h i trình biên d ch. ộ ể ể ỏ ị
3.12 Thu t ng ậ ữ
kh i t o: ở ạ
Câu l nh nh m khai báo m t bi n đ ng th i gán giá tr cho nó. ệ ằ ộ ế ồ ờ ị
d u ph y đ ng: ấ ẩ ộ
M t ki u c a bi n (ho c giá tr ) có th ch a c s có ph n th p phân l n s nguyên. Ki u d u ộ ể ủ ế ặ ị ể ứ ả ố ầ ậ ẫ ố ể ấ ph y đ ng mà ta s dùng là ẩ ộ ẽ double.
l p: ớ
M t t p h p đ c đ t tên, có ch a các ph ng th c. Đ n gi ta đã dùng l p ộ ậ ợ ượ ặ ứ ươ ứ ế ờ ớ Math và l pớ System, và cũng vi t đ c các l p có tên ế ượ ớ Hello và NewLine.
ph ng th c: ươ ứ
M t lo t nh ng câu l nh nh m th c hi n m t ch c năng có ích. Ph ng th c đ c đ t tên. Nó có th ộ ạ ữ ệ ằ ự ệ ộ ứ ươ ứ ượ ặ ể nh n ho c không nh n ậ ặ ậ tham s , đ ng th i có th tr l i ho c không tr m t giá tr . ố ồ ờ ể ả ạ ặ ả ộ ị tham s : ố
M t đ n v thông tin mà ph ng th c yêu c u tr c khi nó có th đ c th c hi n. Tham s là các bi n: ộ ơ ị ươ ứ ầ ướ ể ượ ự ệ ố ế
chúng ch a nh ng giá tr và có ki u riêng. ứ ữ ị ể
đ i s : ố ố
Giá tr mà b n cung c p khi b n kích ho t m t ph ng th c. Giá tr này ph i có cùng ki u v i tham s ị ạ ấ ạ ạ ộ ươ ứ ị ả ể ớ ố t ng ng. ươ ứ
khung:
M t c u trúc (bi u di n b i kh i ch nh t màu xám trong bi u đ ngăn x p) có ch a các tham s và ộ ấ ể ễ ở ố ữ ậ ể ồ ế ứ ố bi n c a m t ph ng th c. ế ủ ộ ươ ứ
kích ho t: ạ
Làm cho ph ng th c đ c th c thi. ươ ứ ượ ự
3.13 Bài t pậ
BÀI T P 1 Ậ
Hãy v m t khung ngăn x p đ bi u di n tr ng thái ch ng trình M c ẽ ộ ế ể ể ễ ạ ươ ở ụ 3.10 khi main kích ho t ạ printTime v i các đ i s ớ ố ố 11 và 59.
BÀI T P 2 Ậ
M c đích c a bài t p này là luy n đ c mã l nh đ đ m b o r ng b n hi u đ c lu ng th c thi c a ụ ủ ậ ệ ọ ệ ể ả ả ằ ạ ể ượ ồ ự ủ ch ng trình g m nhi u ph ng th c khác nhau. ươ ồ ề ươ ứ
1. K t qu c a ch ng trình sau là gì? Hãy nói chính xác v trí các d u tr ng và các ch xu ng dòng. G I ế ả ủ ươ ị ấ ố ỗ ố Ợ Ý: B t đ u b ng vi c di n t b ng l i xem ắ ầ ằ ệ ễ ả ằ ờ ping và baffle làm nh ng gì khi chúng đ c kích ho t. ữ ượ ạ 2. Hãy v m t bi u đ ngăn x p bi u di n tr ng thái c a ch ng trình khi ẽ ộ ể ồ ế ể ễ ạ ủ ươ ping đ c kích ho t l n đ u. ượ ạ ầ ầ public static void zoop() {
baffle();
System.out.print("You wugga ");
baffle();
}
public static void main(String[] args) {
System.out.print("No, I ");
zoop();
System.out.print("I ");
baffle();
}
public static void baffle() {
System.out.print("wug");
ping();
}
public static void ping() {
System.out.println(".");
}
BÀI T P 3 Ậ
M c đích c a bài t p này là đ m b o hi u đ c cách vi t và cách kích ho t ph ng th c nh n tham s . ụ ủ ậ ả ả ể ượ ế ạ ươ ứ ậ ố
1. Hãy vi t dòng đ u tiên c a m t ph ng th c có tên ế ầ ủ ộ ươ ứ zool nh n vào ba tham s : m t ậ ố ộ int và hai String. 2. Hãy vi t m t dòng l nh ế ộ ệ zool, truy n làm tham s các giá tr sau: ề ố ị 11, tên c a con thú c ng l n đ u b n ủ ư ầ ầ ạ nuôi, và tên c a dãy ph mà b n s ng th i th u. ủ ố ạ ố ờ ơ ấ
BÀI T P 4 Ậ
M c đích c a bài t p này là l y đo n mã t m t bài t p tr c r i bao gói nó vào trong m t ph ng th c ụ ủ ậ ấ ạ ừ ộ ậ ướ ồ ộ ươ ứ có nh n tham s . B n nên tìm m t l i gi i hoàn ch nh cho Bài t p ậ ố ạ ộ ờ ả ỉ ậ 2 đ b t đ u. ể ắ ầ
1. Hãy vi t m t ph ng th c có tên ế ộ ươ ứ printAmerican đ nh n ngày, tháng, năm làm các tham s r i in ể ậ ố ồ chúng ra d i d ng quy đ nh c a M . ướ ạ ị ủ ỹ
2. Ki m tra ph ng th c c a b n b ng cách kích ho t nó t ể ươ ứ ủ ạ ằ ạ ừ main r i truy n các đ i s phù h p. K t qu ồ ề ố ố ợ ế ả
ph i trông gi ng nh sau (ch tr s ngày có th khác đi): ả ố ư ỉ ừ ố ể
Saturday, July 16, 2011
3. M t khi b n đã g l i xong cho ộ ạ ỡ ỗ printAmerican, hãy vi t m t ph ng th c khác có tên ế ộ ươ ứ printEuropean để in ra ngày tháng theo quy chu n châu Âu. ẩ
Ch ng 4: Câu l nh đi u ki n và đ quy ươ ệ ề ệ ệ Java
Tr v ở ề M c l c ụ ụ cu n sách ố
4.1 Toán t chia d ử ư
Toán t chia d ử ư tính v i các s nguyên (cùng các bi u th c s nguyên) và cho k t qu là ớ ố ể ứ ố ế ả ph n d ầ ư c a ủ phép chia s th nh t cho s th hai. ố ứ ấ ố ứ Trong Java, toán t chia d có kí hi u là d u ph n trăm, ử ư ệ ấ ầ %. Cú
pháp cũng gi ng nh các toán t khác: ố ư ử
int quotient = 7 / 3;
int remainder = 7 % 3;
V i toán t th nh t, chia nguyên, k t qu là 2. V i toán t th hai ta đ c k t qu b ng 1. Nh v y 7 ớ ử ứ ấ ế ả ớ ử ứ ượ ế ả ằ ư ậ chia cho 3 b ng 2 d 1. ằ ư
Toán t s d b t ng tr nên có ích. Ch ng h n, b n có th ki m tra xem m t s có chia h t cho s ử ố ư ấ ờ ở ẳ ạ ạ ể ể ộ ố ế ố khác không: n uế x % y b ng không thì ằ x chia h t cho ế y.
H n n a, b n còn có th l c ra nh ng ch s cu i cùng bên ph i t s ban đ u. Ch ng h n, ơ ữ ạ ể ọ ữ ữ ố ố ả ừ ố ầ ẳ ạ x % 10 cho
ta s hàng đ n v c a ố ơ ị ủ x (trong h th p phân). T ng t , ệ ậ ươ ự x % 100 cho ta hai ch s hàng ch c và đ n v . ữ ố ụ ơ ị 4.2 Th c hi n l nh theo đi u ki n ự ệ ệ ề ệ
Đ vi t đ c nh ng ch ng trình h u ích, chúng ta th ng luôn ph i ki m tra nh ng đi u ki n và thay ể ế ượ ữ ươ ữ ườ ả ể ữ ề ệ đ i bi u hi n t ng ng c a ch ng trình. Các ổ ể ệ ươ ứ ủ ươ câu l nh đi u ki n ệ ề ệ cung c p cho ta kh năng này. ấ ả
D ng đ n gi n nh t là l nh ạ ơ ả ấ ệ if:
if (x > 0) {
System.out.println("x la so duong");
}
Bi u th c trong c p ngo c tròn ể ứ ở ặ ặ đ c g i là ượ ọ đi u ki n. N u nó đ c tho mãn thì đo n l nh bên trong ề ệ ế ượ ả ạ ệ c p ngo c nh n đ c th c thi. N u không, s ch ng có đi u gì x y ra. ặ ặ ọ ượ ự ế ẽ ẳ ề ả
Đi u ki n có th ch a b t kì toán t so sánh nào, v n đôi khi còn đ c g i là ề ệ ể ứ ấ ử ố ượ ọ toán t quan h ử ệ: x == y // x bằng y
x != y // x không bằng y
x > y // x is lớn hơn y
x < y // x nhỏ hơn y
x >= y // x lớn hơn hoặc bằng y
x <= y // x nhỏ hơn hoặc bằng y
M c dù có th b n đã quen thu c v i nh ng phép toán này, cú pháp dùng trong Java v n h i khác ặ ể ạ ộ ớ ữ ẫ ơ nh ng bi u th c nh =, ≠ và ≤. M t l i th ng m c ph i là dùng m t d u ữ ể ứ ư ộ ỗ ườ ắ ả ộ ấ = thay vì hai ==. Hãy nh ớ r ng ằ = là toán t gán, còn ử == là toán t so sánh. ử Ngoài ra không có toán t nào đ c vi t là ử ượ ế =< ho cặ =>. Hai v trong m t bi u th c đi u ki n ph i có cùng ki u d li u. B n ch đ c phép so ế ộ ể ứ ề ệ ả ể ữ ệ ạ ỉ ượ sánh int v i ớ ints ho cặ double v i ớ double.
Hai toán tử == và != cũng làm vi c v i các chu i kí t , nh ng cách ho t đ ng c a chúng không gi ng ệ ớ ỗ ự ư ạ ộ ủ ố nh b n đã d ki n. Còn t t c nh ng toán t quan h khác thì không có tác d ng gì đ i v i chu i. Ta s ư ạ ự ế ấ ả ữ ử ệ ụ ố ớ ỗ ẽ
xem cách so sánh chu i M c ỗ ở ụ 8.10.
4.3 Th c hi n ch n l a ự ệ ọ ự
D ng th hai c a th c hi n teho đi u ki n ạ ứ ủ ự ệ ề ệ là th c hi n l nh theo l a ch n, trong đó có hai kh năng và ự ệ ệ ự ọ ả đi u ki n đ c đ t ra đ căn c vào đó mà l a ch n th c hi n m t trong hai. Cú pháp có d ng nh sau: ề ệ ượ ặ ể ứ ự ọ ự ệ ộ ạ ư if (x%2 == 0) {
System.out.println("x la so chan");
} else {
System.out.println("x la so le");
}
N u ph n d c a phép chia ế ầ ư ủ x cho 2 là 0, thì chúng ta bi t r ng ế ằ x là s ch n, và ch ng trình s hi n th ố ẵ ươ ẽ ể ị thông báo đi u này. N u đi u ki n không đ c tho mã thì l nh th hai s đ c th c hi n. Vì đi u ki n ề ế ề ệ ượ ả ệ ứ ẽ ượ ự ệ ề ệ ho c là đ c tho mãn, ho c không; nên luôn ch có m t trong hai ph ng án đ c th c hi n. ặ ượ ả ặ ỉ ộ ươ ượ ự ệ
Nhân ti n nói thêm, n u b n có ý đ nh th ng xuyên ki m tra tính ch n l , có th b n s mu n ệ ế ạ ị ườ ể ẵ ẻ ể ạ ẽ ố “gói” đo n mã l nh này vào trong m t ph ng th c, nh sau: ạ ệ ộ ươ ứ ư
public static void printParity(int x) {
if (x%2 == 0) {
System.out.println("x la so chan");
} else {
System.out.println("x la so le");
}
}
Bây gi b n có m t ph ng th c tên là ờ ạ ộ ươ ứ printParity đ in ra thông báo thích h p cho m i s nguyên b n ể ợ ỗ ố ạ
cung c p cho nó. Trong ấ main b n s kích ho t ph ng th c này nh sau: ạ ẽ ạ ươ ứ ư
printParity(17);
Hãy luôn nh r ng khi b n ớ ằ ạ kích ho t ạ m t ph ng th c, thì không nh t thi t ph i khai báo các ki u c a ộ ươ ứ ấ ế ả ể ủ đ i s đ c cung ố ố ượ c p. Java có th hình dung ra ki u d li u là gì. B n ph i ki m ch đ tránh vi t ấ ể ể ữ ệ ạ ả ề ế ể ế
nh ng l nh ki u nh : ữ ệ ể ư
int number = 17;
printParity(int number); // SAI!!!
4.4 Các đi u ki n xâu chu i ề ệ ỗ
Đôi khi b n c n ph i ki m tra m t s các đi u ki n có liên quan và ch n trong m t s nh ng hành ạ ầ ả ể ộ ố ề ệ ọ ộ ố ữ
đ ng. ộ M t cách th c hi n vi c này là ộ ự ệ ệ xâu chu i ỗ m t lo t các ộ ạ if và else:
if (x > 0) {
System.out.println("x la so duong");
} else if (x < 0) {
System.out.println("x la so am");
} else {
System.out.println("x bang khong");
}
Vi c xâu chu i nh v y có th dài tùy ý, m c dù chúng có th khó đ c n u đi quá đà. M t cách làm đ ệ ỗ ư ậ ể ặ ể ọ ế ộ ể d đ c h n là s d ng quy t c th t đ u dòng tiêu chu n, nh đã trình bày trong các ví d trên. n u b n ễ ọ ơ ử ụ ắ ụ ầ ẩ ư ụ ế ạ gi cho các câu l nh và các ngo c nh n đ c th ng hàng v i nhua thì ít có kh năng gây l i cú pháp ữ ệ ặ ọ ượ ẳ ớ ả ỗ h n, và n u có thì cũng d tìm th y h n. ơ ế ễ ấ ơ
4.5 Các đi u ki n l ng ghép ề ệ ồ
Ngoài vi c xâu chu i, b n còn có th l ng ghép m t đi u ki n bên trong đi u ki n khác. Ta có th vi t ệ ỗ ạ ể ồ ộ ề ệ ề ệ ể ế l i ví d trên nh sau: ạ ụ ư
if (x == 0) {
System.out.println("x bang khong");
} else {
if (x > 0) {
System.out.println("x la so duong");
} else {
System.out.println("x la so am");
}
}
Bây gi thì câu l nh đi u ki n bên ngoài có hai nhánh. Nhánh th nh t ch ch a m t l nh ờ ệ ề ệ ứ ấ ỉ ứ ộ ệ print, nhánh th hai l i ch a m t câu l nh đi u ki n ứ ạ ứ ộ ệ ề ệ khác, mà b n thân nó l i có hai nhánh. Hai nhánh này đ u ch a ả ạ ề ứ nh ng câu l nh ữ ệ print đ n gi n, ơ ả m c dù dĩ nhiên chúng có th là nh ng câu l nh đi u ki n khác. ặ ể ữ ệ ề ệ Tuy cách vi t th t vào trong làm cho c u trúc rõ ý, nh ng ế ụ ấ ư các l nh đi u ki n l ng ghép ệ ề ệ ồ tr nên r t khó ở ấ đ ng i đ c nhanh. Ta nên c g ng tránh dùng chúng. ể ườ ọ ố ắ
M t khác, d ng ặ ạ c u trúc l ng ghép ấ ồ này cũng th ng th y, và sau này ta còn g p chúng, do v y b n ườ ấ ặ ậ ạ
cũng làm quen v i nó. ớ
4.6 Câu l nh return ệ
Câu l nh ệ return cho phép b n k t thúc vi c th c thi c a m t ph ng th c tr c khi đ n cu i ph ng ạ ế ệ ự ủ ộ ươ ứ ướ ế ố ươ
th c đó. M t lí do dùng câu l nh này là n u b n phát hi n ra đi u ki n gây l i: ứ ộ ệ ế ạ ệ ề ệ ỗ public static void printLogarithm(double x) {
if (x <= 0.0) {
System.out.println("Yêu cau nhap vao so duong.");
return;
}
double result = Math.log(x);
System.out.println("Gia tri log cua x bang " + result);
}
Mã l nh này đ nh nghĩa m t ph ng th c có tên ệ ị ộ ươ ứ printLogarithm; nó nh n tham s là m t ậ ố ộ double có tên x. Ph ng th c này ki m ươ ứ ể tra xem li uệ x có nh h n ho c b ng 0 hay không, và trong tr ng h p ỏ ơ ặ ằ ườ ợ
nh v y thì in ra m t thông báo l i r i dùng ư ậ ộ ỗ ồ return đ thoát kh i ph ng th c. Lu ng th c thi s l p ể ỏ ươ ứ ồ ự ẽ ậ t c tr l i ch g i ph ng th c đó và nh ng dòng còn l i c a ph ng th c s không đ c th c hi n. ứ ở ạ ỗ ọ ươ ứ ữ ạ ủ ươ ứ ẽ ượ ự ệ Tôi đã dùng m t giá tr d u ph y đ ng bên v ph i c a đi u ki n vì v trái bi u th c này là m t bi n ộ ị ấ ẩ ộ ở ế ả ủ ề ệ ế ể ứ ộ ế ph y đ ng. ẩ ộ
4.7 Chuy n đ i ki u ể ổ ể
B n có th t h i r ng làm sao ch ng trình c a ta có th êm xuôi v i bi u th c ki u nh ạ ể ự ỏ ằ ươ ủ ể ớ ể ứ ể ư "Gia tri log cua x bang " + result, b i m t toán h ng là ở ộ ạ String còn toán h ng kia là ạ double. Truong tr ng h p này ườ ợ Java đã thông minh đ thay ta chuy n giá tr ể ể ị double thành String tr c khi th c hi n vi c ghép chu i. ướ ự ệ ệ ỗ M i khi b n th “c ng” hai bi u th c, mà m t trong s đó là ỗ ạ ử ộ ể ứ ộ ố String, Java s chuy n đ i cái còn l i ẽ ể ổ ạ thành String r i m i th c hi n ghép chu i. B n nghĩ đi u gì s x y ra n u th c hi n phép c ng gi a m t ồ ớ ự ệ ỗ ạ ề ẽ ả ế ự ệ ộ ữ ộ
s nguyên v i m t giá tr ph y đ ng? ố ớ ộ ị ẩ ộ
4.8 Đ quy ệ
Ở ươ ướ ằ ệ ộ ươ ứ ạ ươ ứ ợ ệ ch ng tr c tôi đã nói r ng vi c m t ph ng th c kích ho t ph ng th c khác là h p l , và a đã xét vài ví d . Tôi ch a đ c p r ng m t ph ng th c kích ho t chính nó cũng h p l . M c dù b ngoài thì có ụ ư ề ậ ằ ộ ươ ứ ạ ợ ệ ặ ề th đi u này không rõ hay d ra sao, nh ng th c ra đó chính là m t trong nh ng đ c đi m hay nh t ể ề ở ư ự ộ ữ ặ ể ấ trong l p trình. ậ
Ch ng h n, hãy xét ph ng th c sau: ẳ ạ ươ ứ
public static void countdown(int n) {
if (n == 0) {
System.out.println("Bum!");
} else {
System.out.println(n);
countdown(n-1);
}
}
Ph ng th c có tên là ươ ứ countdown và nó nh n tham s là m t s nguyên. N u tham s ậ ố ộ ố ế ố b ng 0 ho c âm, ằ ặ ch ng trình s in ra ch , “Bùm!” Còn n u không, nó s in ra giá tr tham s ươ ẽ ữ ế ẽ ị ố và sau đó kích ho t m t ạ ộ ph ng th c có tên ươ ứ countdown—nghĩa là chính nó—nh ng truy n vào đ i s ư ề ố ố n-1.
Đi u gì s x y ra khi ta kích ho t m t ph ng th c ki u nh th này? ề ẽ ả ạ ộ ươ ứ ể ư ế
countdown(3);
Vi c th c hi n ệ ự ệ countdown b t đ u v i ắ ầ ớ n=3, và do n l n h n 0, nó đ a ra giá tr 3, và r i g i chính nó… ớ ơ ư ị ồ ọ Vi c th c hi n ệ ự ệ countdown b t đ u v i ắ ầ ớ n=2, và do n l n h n 0, nó đ a ra giá tr 2, và r i g i chính nó… ớ ơ ư ị ồ ọ Vi c th c hi n ệ ự ệ countdown b t đ u v i ắ ầ ớ n=1, và do n l n h n 0, nó đ a ra giá tr 1, và r i g i chính nó… ớ ơ ư ị ồ ọ Vi c th c hi n ệ ự ệ countdown b t đ u v i ắ ầ ớ n=0, và do n không còn l n h n 0, nó đ a ra dòng ch “Bùm!” và ớ ơ ư ữ
r i quay v . ồ ề
Ph ng th c ươ ứ countdown ứ ớ ng v i n=1 quay v . ề
Ph ng th c ươ ứ countdown ứ ớ ng v i n=2 quay v . ề
Ph ng th c ươ ứ countdown ứ ớ ng v i n=3 quay v . ề
Và r i b n tr v v i ồ ạ ở ề ớ main. Nh v y, toàn b k t qu đ u ra nh sau: ư ậ ộ ế ả ầ ư
3
2
1
Bum!
Ví d th hai là hãy xem l i các ph ng th c ụ ứ ạ ươ ứ newLine và threeLine.
public static void newLine() {
System.out.println("");
}
public static void threeLine() {
newLine(); newLine(); newLine();
}
M c dù cách này có tác d ng, nh ng s không giúp ích đ c nhi u trong tr ng h p ta c n in 2, ho c ặ ụ ư ẽ ượ ề ườ ợ ầ ặ 106 dòng m i. M t cách làm hay h n là ớ ộ ơ
public static void nLines(int n) {
if (n > 0) {
System.out.println("");
nLines(n-1);
}
}
Ch ng trình này t ng t nh ươ ươ ự ư countdown; khi n còn l n h n 0, nó s in ra m t dòng m i ớ ơ ẽ ộ ớ và sau đó s ẽ kích ho t chính nó đ in thêm ạ ể n - 1 dòng m i n a. Nh v y s dòng k t qu s là ớ ữ ư ậ ố ế ả ẽ 1 + (n-1), t c là ứ b ng ằ n.
Khi m t ph ng th c kích ho t chính nó, đi u này g i là ộ ươ ứ ạ ề ọ đ quy ệ , và nh ng ph ng th c đó có ữ ươ ứ tính đ ệ
quy.
4.9 Bi u đ ngăn x p cho các ph ng th c đ quy ể ồ ế ươ ứ ệ
Trong ch ng tr c, chúng ta đã dùng m t bi u đ ngăn x p đ bi u th tr ng thái c a m t ch ng ươ ướ ộ ể ồ ế ể ể ị ạ ủ ộ ươ trình trong quá trình ph ng th c đ c kích ho t. Lo i bi u đ này cũng ti n dùng cho vi c di n gi i ươ ứ ượ ạ ạ ể ồ ệ ệ ễ ả m t ph ng th c đ quy. ộ ươ ứ ệ
Hãy nh r ng m i khi ph ng th c đ c kích ho t, Java t o ra m t “khung” m i trong đó có ch a ơ ằ ỗ ươ ứ ượ ạ ạ ộ ớ ứ phiên b n m i c a các bi n c c b và tham s trong ph ng th c. ả ớ ủ ế ụ ộ ố ươ ứ
Hình v này minh ho m t s đ ngăn x p cho ph ng th c ẽ ạ ộ ơ ồ ế ươ ứ countdown khi g i v i ọ ớ n = 3:
Có m t khung dành cho ộ main và b n khung ố countdown, m i khung có m t giá tr riêng cho tham ỗ ộ ị bi nế n. Đáy c a ngăn x p, ủ ế countdown v i ớ n=0, đ c g i là ượ ọ tr ng h p c s ườ ợ ơ ở. Nó không th c hi n l i ự ệ ờ g i đ quy, do đó không có thêm khung ọ ệ countdown nào.
Khung ch aứ main thì r ng vì ỗ main không ch a b t kì tham s hay bi n nào. ứ ấ ố ế
4.10 Thu t ng ậ ữ
toán t module: ử
Toán t dùng v i hai s nguyên và tr l i ph n d trong phép chia gi a hai s đó. Trong Java, ử ớ ố ả ạ ầ ư ữ ố toán t này đ c kí hi u b i d u ph n trăm ( ử ượ ệ ở ấ ầ %).
l nh đi u ki n: ệ ề ệ
M t kh i l nh có th đ c th c thi hay không tùy theo m t đi u ki n nào đó. ộ ố ệ ể ượ ự ộ ề ệ
xâu chu i: ỗ
Cách n i nhi u l nh đi u ki n thành dãy liên t c. ố ề ệ ề ệ ụ
l ng ghép: ồ
Cách đ t m t l nh đi u ki n này vò trong m t ho c c hai nhánh c a m t l nh đi u ki n khác. ặ ộ ệ ề ệ ộ ặ ả ủ ộ ệ ề ệ đ nh ki u: ị ể
M t toán t giúp chuy n đ i t ki u d li u này sang ki u khác. Trong Java nó có d ng tên m t ộ ử ể ổ ừ ể ữ ệ ể ạ ộ ki u d li u vi t gi a c p ngo c tròn, nh ể ữ ệ ế ữ ặ ặ ư (int).
đ quy: ệ
Quá trình kích ho t chính ph ng th c đang đ c th c thi. ạ ươ ứ ượ ự
tr ng h p c s : ườ ợ ơ ở
M t đi u ki n đ cho ph ng th c đ quy ộ ề ệ ể ươ ứ ệ không kích ho t đ quy n a. ạ ệ ữ
4.11 Bài t pậ
Bài t p 1 ậ Hãy v m t bi u đ ngăn x p bi u di n tr ng thái ch ng trình M c ẽ ộ ể ồ ế ể ễ ạ ươ ở ụ 4.8 sau khi main kích ho t ạ nLines v i tham s ớ ố n=4, ngay tr c khi l n kích ho t cu i cùng c a ướ ầ ạ ố ủ nLines tr v . ả ề Bài t p 2 ậ Bài t p này ôn l i lu ng th c thi, b ng m t ch ng trình v i nhi u ph ng th c. Hãy đ c ậ ạ ồ ự ằ ộ ươ ớ ề ươ ứ ọ
mã l nh d i đây r i tr l i nh ng câu h i đi theo. ệ ướ ồ ả ờ ữ ỏ
public class Buzz {
public static void baffle(String blimp) {
System.out.println(blimp);
zippo("ping", -5);
}
public static void zippo(String quince, int flag) {
if (flag < 0) {
System.out.println(quince + " zoop");
} else {
System.out.println("ik");
baffle(quince);
System.out.println("boo-wa-ha-ha");
}
}
public static void main(String[] args) {
zippo("rattle", 13);
}
}
1. Hãy vi t s ế ố 1 k bên câu l nh đ u tiên đ c th c thi c a ch ng trình này. Hãy c n th n đ tách bi t ế ệ ầ ượ ự ủ ươ ẩ ậ ể ệ nh ng th thu c v câu l nh v i nh ng th khác. ữ ứ ộ ề ệ ớ ữ ứ
2. Vi t s ế ố 2 k b nh câu l nh th hai, và c nh v y đ n cu i ch ng trình. N u m t câu l nh đ c th c ế ệ ệ ứ ứ ư ậ ế ố ươ ế ộ ệ ượ ự hi n nhi u l n thì cu i cùng ta có th s th y k t qu in ra ch a nhi u con s ghi bên c nh nó. ệ ề ầ ố ể ẽ ấ ế ả ứ ề ố ạ 3. Giá tr c a tham s ị ủ ố blimp khi baffle b kích ho t là gì? ị ạ
4. K t qu c a ch ng trình này là gì? ế ả ủ ươ
Bài t p 3 ậ Câu đ u trong l i bài hát ầ ờ “99 Bottles of Beer” là:
99 bottles of beer on the wall, 99 bottles of beer, ya’ take one down, ya’ pass it around, 98 bottles of beer on the wall.
Nh ng câu ti p theo cũng nh v y ch khác là s chai bia c gi m d n đi m t, đ n câu cu i cùng: ữ ế ư ậ ỉ ố ứ ả ầ ộ ế ố
No bottles of beer on the wall, no bottles of beer, ya’ can’t take one down, ya’ can’t pass it around, ’cause there are no more bottles of beer on the wall!
Và sau đó thì cu i cùng bài hát cũng k t thúc. ố ế
Hãy vi t ch ng trình in ra toàn b l i bài hát “99 Bottles of Beer.” Ch ng trình này c n có m t ế ươ ộ ờ ươ ầ ộ ph ng th c đ quy đ gi i quy t ph n khó khăn, nh ng có th b n còn mu n vi t thêm nh ng ph ng ươ ứ ệ ể ả ế ầ ư ể ạ ố ế ữ ươ th c ph tr vi c phân chia nh ng tính năng c b n c a ch ng trình. ứ ụ ợ ệ ữ ơ ả ủ ươ
Trong quá trình phát tri n mã l nh, hãy th ch y v i m t s ít các câu hát, nh “3 Bottles of Beer.” ể ệ ử ạ ớ ộ ố ư M c đích c a bài t p này là ti p nh n bài toán r i chia nh nó thành nh ng bài toán con, và gi i bài ụ ủ ậ ế ậ ồ ỏ ữ ả
toán con b ng cách vi t nh ng ph ng th c đ n gi n. ằ ế ữ ươ ứ ơ ả
Bài t p 4 ậ K t qu c a ch ng trình sau đây là gì? ế ả ủ ươ
public class Narf {
public static void zoop(String fred, int bob) {
System.out.println(fred);
if (bob == 5) {
ping("not ");
} else {
System.out.println("!");
}
}
public static void main(String[] args) {
int bizz = 5;
int buzz = 2;
zoop("just for", bizz);
clink(2*buzz);
}
public static void clink(int fork) {
System.out.print("It's ");
zoop("breakfast ", fork) ;
}
public static void ping(String strangStrung) {
System.out.println("any " + strangStrung + "more ");
}
}
Bài t p 5 ậ Đ nh lý cu i cùng c a Fermat phát bi u r ng không có các s nguyên ị ố ủ ể ằ ố a, b, và c nào tho mãn ả an + bn = cn
tr tr ng h p ừ ườ ợ n = 2.Vi t m t ph ng th c có tên là ế ộ ươ ứ check_fermat nh n vào b n tham s — ậ ố ố a, b, c và n —r i ki m tra xem có tho mãn đ nh lý Fermat không. N u ồ ể ả ị ế n l n h n 2 và hoá ra ớ ơ an + bn = cn, thì ch ng trình s in ra “Tr i, Fermat đã l m!” Còn n u không thì ch ng trình s in ra, “Không, v n ươ ẽ ờ ầ ế ươ ẽ ẫ không đúng”.
B n c n ph i gi s r ng có m t ph ng th c tên là ạ ầ ả ả ử ằ ộ ươ ứ raiseToPow ; ph ng th c này nh n đ i s là hai s ươ ứ ậ ố ố ố
nguyên r i nâng đ i s th nh t lên lũy th a s th hai. Ch ng h n: ồ ố ố ứ ấ ừ ố ứ ẳ ạ
int x = raiseToPow(2, 3);
s gán giá tr ẽ ị 8 cho x, b i 2 ở 3 = 8.
Ch ng 5: Grid World, ph n ươ ầ 1
Tr v ở ề M c l c ụ ụ cu n sách ố
5.1 Kh i đ ng ở ộ
Bây gi đã đ n lúc ta b t đ u làm Nghiên c u c th v kì thi Khoa h c máy tính ờ ế ắ ầ ứ ụ ể ề ọ AP; nghiên c u này ứ xoay quanh m t ch ng trình có tên GridWorld. Đ u tiên, hãy cài đ t GridWorld; b n có th t i ch ng ộ ươ ầ ặ ạ ể ả ươ trình này v t H i đ ng tuy n sinh Hoa ề ừ ộ ồ ể
Kì: http://www.collegeboard.com/student/testing/ap/compsci_a/case.html.
Khi gi i nén mã ngu n này, b n s thu đ c m t th m c mang tên ả ồ ạ ẽ ượ ộ ư ụ GridWorldCode trong đó ch aứ projects/firstProject, và b n thân th m c này l i ch a ả ư ụ ạ ứ BugRunner.java.
Hãy sao chép t p tin ậ BugRunner.java vào m t th m c khác r i nh p nó t môi tr ng phát tri n mà ộ ư ụ ồ ậ ừ ườ ể b n đang dùng. B n có th tham kh o h ng ạ ạ ể ả ướ
d n: ẫ http://www.collegeboard.com/prod_downloads/student/testing/ap/compsci_a/ap07_gridworld _installation_guide.pdf.
M t khi ch y ộ ạ BugRunner.java, b n hãy t i B n h ng d n th c hành GridWorld ạ ả ả ướ ẫ ự từ http://www.collegeboard.com/prod_downloads/student/testing/ap/compsci_a/ap07_gridworld_st udmanual_appends_v3.pdf.
B n h ng d n th c hành này có dùng nh ng thu t ng mà tôi ch a trình bày. B i v y đ b n quen ả ướ ẫ ự ữ ậ ữ ư ở ậ ể ạ đ c, sau đây là m t danh sách gi i thi u tóm t t: ượ ộ ớ ệ ắ
• Các thành ph n c a GridWorld, bao g m Bugs, Rocks và b n thân Grid đ u là nh ng ầ ủ ồ ả ề ữ đ i t ng ố ượ . • Constructor là m t ph ng th c đ c bi t đ t o nên nh ng đ i t ng m i. ộ ươ ứ ặ ệ ể ạ ữ ố ượ ớ
• L pớ là m t t p h p các đ i t ng; m i đ i t ng đ u thu c m t l p nh t đ nh. ộ ậ ợ ố ượ ỗ ố ượ ề ộ ộ ớ ấ ị • Đ i t ng còn đ c g i là ố ượ ượ ọ th c th ự ể, vì nó thu c v m t l p. ộ ề ộ ớ
• Thu c tính ộ là m t đ n v thông tin v m t đ i t ng, ch ng h n màu s c hay t a đ (v trí) c a đ i ộ ơ ị ề ộ ố ượ ẳ ạ ắ ọ ộ ị ủ ố t ng đó. ượ
• Ph ng th c truy c p ươ ứ ậ là m t ph ng th c nh m tr l i thu c tính c a m t đ i t ng. ộ ươ ứ ằ ả ạ ộ ủ ộ ố ượ • Ph ng th c s a đ i ươ ứ ử ổ nh m thay đ i thu c tính c a m t đ i t ng. ằ ổ ộ ủ ộ ố ượ
Bây gi b n đã có th đ c đ c Ph n 1 c a cu n H ng d n th c hành và làm các bài t p. ờ ạ ể ọ ượ ầ ủ ố ướ ẫ ự ậ 5.2 BugRunner
BugRunner.java ch a mã l nh sau: ứ ệ
import info.gridworld.actor.ActorWorld;
import info.gridworld.actor.Bug;
import info.gridworld.actor.Rock;
public class BugRunner {
public static void main(String[] args) {
ActorWorld world = new ActorWorld();
world.add(new Bug());
world.add(new Rock());
world.show();
}
}
Ba dòng đ u tiên là các câu l nh ầ ệ import; chúng li t kê các l p trong GridWorld đ c dùng đ n ệ ớ ượ ế ở ch ng trình này. B n có th tìm tài li u cho nh ng l p này ươ ạ ể ệ ữ ớ
t i ạ http://www.greenteapress.com/thinkapjava/javadoc/gridworld/.
Cũng nh nh ng ch ng trình khác ta đã g p, BugRunner đ nh nghĩa l p có nhi m v cung c p ph ng ư ữ ươ ặ ị ớ ệ ụ ấ ươ th cứ main. Dòng đ u tiên trong ầ main t o ra m t đ i t ng ạ ộ ố ượ ActorWorld. đây, Ở new là t khóa Java đ ừ ể t o nên đ i t ng m i. ạ ố ượ ớ
Hai dòng k t ti p t o ra m t Bug (con b ) và m t Rock (t ng đá), r i b sung chúng vào ế ế ạ ộ ọ ộ ả ồ ổ world (môi tr ng). Dòng cu i cùng hi n th môi tr ng lên màn hình. ườ ố ể ị ườ
Hãy m t p tin ở ậ BugRunner.java đ ch nh s a và thay dòng này: ể ỉ ử
world.add(new Bug());
b ng các dòng này: ằ
Bug redBug = new Bug();
world.add(redBug);
Dòng đ u tiên gán Bug cho m t bi n có tên ầ ộ ế redBug; ta có th dùng ể redBug đ kích ho t nh ng ph ng ể ạ ữ ươ
th c c a Bug. hãy th l nh này: ứ ủ ử ệ
System.out.println(redBug.getLocation());
Chú ý: N u b n ch y l nh này tr c khi b sung Bug vào ế ạ ạ ệ ướ ổ world, thì k t qu s là ế ả ẽ null, b i đ i t ng Bug ở ố ượ này ch a có m t v trí c th . ư ộ ị ụ ể
Hãy kích ho t nh ng ph ng th c truy c p khác r i in ra các thu c tính c a con b v a t o ra. Kích ạ ữ ươ ứ ậ ồ ộ ủ ọ ừ ạ ho t các ph ng th c ạ ươ ứ canMove, move và turn đ ng th i đ m b o r ng b n n m đ c tác d ng c a ồ ờ ả ả ằ ạ ắ ượ ụ ủ
chúng.
5.3 Bài t pậ
Bài t p 1 ậ
1. Hãy vi t m t ph ng th c có tên ế ộ ươ ứ moveBug đ nh n vào tham s là con b r i kích ho t ể ậ ố ọ ồ ạ move. Ki m tra ể ph ng th c v a vi t ra b ng cách g i nó t ươ ứ ừ ế ằ ọ ừ main.
2. S a ch a ử ữ moveBug đ nó kích ho t ể ạ canMove r i di chuy n con b ch khi nó chuy n đ ng đ c. ồ ể ọ ỉ ể ộ ượ 3. S a ch a ử ữ moveBug đ nó nh n m t tham s là s nguyên ể ậ ộ ố ố n, r i di chuy n con b ồ ể ọ n l n (n u có th ). ầ ế ể 4. S a ch a ử ữ moveBug sao cho n u con b không chuy n đ ng đ c thì ph ng th c này s kích ho t ế ọ ể ộ ượ ươ ứ ẽ ạ turn. Bài t p 2 ậ
1. L pớ Math cung c p m t ph ng th c mang tên ấ ộ ươ ứ random đ tr l i m t s ph y đ ng gi a 0.0 và 1.0 ể ả ạ ộ ố ẩ ộ ữ (không bao g m 1.0). ồ
2. Hãy vi t m t ph ng th c mang tên ế ộ ươ ứ randomBug đ nh n tham s là m t Bug r i đ t h ng c a con b ể ậ ố ộ ồ ặ ướ ủ ọ này là m t trong nh ng giá tr 0, 90, 180 ho c 270 theo xác su t b ng nhau, r i cho con b chuy n đ ng ộ ữ ị ặ ấ ằ ồ ọ ể ộ n u nó có th . ế ể
3. S a ch a ử ữ randomBug đ nh n vào s nguyên ể ậ ố n r i th c hi n l p l i ồ ự ệ ặ ạ n l n thao tác trên.K t qu s là ầ ế ả ẽ m t quá trình “b c ng u nhiên”, mà b n có th xem thêm ộ ướ ẫ ạ ể
ở http://en.wikipedia.org/wiki/Random_walk.
4. Đ quan sát quá trình b c ng u nhiên dài h n, b n có th cho ActorWorld m t không gian r ng h n. ể ướ ẫ ơ ạ ể ộ ộ ơ
Ở ầ trên đ u file BugRunner.java, hãy b sung câu l nh ổ ệ import sau:
import info.gridworld.grid.UnboundedGrid;
Bây gi , hãy thay dòng l nh t o nên ActorWorld v i dòng l nh sau: ờ ệ ạ ớ ệ
ActorWorld world = new ActorWorld(new UnboundedGrid());
B n có th trình di n b c ng u nhiên v i vài nghìn b c di chuy n (có th ph i kéo thanh tr t đ tìm ạ ể ễ ướ ẫ ớ ướ ể ể ả ượ ể con b ). ọ
Bài t p 3 ậ GridWorld dùng các đ i t ng Color, v n đ c đ nh nghĩa trong m t th vi n Java. B n có ố ượ ố ượ ị ộ ư ệ ạ th đ c tài li u ể ọ ệ ở http://download.oracle.com/javase/6/docs/api/java/awt/Color.html.Đ t o nên ể ạ
nhi u con b v i các màu s c khác nhau, b n ph i nh p ề ọ ớ ắ ạ ả ậ Color:
import java.awt.Color;
Khi đó b n s truy c p đ c các màu đã đ nh s n, nh ạ ẽ ậ ượ ị ẵ ư Color.blue, hay m t màu m i nh sau: ộ ớ ư Color purple = new Color(148, 0, 211);
Hãy t o ra m t vài con b v i màu s c khác nhau. Ti p theo, hãy vi t m t ph ng th c có ạ ộ ọ ớ ắ ế ế ộ ươ ứ tên colorBug đ nh n tham s là m t con b , đ c vào t a đ c a nó, r i đ t màu. ể ậ ố ộ ọ ọ ọ ộ ủ ồ ặ Đ i t ng Location mà b n đã l y t ố ượ ạ ấ ừ getLocation có ch a nh ng ph ng th c mang ứ ữ ươ ứ
tên getRow và getCol v n tr l i nh ng s nguyên. VÌ v y b n có th l y t a đ x c a con b nh sau: ố ả ạ ữ ố ậ ạ ể ấ ọ ộ ủ ọ ư int x = bug.getLocation().getCol();
Hãy vi t m t ph ng th c có tên ế ộ ươ ứ makeBugs đ nh n vào m t ActorWorld và m t s nguyên ể ậ ộ ộ ố n r i t o ồ ạ nên n con b có màu s c tùy thu c theo t a đ c a chúng. Hãy dùng s th t dòng đ đi u khi n m c ọ ắ ộ ọ ộ ủ ố ứ ự ể ề ể ứ s c đ và th t c t đ đi u khi n m c s c lam. ắ ỏ ứ ự ộ ể ề ể ứ ắ
Ch ng 6: Ph ng th c tr l i giá ươ ươ ứ ả ạ trị
Tr v ở ề M c l c ụ ụ cu n sách ố
6.1 Nh ng giá tr đ c tr l i ữ ị ượ ả ạ
M t s ph ng th c mà ta đã dùng, nh các hàm toán h c, có tr l i k t qu . Nghĩa là, hi u ng t vi c ộ ố ươ ứ ư ọ ả ạ ế ả ệ ứ ừ ệ kích ho t ph ng th c là t o ra m t giá tr m i mà ta th ng gán nó cho m t bi n ho c dùng nh m t ạ ươ ứ ạ ộ ị ớ ườ ộ ế ặ ư ộ ph n h p nên m t bi u th c l n h n. Ch ng h n: ầ ợ ộ ể ứ ớ ơ ẳ ạ
double e = Math.exp(1.0);
double height = radius * Math.sin(angle);
Nh ng cho đ n gi t t c nh ng ph ng th c mà t tay vi t đ u là ph ng th c ư ế ờ ấ ả ữ ươ ứ ự ế ề ươ ứ r ng ỗ ; theo nghĩa nh ng ph ng th c này không tr l i giá tr nào. Khi b n kích ho t m t ph ng th c r ng, nó th ng ữ ươ ứ ả ạ ị ạ ạ ộ ươ ứ ố ườ ch t đ c đ t trên m t dòng mà không có l nh gán nào c : ỉ ự ượ ặ ộ ệ ả
countdown(3);
nLines(3);
Trong ch ng này ta vi t nh ng ph ng th c tr l i thông tin, mà tôi g i là ph ng th c ươ ế ữ ươ ứ ả ạ ọ ươ ứ tr l i ả ạ giá trị. Ví d đ u tiên là ụ ầ area, m t ph ng th c nh n vào tham s là m t ộ ươ ứ ậ ố ộ double, r i tr l i ồ ả ạ di n tích c a m t ệ ủ ộ
hình tròn v i bán kính cho tr c: ớ ướ
public static double area(double radius) {
double area = Math.PI * radius * radius;
return area;
}
Đi u đ u tiên mà ta nh n th y là đo n đ u c a đ nh nghĩa ph ng th c đã khác đi. Thay vì ề ầ ậ ấ ạ ầ ủ ị ươ ứ public static void, v n đ ch m t ph ng th c r ng, ta th y ố ể ỉ ộ ươ ứ ỗ ấ public static double, có nghĩa là giá tr tr v t ph ng ị ả ề ừ ươ th c này là m t ứ ộ double. Tôi v n ch a gi i thích ý nghĩa c a ẫ ư ả ủ public static, song b n hãy kiên nh n. ạ ẫ Dòng cu i là m t d ng m i c a câu l nh ố ộ ạ ớ ủ ệ return trong đó bao g m m t giá tr tr l i. Câu l nh này có ồ ộ ị ả ạ ệ nghĩa là “t ph ng th c này hãy l p t c tr v và dùng bi u th c kèm theo đây làm giá tr tr l i.” Bi u ừ ươ ứ ậ ứ ở ề ể ứ ị ả ạ ể
th c mà b n đ t ra có th ph c t p tùy ý, vì v y ta có th vi t ph ng th c sau m t cách g n h n: ứ ạ ặ ể ứ ạ ậ ể ế ươ ứ ộ ọ ơ public static double area(double radius) {
return Math.PI * radius * radius;
}
M t khác, nh ng ặ ữ bi n t m th i ế ạ ờ như area th ng giúp cho vi c g l i đ c d dàng h n. ườ ệ ỡ ỗ ượ ễ ơ Trong c i hai ả tr ng h p, ki u c a bi u th c trong l nh ườ ợ ể ủ ể ứ ệ return ph i kh p v i ki u c a ph ng th c. Nói cách khác, ả ớ ớ ể ủ ươ ứ khi b n khai báo r ng ki u tr l i là ạ ằ ể ả ạ double, b n đã cam k t r ng ph ng th c này cu i cùng s t o ra ạ ế ằ ươ ứ ố ẽ ạ m t ộ double. N u b n th ế ạ ử return mà không kèm theo bi u th c nào, ho c kèm theo bi u th c nh ng sai ể ứ ặ ể ứ ư ki u, thì trình biên d ch s r y la b n. ể ị ẽ ầ ạ
Đôi khi c n ph i có nhi u l nh return, m i l nh đ t m t nhánh c a l nh đi u ki n: ầ ả ề ệ ỗ ệ ặ ở ộ ủ ệ ề ệ public static double absoluteValue(double x) {
if (x < 0) {
return -x;
} else {
return x;
}
}
Vì nh ng l nh return này c u trúc đi u ki n l a ch n, cho nên ch có m t l nh đ c th c thi. Dù r ng ữ ệ ở ấ ề ệ ự ọ ỉ ộ ệ ượ ự ằ hoàn toàn h p l n u b n có nhi u l nh return trong cùng m t ph ng th c, song b n c n ghi nh r ng ợ ệ ế ạ ề ệ ộ ươ ứ ạ ầ ớ ằ ngay khi m t l nh return đ c th c hi n, ph ng th c s k t thúc mà không th c hi n b t c l nh nào ộ ệ ượ ự ệ ươ ứ ẽ ế ự ệ ấ ứ ệ ti p sau nó. ế
Mã l nh xu t hi n sau dòng l nh ệ ấ ệ ệ return, hay nói chung, trong b t c ch nào khác c a ch ng trình ấ ứ ỗ ủ ươ mà không n m trong lu ng th c hi n thì đ c g i là ằ ồ ự ệ ượ ọ mã l nh ch t ệ ế . M t s trình biên d ch s c nh báo ộ ố ị ẽ ả n u có đo n l nh ch t trong mã l nh b n vi t nên. ế ạ ệ ế ệ ạ ế
N u b n đ t l nh return trong c u trúc đi u ki n, thì ph i đ m b o đ c r ng ế ạ ặ ệ ấ ề ệ ả ả ả ượ ằ m i lu ng th c hi n kh ỗ ồ ự ệ ả
dĩ đ u d n t i m t l nh ề ẫ ớ ộ ệ return. Ch ng h n: ẳ ạ
public static double absoluteValue(double x) {
if (x < 0) {
return -x;
} else if (x > 0) {
return x;
} // SAI!!
}
Ch ng trình này không h p l vì n u ươ ợ ệ ế x b ng 0, thì c hai đi u ki n không có đi u ki n nào đ c tho ằ ả ề ệ ề ệ ượ ả mãn, và hàm s k t thúc mà không g p ph i l nh ẽ ế ặ ả ệ return nào. Trình biên d ch th ng s đ a ra thông ị ườ ẽ ư báo ki u nh ể ư “return statement required in absoluteValue” (yêu c u ph i có l nh return trong ầ ả ệ absoluteValue); l i thông báo này d gây nh m l n vì trong đó b n đã vi t hai l nh return r i. ờ ễ ầ ẫ ạ ế ệ ồ 6.2 Phát tri n ch ng trình ể ươ
Lúc này b n đã có th nhìn vào toàn b ph ng th c Java r i cho bi t chúng có nhi m v gì. Nh ng ạ ể ộ ươ ứ ồ ế ệ ụ ư ch a ch c b n đã bi t cách vi t nên chúng. Tôi s đ xu t m t ph ng pháp ư ắ ạ ế ế ẽ ề ấ ộ ươ g i là ọ phát tri n tăng ể d nầ .
Ở ụ ả ụ ạ ầ ả ữ ể ở ạ ộ ví d này, gi d b n c n tìm kho ng cách gi a hai đi m cho b i các to đ (x1, y1) và (x2, y2). Theo
đ nh nghĩa thông th ng, kho ng cách (distance) s là: ị ườ ả ẽ
√
distance =
———————————— (x2 − x1)2 +(y2 − y1)2
B c đ u tiên là cân nh c xem m t hàm ướ ầ ắ ộ distance trong Java s trông nh th nào. Nói cách khác, các ẽ ư ế s li u đ u vào (tham s ) và k t qu (giá tr tr l i) là gì? ố ệ ầ ố ế ả ị ả ạ
Trong tr ng h p này, s li u đ u vào mô t hai đi m; ta có th bi u th chúng b ng b n s ườ ợ ố ệ ầ ả ể ể ể ị ằ ố ố double, dù r ng sau này ta s th y Java có ki u đ i t ng ằ ẽ ấ ể ố ượ Point mà ta có th t n d ng. ể ậ ụ Giá tr c n tr v là kho ng ị ầ ả ề ả cách, t c là s thu c ki u ứ ẽ ộ ể double.
Ta đã có th phác th o ngay ra hàm nh sau: ể ả ư
public static double distance (double x1, double y1, double x2, double y2) { return 0.0;
}
Câu l nh ệ return 0.0; đóng vai trò gi ch c n thi t cho vi c biên d ch ch ng trình. Đ ng nhiên, vào ữ ỗ ầ ế ệ ị ươ ươ lúc này nó ch a phát huy tác d ng, song v n đáng đ ta th biên d ch nh m phát hi n ra l i cú pháp, ư ụ ẫ ể ử ị ằ ệ ỗ
n u có, tr c khi vi t thêm mã l nh. ế ướ ế ệ
Đ ki m tra ph ng th c m i vi t này, ta ph i kích ho t nó b ng các giá tr m u. Đâu đó trong ể ể ươ ứ ớ ế ả ạ ằ ị ẫ ở main, tôi s ph i vi t l nh: ẽ ả ế ệ
double dist = distance(1.0, 2.0, 4.0, 6.0);
S dĩ tôi ch n các tham s này vì kho ng cách ngang s là 3 và kho ng cách d c là 4, theo đó thì k t qu ở ọ ố ả ẽ ả ọ ế ả s b ng 5 (c nh huy n c a m t tam giác có các c nh là 3-4-5). Khi th nghi m m t hàm, b n nên bi t ẽ ằ ạ ề ủ ộ ạ ử ệ ộ ạ ế tr c k t qu đúng. ướ ế ả
M t khi đã ki m tra xong cú pháp c a l i đ nh nghĩa hàm, ta có th b t tay vào thêm mã l nh vào ph n ộ ể ủ ờ ị ể ắ ệ ầ thân. Sau m i l n thay đ i tăng d n, ta biên d ch l i và ch y ch ng trình. N u có l i b t kì b c thay ỗ ầ ổ ầ ị ạ ạ ươ ế ỗ ở ấ ướ đ i nào, ta s bi t ngay r ng ph i nhìn vào đâu: chính là vào dòng l nh mà ta v a m i b sung. ổ ẽ ế ằ ả ệ ừ ớ ổ
M t b c làm h p lí ti p theo là tính các hi u s ộ ướ ợ ế ệ ố x2 − x1 và y2 − y1. Tôi l u tr các giá tr trên vào nh ng ư ữ ị ữ bi n t m th i có tên ế ạ ờ dx và dy.
public static double distance (double x1, double y1, double x2, double y2) { double dx = x2 - x1;
double dy = y2 - y1;
System.out.println("dx is " + dx);
System.out.println("dy is " + dy);
return 0.0;
}
Tôi đã b sung hai l nh in vào sau đó đ ta ki m tra đ c nh ng giá tr trung gian tr c khi ti p t c. ổ ệ ể ể ượ ữ ị ướ ế ụ Nh ng giá tr này ph i b ng 3.0 và 4.0. ữ ị ả ằ
M t khi đã vi t xong ph ng th c r i thì ta c n ph i b nh ng l nh in này đi. ộ ế ươ ứ ồ ầ ả ỏ ữ ệ Các câu l nh nh v y còn ệ ư ậ có tên là dàn giáo vì nó có ích cho vi c xây d ng ch ng trình nh ng l i không ph i là m t ph n trong ệ ự ươ ư ạ ả ộ ầ s n ph m cu i cùng. ả ẩ ố
Ti p theo chúng ta tính các bình ph ng c a ế ươ ủ dx và dy. Ta đã có th dùng ph ng th c ể ươ ứ Math.pow, nh ng ư
đem nhân t ng s v i chính nó s đ n gi n h n. ừ ố ớ ẽ ơ ả ơ
public static double distance (double x1, double y1, double x2, double y2) { double dx = x2 - x1;
double dy = y2 - y1;
double dsquared = dx*dx + dy*dy;
System.out.println("dsquared is " + dsquared);
return 0.0;
}
M t l n n a, tôi biên d ch r i ch y ch ng trình giai đo n này và ki m tra giá tr trung gian (v n ph i ộ ầ ữ ị ồ ạ ươ ở ạ ể ị ố ả b ng 25.0). ằ
Sau cùng, ta có th dùng ể Math.sqrt đ tính r i tr l i k t qu . ể ồ ả ạ ế ả
public static double distance (double x1, double y1, double x2, double y2) { double dx = x2 - x1;
double dy = y2 - y1;
double dsquared = dx*dx + dy*dy;
double result = Math.sqrt(dsquared);
return result;
}
Từ main, ta có th in và ki m tra giá tr c a k t qu . ể ể ị ủ ế ả
Sau này khi đã có kinh nghi m, b n s vi t và g l i nhi u dòng l nh cùng lúc. Song dù sao đi n a, vi c ệ ạ ẽ ế ỡ ỗ ề ệ ữ ệ phát tri n tăng d n s giúp b n ti t ki m nhi u th i gian. ể ầ ẽ ạ ế ệ ề ờ Các đi m c b n c a quy trình này là: ể ơ ả ủ
• B t đ u v i m t ch ng trình ch y đ c và thêm vào nh ng thay đ i nh . B t c lúc nào khi g p l i, ắ ầ ớ ộ ươ ạ ượ ữ ổ ỏ ấ ứ ặ ỗ b n s phát hi n đ c ngay l i đó đâu. ạ ẽ ệ ượ ỗ ở
• Dùng các bi n t m đ l u gi các giá tr trung gian, t đó b n có th hi n th và ki m tra chúng. ế ạ ể ư ữ ị ừ ạ ể ể ị ể • M t khi ch ng trình đã ho t đ ng, b n có th d b các đo n mã “dàn giáo”, ho c rút g n nhi u câu ộ ươ ạ ộ ạ ể ỡ ỏ ạ ặ ọ ề
l nh v m t bi u th c ph c h p, n u vi c này không làm cho ch ng trình tr nên khó đ c h n. ệ ề ộ ể ứ ứ ợ ế ệ ươ ở ọ ơ 6.3 K t h p ph ng th c ế ợ ươ ứ
M t khi đã đ nh nghĩa m t ph ng th c m i, b n có th dùng nó nh m t ph n c a bi u th c l n, và ộ ị ộ ươ ứ ớ ạ ể ư ộ ầ ủ ể ứ ớ b n cũng có th thi t l p nh ng ph ng th c m i t các ph ng th c s n có. Ch ng h n, n u ai đó cho ạ ể ế ậ ữ ươ ứ ớ ừ ươ ứ ẵ ẳ ạ ế b n hai đi m: m t là tâm đ ng tròn và m t đi m trên đ ng tròn đó, r i yêu c u b n tính di n tích ạ ể ộ ườ ộ ể ườ ồ ầ ạ ệ hình tròn thì b n s làm th nào? ạ ẽ ế
Gi s nh to đ c a tâm đi m đ c l u trong các bi n ả ử ư ạ ộ ủ ể ượ ư ế xc và yc, to đ đi m trên đ ng tròn ạ ộ ể ườ là xp và yp. B c đ u tiên s là tìm bán kính c a đ ng tròn, v n là kho ng cách gi a hai đi m đó. Th t ướ ầ ẽ ủ ườ ố ả ữ ể ậ
may là ta đã có m t ph ng th c, ộ ươ ứ distance, đ làm vi c này: ể ệ
double radius = distance(xc, yc, xp, yp);
B c ti p theo là tìm di n tích c a m t đ ng tròn có bán kính đó, r i tr l i k t qu . ướ ế ệ ủ ộ ườ ồ ả ạ ế ả double area = area(radius); return area;
K t h p hai b c này vào trong cùng m t ph ng th c, ta thu đ c: ế ợ ướ ộ ươ ứ ượ
public static double circleArea (double xc, double yc, double xp, double yp) { double radius = distance(xc, yc, xp, yp);
double area = area(radius);
return area;
}
Các bi n t m th i ế ạ ờ radius và area có ích cho vi c phát tri n và g l i ch ng trình, nh ng m t khi ệ ể ỡ ỗ ươ ư ộ ch ng trình đã ho t đ ng t t, ta có th rút g n nó l i b ng cách k t h p các l nh kích ho t ph ng ươ ạ ộ ố ể ọ ạ ằ ế ợ ệ ạ ươ
th c: ứ
public static double circleArea (double xc, double yc, double xp, double yp) { return area(distance(xc, yc, xp, yp));
}
6.4 Quá t i toán t ả ử
Có th b n đã nh n th y r ng c ể ạ ậ ấ ằ ả circleArea l nẫ area đ u th c hi n nh ng tính năng t ng t —tìm di n ề ự ệ ữ ươ ự ệ tích hình tròn—nh ng nh n các tham s khác nhau. V i ư ậ ố ớ area, chúng ta ph i cung c p bán kính; còn ả ấ v i ớ circleArea ta cung c p hai đi m. ấ ể
N u hai ph ng th c cùng làm m t vi c, l t nhiên là ta đ t chung m t tên cho c hai. Vi c có nhi u ế ươ ứ ộ ệ ẽ ự ặ ộ ả ệ ề ph ng th c cùng tên, v n đ c g i là ươ ứ ố ượ ọ quá t i ả (overloading), là đi u h p l trong Java ề ợ ệ mi n sao các ễ
d ng ph ng th c ph i nh n nh ng tham s khác nhau ạ ươ ứ ả ậ ữ ố . Nh v y ta có th đ i tên ư ậ ể ổ circleArea: public static double area (double x1, double y1, double x2, double y2) {
return area(distance(xc, yc, xp, yp));
}
Khi b n kích ho t m t ph ng th c quá t i, Java s bi t đ c r ng b n mu n dùng d ng ph ng th c ạ ạ ộ ươ ứ ả ẽ ế ượ ằ ạ ố ạ ươ ứ nào, qua vi c xem xét các đ i s mà b n cung c p. N u b n vi t: ệ ố ố ạ ấ ế ạ ế
double x = area(3.0);
thì Java s đi tìm m t ph ng th c mang tên ẽ ộ ươ ứ area mà nh n đ i s là m t ậ ố ố ộ double; do đó nó s dùng ẽ
d ng th nh t, t c là hi u đ i s nh m t bán kính. Còn n u b n vi t: ạ ứ ấ ứ ể ố ố ư ộ ế ạ ế
double x = area(1.0, 2.0, 4.0, 6.0);
thì Java s dùng d ng th hai c a ẽ ạ ứ ủ area. Và l u ý r ng th c ra d ng ư ằ ự ạ area th hai đã kích ho t d ng th ứ ạ ạ ứ nh t. ấ
Nhi u ph ng th c Java đ c qua t i, nghĩa là có nhi u d ng trong đó ch p nh n s l ng ho c ki u ề ươ ứ ượ ả ề ạ ấ ậ ố ượ ặ ể tham s khác nhau. Ch ng h n, có nh ng d ng ố ẳ ạ ữ ạ print và println ch p nh n m t tham s thu c ki u b t ấ ậ ộ ố ộ ể ấ kì. Trong l p Math, có m t d ng ớ ộ ạ abs làm vi c v i ệ ớ double, đ ng th i có m t d ng dành cho ồ ờ ộ ạ int. M c dù quá t i là m t đ c đi m h u ích, so b n hãy c n th n khi dùng. B n có th th t s c m th y lú ặ ả ộ ặ ể ữ ạ ẩ ậ ạ ể ậ ự ả ấ l n n u c g ng g l i m t d ng ph ng th c trong khi b n không ch ý kích ho t nó, mà là m t ẫ ế ố ắ ỡ ỗ ộ ạ ươ ứ ạ ủ ạ ộ ph ng th c khác cùng tên! ươ ứ
Và đi u này làm tôi nh đ n m t quy t c then ch t trong g l i: ề ớ ế ộ ắ ố ỡ ỗ hãy đ m b o ch c r ng phiên b n ả ả ắ ằ ả ch ng trình b n c n g l i chính là phiên b n ch ng trình b n đang ch y! ươ ạ ầ ỡ ỗ ả ươ ạ ạ
M t ngày nào đó có th b n s th y mình đang loay hoay s a đi s a l i ch ng trình, và c th y k t qu ộ ể ạ ẽ ấ ử ử ạ ươ ứ ấ ế ả v n y nguyên nh v y khi ch y l i. Đây là m t tín hi u c nh báo r ng hi n b n không ch y phiên b n ẫ ư ậ ạ ạ ộ ệ ả ằ ệ ạ ạ ả ch ng trình nh đang nghĩ. Đ ki m tra l i, b n hãy th thêm m t câu l nh ươ ư ể ể ạ ạ ử ộ ệ print (ch ng quan tr ng là ẳ ọ in th gì) và xem ch ng trình có bi u hi n t ng ng hay không. ứ ươ ể ệ ươ ứ
6.5 Bi u th c logic ể ứ
H u h t các toán t mà ta đã g p đ u t o ra k t qu có cùng ki u v i các toán h ng trong đó. L y ví d , ầ ế ử ặ ề ạ ế ả ể ớ ạ ấ ụ toán tử + nh n hai s ậ ố int r i cũng t o ra m t s ồ ạ ộ ố int, ho c hai s ặ ố double r i t o thành m t ồ ạ ộ double, v.v. Nh ng ngo i l mà ta g p, đó là các ữ ạ ệ ặ toán t quan h ử ệ, v n đ so sánh các ố ể int ho cặ float r i tr ồ ả l i ạ true ho cặ false. true và false là nh ng giá tr đ c bi t trong Java; hai giá tr này h p nên m t ki u g i ữ ị ặ ệ ị ợ ộ ể ọ là boolean. B n có th nh l i r ng khi tôi đ nh nghĩa m t ki u, tôi có nói r ng đó là m t t p các giá tr . ạ ể ớ ạ ằ ị ộ ể ằ ộ ậ ị Đ i v i các s ố ớ ố int, double hay chu i ỗ String, nh ng t p h p nh v y đ u r t l n. Song v i ữ ậ ợ ư ậ ề ấ ớ ớ boolean, t p ậ h p này ch ch a hai giá tr . ợ ỉ ứ ị
Các bi u th c boolean, hay bi u th c logic, cùng các bi n cũng ho t đ ng gi ng nh các bi u th c và ể ứ ể ứ ế ạ ộ ố ư ể ứ bi n thu c ki u khác: ế ộ ể
boolean flag;
flag = true;
boolean testResult = false;
Ví d th nh t là m t l i khai báo bi n đ n gi n; ví d th hai là m t l nh gán, còn ví d th ba là m t ụ ứ ấ ộ ờ ế ơ ả ụ ứ ộ ệ ụ ứ ộ l nh kh i t o. ệ ở ạ
Các giá trị true và false là nh ng t khóa trong Java, vì v y chúng có th xu t hi n v i màu ch khác tùy ữ ừ ậ ể ấ ệ ớ ữ theo môi tr ng phát tri n tích h p mà b n đang dùng. ườ ể ợ ạ
K t qu c a m t toán t đi u ki n là m t giá tr boolean, b i v y b n có th l u tr k t qu c a phép so ế ả ủ ộ ử ề ệ ộ ị ở ậ ạ ể ư ữ ế ả ủ sánh vào m t bi n: ộ ế
boolean evenFlag = (n%2 == 0); // đúng nếu n chẵn
boolean positiveFlag = (x > 0); // đúng nếu x dương
r i l i dùng nó làm b ph n c a m t câu l nh đi u ki n: ồ ạ ộ ậ ủ ộ ệ ề ệ
if (evenFlag) {
System.out.println("Khi tôi kiểm tra, n là số chẵn");
}
M t bi n đ c dùng theo cách này có th g i là m t bi n ộ ế ượ ể ọ ộ ế d u hi u ấ ệ vì nó đánh d u cho s có m t ho c ấ ự ặ ặ v ng m t c a m t đi u ki n nào đó. ắ ặ ủ ộ ề ệ
6.6 Toán t logic ử
Có ba toán t logic ử trong Java: AND, OR và NOT, v n đ c kí hi u b i ba d u ố ượ ệ ở ấ &&, || và !. Ý nghĩa c a ủ các toán t này gi ng nh nghĩa các t t ng ng trong ti ng Anh. Ch ng h n, ử ố ư ừ ươ ứ ế ẳ ạ x > 0 && x < 10 ch đúng ỉ khi x l n h n 0 ớ ơ và nh h n 10. ỏ ơ
evenFlag || n%3 == 0 ch đúng khi ỉ m t trong hai ộ đi u ki n là đúng; nghĩa ề ệ
là evenFlag đúng ho cặ số n chia h t cho ế 3.
Sau cùng, toán tử not ph đ nh m t bi u th c Boole. Do v y ủ ị ộ ể ứ ậ !evenFlag là đúng n u nh ế ư evenFlag là sai —t c là n u s đã cho là l . ứ ế ố ẻ
Toán t logic có th làm đ n gi n nh ng câu l nh đi u ki n l ng ghép. Ch ng h n, b n có th vi t l i ử ể ơ ả ữ ệ ề ệ ồ ẳ ạ ạ ể ế ạ mã l nh d i đây b ng m t câu l nh đi u ki n đ n l đ c không? ệ ướ ằ ộ ệ ề ệ ơ ẻ ượ
if (x > 0) {
if (x < 10) {
System.out.println("x là số dương gồm 1 chữ số.");
}
}
6.7 Ph ng th c logic ươ ứ
Các ph ng th c có th tr l i giá tr boolean cũng nh các ki u d li u khác; và đi u này th ng thu n ươ ứ ể ả ạ ị ư ể ữ ệ ề ườ ậ ti n cho vi c đem nh ng thao tác ki m tra c t gi u vào trong ph ng th c. Ch ng h n: ệ ệ ữ ể ấ ấ ươ ứ ẳ ạ
public static boolean isSingleDigit(int x) {
if (x >= 0 && x < 10) {
return true;
} else {
return false;
}
}
Ph ng th c này có tên là ươ ứ isSingleDigit. Th ng thì ng i ta hay đ t tên ph ng th c logic theo ki u ườ ườ ặ ươ ứ ể nh nh ng câu h i đúng/sai. Ki u d li u tr l i là ư ữ ỏ ể ữ ệ ả ạ boolean, nh v y m i câu l nh return đ u ph i đ a ư ậ ỗ ệ ề ả ư ra m t bi u th c boolean. ộ ể ứ
B n thân đo n mã l nh r t rõ nghĩa, m c dù nó dài h n m c c n thi t. Hãy nh r ng bi u th c ả ạ ệ ấ ặ ơ ứ ầ ế ớ ằ ể ứ x >= 0 && x < 10 có ki u boolean, b i v y không có gì sai khi ta tr c ti p tr l i nó đ ng th i tránh đ c câu ể ở ậ ự ế ả ạ ồ ờ ượ
l nh ệ if:
public static boolean isSingleDigit(int x) {
return (x >= 0 && x < 10);
}
Từ main b n có th kích ho t ph ng th c này theo cách thông th ng: ạ ể ạ ươ ứ ườ
boolean bigFlag = !isSingleDigit(17);
System.out.println(isSingleDigit(2));
Dòng đ u tiên đ t ầ ặ bigFlag là true ch khi 17 ỉ không ph i ả s có m t ch s . Dòng l nh th hai in ố ộ ữ ố ệ ứ ra true b i 2 là ch có m t ch s . ở ỉ ộ ữ ố
Cách dùng hay g p nh t đ i v i ph ng th c boole là trong các câu l nh đi u ki n ặ ấ ố ớ ươ ứ ệ ề ệ if (isSingleDigit(x)) {
System.out.println("x nhỏ");
} else {
System.out.println("x lớn");
}
6.8 Nói thêm v đ quy ề ệ
Bây gi khi đã bi t ph ng th c tr l i giá tr , ta có đ c m t ngôn ng l p trình ờ ế ươ ứ ả ạ ị ượ ộ ữ ậ Turing đ y đ ầ ủ; theo nghĩa là chúng ta s tính đ c m i th có th tính toán, trong đó “có th tính toán” đ c đ nh nghĩa ẽ ượ ọ ứ ể ể ượ ị
theo cách b t kì, mi n là h p lý. Ý t ng này đ c ấ ễ ợ ưở ượ Alonzo Church và Alan Turing phát tri n, b i v y nó ể ở ậ còn mang tên lu n án Church-Turing. B n có th đ c thêm thông tin ậ ạ ể ọ
ởhttp://en.wikipedia.org/wiki/Turing_thesis.
Đ c th hoá tác d ng c a nh ng ki n th c l p trình mà b n v a đ c h c, chúng ta hãy cùng l p m t ể ụ ể ụ ủ ữ ế ứ ậ ạ ừ ượ ọ ậ ộ s hàm toán h c theo cách đ quy. M t đ nh nghĩa đ quy gi ng nh vi c đ nh nghĩa vòng quanh; đi m ố ọ ệ ộ ị ệ ố ư ệ ị ể t ng đ ng là trong ph n đ nh nghĩa l i có tham chi u đ n s v t đ c đ nh nghĩa. Nh ng cách đ nh ươ ồ ầ ị ạ ế ế ự ậ ượ ị ư ị nghĩa vòng quanh th c s thì không m y có tác d ng: ự ự ấ ụ
đ quy: ệ
m t tính t đ ch m t ph ng th c mang tính đ quy. ộ ừ ể ỉ ộ ươ ứ ệ
B n h n s b c mình khi th y m t đ nh nghĩa ki u nh v y trong cu n t đi n. Ng c l i, khi b n xem ạ ẳ ẽ ự ấ ộ ị ể ư ậ ố ừ ể ượ ạ ạ
đ nh nghĩa v hàm ị ề giai th aừ trong toán h c, có th b n s th y: ọ ể ạ ẽ ấ
0! = 1
n! = n ·(n−1)!
(Giai th a th ng đ c kí hi u b i d u !, xin đ ng nh m v i toán t logic ừ ườ ượ ệ ở ấ ừ ầ ớ ử ! v i ý nghĩa NOT.) Đ nh ớ ị nghĩa này phát bi u r ng giai th a c a 0 là 1, và giai th a c a b t kì m t giá tr nào khác, ể ằ ừ ủ ừ ủ ấ ộ ị n, thì b ng ằ n nhân v i giai th a c a ớ ừ ủ n - 1. Theo đó, 3! b ng 3 nhân v i ằ ớ 2!, v n l i b ng 2 nhân v i ố ạ ằ ớ 1!, v n b ng ố ằ
1 nhân v i ớ 0!. G p t t c l i, ta có ộ ấ ả ạ 3! b ng 3 nhân 2 nhân 1 nhân 1, t c là b ng 6. ằ ứ ằ N u b n có th phát bi u m t đ nh nghĩa có tính đ quy cho m t hàm nào đó thì b n cũng có th vi t ế ạ ể ể ộ ị ệ ộ ạ ể ế
m t ph ng th c Java đ tính nó. B c đ u tiên là xác đ nh các tham s và ki u d li u c a giá tr tr ộ ươ ứ ể ướ ầ ị ố ể ữ ệ ủ ị ả l i. Vì giai th a đ c đ nh nghĩa cho các s nguyên, nên ph ng th c c n vi t s nh n tham s là s ạ ừ ượ ị ố ươ ứ ầ ế ẽ ậ ố ố nguyên r i tr l i cũng m t s nguyên: ồ ả ạ ộ ố
public static int factorial(int n) {
}
N u đ i s b ng 0, chúng ta ch c n tr l i giá tr 1: ế ố ố ằ ỉ ầ ả ạ ị
public static int factorial(int n) {
if (n == 0) {
return 1;
}
}
Đó là tr ng h p c s . ườ ợ ơ ở
N u đi u đó không x y ra (đây chính là ph n hay nh t), chúng ta th c hi n l i g i đ quy đ tính giai ế ề ả ầ ấ ự ệ ờ ọ ệ ể
th a c a ừ ủ n - 1 và sau đó nhân nó v i ớ n.
public static int factorial(int n) {
if (n == 0) {
return 1;
} else {
int recurse = factorial(n-1);
int result = n * recurse;
return result;
}
}
Lu ng th c hi n c a ch ng trình này cũng gi ng v i ồ ự ệ ủ ươ ố ớ countdown trong M c 4.8. N u ta kích ụ ế ho t ạ factorial v i giá tr 3: ớ ị
Vì 3 khác 0 nên ta ch n nhánh th hai và tính giai th a c a ọ ứ ừ ủ n-1…
Vì 2 khác 0 nên ta ch n nhánh th hai và tính giai th a c a ọ ứ ừ ủ n-1…
Vì 1 khác 0 nên ta ch n nhánh th hai và tính giai th a c a ọ ứ ừ ủ n-1…
Vì 0 b ng ằ 0 nên ta ch n nhánh th nh t và tr l i giá tr 1 và không g i đ quy thêm l n nào n a. ọ ứ ấ ả ạ ị ọ ệ ầ ữ Giá tr đ c tr v , 1, đ c nhân v i ị ượ ả ề ượ ớ n, v n b ng 1, và k t qu đ c tr l i. ố ằ ế ả ượ ả ạ
Giá tr đ c tr v (1) đ c nhân v i ị ượ ả ề ượ ớ n, v n b ng 2, và k t qu đ c tr l i. ố ằ ế ả ượ ả ạ
Giá tr đ c tr v (2) đ c nhân v i ị ượ ả ề ượ ớ n, v n b ng 3, và k t qu , 6 tr thành giá tr tr v c a hàm ng ố ằ ế ả ở ị ả ề ủ ứ v i lúc b t đ u g i đ quy. ớ ắ ầ ọ ệ
Sau đây là n i dung c a bi u đ ngăn x p khi m t lo t các ph ng th c đ c kích ho t: ộ ủ ể ồ ế ộ ạ ươ ứ ượ ạ Các giá tr tr l i nh đây đ c chuy n v ngăn x p. ị ả ạ ư ở ượ ể ề ế
L u ý r ng khung cu i cùng, các bi n đ a ph ng ư ằ ở ố ế ị ươ recurse và result đ u không t n t i, vì ề ồ ạ
khi n=0, nhánh t o ra chúng không đ c th c hi n. ạ ượ ự ệ
6.9 Ni m tin ề
Vi c dõi theo lu ng th c hi n c a ch ng trình là m t cách đ c mã l nh, nh ng b n s nhanh chóng l c ệ ồ ự ệ ủ ươ ộ ọ ệ ư ạ ẽ ạ vào mê cung. M t cách làm khác mà tôi g i là “ni m tin” nh sau. Khi b n dò đ n ch kích ho t ph ng ộ ọ ề ư ạ ế ỗ ạ ươ th c, thay vì vi c đi theo lu ng th c hi n, hãy ứ ệ ồ ự ệ coi như là ph ng th c đó ho t đ ng t t và tr l i k t qu ươ ứ ạ ộ ố ả ạ ế ả đúng.
Th t ra, b n đã t ng có “ni m tin” này khi dùng các ph ng th c c a Java. M i l n kích ậ ạ ừ ề ươ ứ ủ ỗ ầ ho t ạ Math.cos hay System.out.println, b n không ki m tra n i dung bên trong các ph ng th c ạ ể ộ ươ ứ này. B n ch vi c gi s r ng chúng ho t đ ng đ c. ạ ỉ ệ ả ử ằ ạ ộ ượ
Cũng v i lý l t ng t khi b n kích ho t các ph ng th c do mình vi t nên. Ch ng h n, trong M c 6.7, ớ ẽ ươ ự ạ ạ ươ ứ ế ẳ ạ ụ chúng ta đã vi t m t hàm tên là ế ộ isSingleDigit đ xác đ nh xem m t s có n m trong kho ng t 0 đ n ể ị ộ ố ằ ả ừ ế 9 hay không. M t khi chúng ta t thuy t ph c r ng ph ng th c này đã vi t đúng—b ng cách ki m tra ộ ự ế ụ ằ ươ ứ ế ằ ể
và th mã l nh—chúng ta có th s d ng ph ng th c mà không c n ph i xem l i ph n mã l nh n a. ử ệ ể ử ụ ươ ứ ầ ả ạ ầ ệ ữ Đi u t ng t cũng đúng v i các ch ng trình đ quy. Khi b n đ n đi m kích ho t đ quy, thay vì đi ề ươ ự ớ ươ ệ ạ ế ể ạ ệ theo lu ng th c hi n, b n c n ồ ự ệ ạ ầ coi r ng ằ l i g i đ quy ho t đ ng t t (t c là cho k t qu đúng) và sau đó ờ ọ ệ ạ ộ ố ứ ế ả t h i mình “Gi d nh ta đã tìm đ c giai th a c a ự ỏ ả ụ ư ượ ừ ủ n−1, li u ta có tính đ c giai th a c a ệ ượ ừ ủ n không?” Trong tr ng h p này, rõ ràng là ta s tính đ c, b ng cách nhân v i ườ ợ ẽ ượ ằ ớ n.
Dĩ nhiên là s có chút kì l trong vi c ta gi s r ng hàm ho t đ ng t t khi ch a vi t xong nó, nh ng ẽ ạ ệ ả ử ằ ạ ộ ố ư ế ư chính vì v y mà ta g i đó là ni m tin! ậ ọ ề
6.10 Thêm m t ví d ộ ụ
Ví d thông d ng th hai đ minh h a cho m t hàm toán toán h c đ quy là ụ ụ ứ ể ọ ộ ọ ệ fibonacci, v i cách đ nh ớ ị
nghĩa hàm nh sau: ư
fibonacci(0) = 1
fibonacci(1) = 1
fibonacci(n) = fibonacci(n−1) + fibonacci(n−2);
Chuy n sang ngôn ng Java, ta vi t đ c ể ữ ế ượ
public static int fibonacci(int n) {
if (n == 0 || n == 1) {
return 1;
} else {
return fibonacci(n-1) + fibonacci(n-2);
}
}
N u b n th g ng theo lu ng th c hi n đây, ngay c v i các giá tr nh c a ế ạ ử ắ ồ ự ệ ở ả ớ ị ỏ ủ n, b n s đau đ u ngay. ạ ẽ ầ Nh ng b ng ni m tin, n u b n coi r ng c hai l i g i đ quy đ u ho t đ ng t t, thì rõ ràng b n s thu ư ằ ề ế ạ ằ ả ờ ọ ệ ề ạ ộ ố ạ ẽ
đ c k t qu đúng khi c ng chúng l i v i nhau. ượ ế ả ộ ạ ớ
6.11 Thu t ng ậ ữ
ki u tr l i: ể ả ạ
Ph n c a l i khai báo ph ng th c, trong đó quy đ nh ki u c a giá tr mà ph ng th c đó s tr l i. ầ ủ ờ ươ ứ ị ể ủ ị ươ ứ ẽ ả ạ giá tr tr l i: ị ả ạ
Giá tr đ c đ a ra làm k t qu c a vi c kích ho t ph ng th c. ị ượ ư ế ả ủ ệ ạ ươ ứ
đo n mã ch t: ạ ế
Ph n ch ng trình không bao gi đ c th c hi n, th ng là do nó xu t hi n sau m t câu ầ ươ ờ ượ ự ệ ườ ấ ệ ộ l nh ệ return.
dàn giáo:
Mã l nh đ c dùng trong giai đo n phát tri n ch ng trình nh ng b b đi phiên b n ch ng trình ệ ượ ạ ể ươ ư ị ỏ ở ả ươ cu i. ố
r ng (void): ỗ
M t ki u tr l i đ c bi t có ph ng th c r ng; nghĩa là ph ng th c không tr l i giá tr nào. ộ ể ả ạ ặ ệ ở ươ ứ ỗ ươ ứ ả ạ ị quá t i: ả
Vi c có nhi u ph ng th c v i cùng tên g i nh ng có các tham s khác nhau. Khi b n kích ho t m t ệ ề ươ ứ ớ ọ ư ố ạ ạ ộ
ph ng th c quá t i, Java s bi t đ c ph i dùng d ng nào c a ph ng th c, căn c vào nh ng đ i s ươ ứ ả ẽ ế ượ ả ạ ủ ươ ứ ứ ữ ố ố mà b n cung c p. (Ti ng Anh: “Overloading”) ạ ấ ế
boolean:
M t ki u bi n ch ch a hai giá tr ộ ể ế ỉ ứ ị true và false (đúng và sai).
d u hi u: ấ ệ
M t bi n (th ng v i ki u ộ ế ườ ớ ể boolean) đ ghi l i thông tin v m t đi u ki n ho c tr ng thái nào đó. ể ạ ề ộ ề ệ ặ ạ toán t đi u ki n: ử ề ệ
M t toán t dùng đ so sánh hai giá tr r i t o ra m t giá tr boolean đ ch đ nh quan h gi a hai toán ộ ử ể ị ồ ạ ộ ị ể ỉ ị ệ ữ h ng nêu trên. ạ
toán t logic: ử
M t toán t nh m k t h p các giá tr boolean r i tr l i cũng giá tr boolean. ộ ử ằ ế ợ ị ồ ả ạ ị
6.12 Bài t pậ
Bài t p 1 ậ Hãy vi t m t ph ng th c có tên ế ộ ươ ứ isDivisible đ nh n vào hai s nguyên, ể ậ ố n và m r i tr ồ ả l i ạ true n uế n chia h t cho ế m và tr l i ả ạ false trong tr ng h p còn l i. ườ ợ ạ
Bài t p 2 ậ Nhi u phép tính có th đ c di n đ t ng n g n b ng phép “multadd” (nhân-c ng), trong đó ề ể ượ ễ ạ ắ ọ ằ ộ l y ba toán h ng r i đi tính ấ ạ ồ a*b + c. Th m chí có b vi x lý còn tích h p c phép tính này đ i v i nh ng ậ ộ ử ợ ả ố ớ ữ s ph y đ ng. ố ẩ ộ
1. Hãy l p m t ch ng trình m i có tên g i ậ ộ ươ ớ ọ Multadd.java.
2. Vi t m t ph ng th c g i là ế ộ ươ ứ ọ multadd đ l y tham s là ba s ể ấ ố ố double r i tr l i k t qu c a phép nhân- ồ ả ạ ế ả ủ c ng gi a chúng. ộ ữ
3. Vi t m t ph ng th c ế ộ ươ ứ main đ ki m tra ể ể multadd b ng cách kích ho t nó v i m t vài tham s đ n gi n ằ ạ ớ ộ ố ơ ả như 1.0, 2.0, 3.0.
4. Cũng trong main, hãy dùng multadd đ tính các giá tr sau: ể ị
+
sin π
— 4
cos
π
—
4
—————
2
log10 + log20
5. Hãy vi t m t ph ng th c có tên ế ộ ươ ứ yikes đ nh n tham s là m t double r i dùng ể ậ ố ộ ồ multadd đ tính ể √
x e−x +
———— 1 − e−x
G i ý: đ nâng ợ ể e lên m t s mũ, hãy dùng ph ng th c có tên ộ ố ươ ứ Math.exp.
Trong câu h i sau cùng, b n có c h i vi t m t ph ng th c đ kích ho t m t ph ng th c mà b n đã ỏ ạ ơ ộ ế ộ ươ ứ ể ạ ộ ươ ứ ạ vi t tr c đó. M i khi làm nh v y, b n nên c n th n ki m th ph ng th c đ u tr c khi vi t sang ế ướ ỗ ư ậ ạ ẩ ậ ể ử ươ ứ ầ ướ ế ph ng th c th hai. N u không, có th b n s r i vào tr ng h p ph i g l i hai ph ng th c cùng ươ ứ ứ ế ể ạ ẽ ơ ườ ợ ả ỡ ỗ ươ ứ lúc, m t công vi c r t khó khăn. ộ ệ ấ
M t m c đích c a bài này là nh m luy n t p cách kh p m u: đó là khi đ c cho m t bài toán c th , ta ộ ụ ủ ằ ệ ậ ớ ẫ ượ ộ ụ ể c n nh n d ng nó trong s m t t p h p các th lo i bài toán. ầ ậ ạ ố ộ ậ ợ ể ạ
Bài t p 3 ậ N u có trong tay ba que g , có th b n s có ho c không x p đ c thành hình tam giác. ế ỗ ể ạ ẽ ặ ế ượ
Ch ng h n, n u m t que dài ẳ ạ ế ộ 12 inch còn hai que kia, m i que ch dài 1 inch, thì b n không th kéo hai ỗ ỉ ạ ể đ u que ng n ch m nhau gi a đ c. V i ba đo n th ng có dài b t kì, có m t cách ki m tra đ n gi n ầ ắ ạ ở ữ ượ ớ ạ ẳ ấ ộ ể ơ ả đ xem li u chúng có x p thành hình tam giác đ c không: ể ệ ế ượ
“N u có b t kì chi u dài nào trong s đó l n h n t ng hai chi u dài còn l i, thì b n không ế ấ ề ố ớ ơ ổ ề ạ ạ th d ng thành hình tam giác. Tr ng h p còn l i, thì có th đ c.” ể ự ườ ợ ạ ể ượ
Hãy vi t m t ph ng th c v i tên g i ế ộ ươ ứ ớ ọ isTriangle, nh n vào đ i s là ba s nguyên, r i tr ậ ố ố ố ồ ả l i ạ true ho cặ false, tùy theo kh năng x p thành hình tam giác b ng nh ng que có chi u dài đã cho. ả ế ằ ữ ề M c đích c a bài t p này là nh m áp d ng nh ng l nh đi u ki n đ vi t nên m t ph ng th c tr l i giá ụ ủ ậ ằ ụ ữ ệ ề ệ ể ế ộ ươ ứ ả ạ tr .ị
Bài t p 4 ậ K t qu c a ch ng trình d i đây là gì? M c đích c a bài t p này nh m đ m b o r ng b n ế ả ủ ươ ướ ụ ủ ậ ằ ả ả ằ ạ
hi u rõ các toán t logic và lu ng th c thi thông qua các ph ng th c tr giá tr . ể ử ồ ự ươ ứ ả ị public static void main(String[] args) {
boolean flag1 = isHoopy(202);
boolean flag2 = isFrabjuous(202);
System.out.println(flag1);
System.out.println(flag2);
if (flag1 && flag2) {
System.out.println("ping!");
}
if (flag1 || flag2) {
System.out.println("pong!");
}
}
public static boolean isHoopy(int x) {
boolean hoopyFlag;
if (x%2 == 0) {
hoopyFlag = true;
} else {
hoopyFlag = false;
}
return hoopyFlag;
}
public static boolean isFrabjuous(int x) {
boolean frabjuousFlag;
if (x > 0) {
frabjuousFlag = true;
} else {
frabjuousFlag = false;
}
return frabjuousFlag;
}
Bài t p 5 ậ Kho ng cách gi a hai đi m ( ả ữ ể x1, y1) và (x2, y2) thì b ng ằ √
Distance =
———————————— (x2 − x1)2 +(y2 − y1)2
Hãy vi t m t ph ng th c có tên ế ộ ươ ứ distance đ nh n các tham s g m b n s ph y đ ng— ể ậ ố ồ ố ố ẩ ộ x1, y1, x2 và y2 —r i in ra kho ng cách gi a hai đi m này. B n c n gi s r ng đã có m t ph ng th c ồ ả ữ ể ạ ầ ả ử ằ ộ ươ ứ sumSquares đ ể
tính và tr l i t ng các bình ph ng c a đ i s . Ch ng h n dòng l nh: ả ạ ổ ươ ủ ố ố ẳ ạ ệ
double x = sumSquares(3.0, 4.0);
s gán giá tr ẽ ị 25.0 cho x.
M c đích c a bài t p này là nh m vi t m t ph ng th c m i có áp d ng ph ng th c s n có. B n ch ụ ủ ậ ằ ế ộ ươ ứ ớ ụ ươ ứ ẵ ạ ỉ c n vi t m t ph ng th c: ầ ế ộ ươ ứ distance. B n không đ c vi t ạ ượ ế sumSquares hay main và cũng không kích ho t ạ distance.
Bài t p 6 ậ M c đích c a bài t p này là dùng bi u đ ngăn x p đ hi u đ c trình t th c hi n m t ụ ủ ậ ể ồ ế ể ể ượ ự ự ệ ộ
ch ng trình đ quy. ươ ệ
public class Prod {
public static void main(String[] args) {
System.out.println(prod(1, 4));
}
public static int prod(int m, int n) {
if (m == n) {
return n;
} else {
int recurse = prod(m, n-1);
int result = n * recurse;
return result;
}
}
}
1. Hãy v m t bi u đ ngăn x p cho th y tr ng thái c a ch ng trình ngay tr c khi th c th cu i cùng ẽ ộ ể ồ ế ấ ạ ủ ươ ướ ự ể ố c aủ prod hoàn t t th c thi. K t qu c a ch ng trình này là gì? ấ ự ế ả ủ ươ
2. Gi i thích ng n g n xem ả ắ ọ prod làm vi c gì. ệ
3. Vi t l i ế ạ prod mà không dùng đ n các bi n t m ế ế ạ recurse và result.
Bài t p 7 ậ M c đích c a bài t p này là chuy n t m t l i đ nh nghĩa đ quy sang m t ph ng th c ụ ủ ậ ể ừ ộ ờ ị ệ ộ ươ ứ Java. Hàm Ackerman đ c đ nh nghĩa cho s nguyên không âm nh sau: ượ ị ố ư
A(m, n) =
⎧
⎨
⎩
n+1 nếu m = 0
A(m−1, 1) nếu m > 0 và n = 0 A(m−1, A(m, n−1)) nếu m > 0 và n > 0.
(1)
Hãy vi t m t ph ng th c tên là ế ộ ươ ứ ack đ nh n tham s là hai s ể ậ ố ố int r i tính và tr l i giá tr c a hàm ồ ả ạ ị ủ Ackerman. Hãy ki m tra ph ng th c v a vi t b ng cách kích ho t nó t ể ươ ứ ừ ế ằ ạ ừ main r i in ra giá tr v a tr ồ ị ừ ả l i. ạ
C NH BÁO: giá tr đ c tr l i s r t nhanh chóng tăng cao. B n ch nên th ch y v i các giá tr m Ả ị ượ ả ạ ẽ ấ ạ ỉ ử ạ ớ ị và n nh (không l n quá 2). ỏ ớ
Bài t p 8 ậ
1. Hãy t o nên m t ch ng trình có tên ạ ộ ươ Recurse.java r i gõ vào các ph ng th c sau: ồ ươ ứ // first: trả lại kí tự đầu tiên của String cho trước
public static char first(String s) {
return s.charAt(0);
}
// last: trả lại một String mới có chứa toàn bộ
// chỉ trừ kí tự đầu của String cho trước
public static String rest(String s) {
return s.substring(1, s.length());
}
// length: trả lại chiều dài của String cho trước
public static int length(String s) {
return s.length();
}
2. Hãy vi t vài câu l nh trong ế ệ main đ ki m tra t ng ph ng th c trên. Đ m b o ch c là chúng ho t đ ng ể ể ừ ươ ứ ả ả ắ ạ ộ đ c, và ch c ch n là b n đã hi u công d ng c a chúng là gì. ượ ắ ắ ạ ể ụ ủ
3. Vi t m t ph ng th c có tên ế ộ ươ ứ printString đ nh n tham s là m t String đ ng th i in các ch cái trong ể ậ ố ộ ồ ờ ữ String đó, m i ch cái trên m t dòng. Ph ng th c này ph i là ki u r ng. ỗ ữ ộ ươ ứ ả ể ỗ
4. Vi t m t ph ng th c có tên ế ộ ươ ứ printBackward có công d ng g n gi ng ụ ầ ố printString ch khác là in String ỉ theo chi u ng c l i (m i kí t trên m t dòng riêng). ề ượ ạ ỗ ự ộ
5. Vi t m t ph ng th c có tên ế ộ ươ ứ reverseString đ nh n tham s là m t String r i tr l i giá tr là m t String ể ậ ố ộ ồ ả ạ ị ộ m i. String m i này ph i có đ y đ các ch cái nh String đã nh p làm tham s ; nh ng l i x p theo th ớ ớ ả ầ ủ ữ ư ậ ố ư ạ ế ứ
t ng c l i. Ch ng h n, k t qu c a đo n mã l nh sau ự ượ ạ ẳ ạ ế ả ủ ạ ệ
String backwards = reverseString("Allen Downey");
System.out.println(backwards);
s ph i là ẽ ả
yenwoD nellA
Bài t p 9 ậ Hãy vi t m t ph ng th c đ quy có tên ế ộ ươ ứ ệ power đ nh n vào ể ậ x và m t s nguyên ộ ố n r i tr ồ ả l i ạ xn. G i ý: m t đ nh nghĩa đ quy đ i v i phép tính này là ợ ộ ị ệ ố ớ xn = x · xn −1. Đ ng th i, c n nh r ng m i ồ ờ ầ ớ ằ ọ s nâng lên lũy th a b c 0 đ u b ng 1. Câu h i khó t ch n: b n có th làm cho ph ng th c này hi u ố ừ ậ ề ằ ỏ ự ọ ạ ể ươ ứ ệ qu h n, trong tr ng h p ả ơ ườ ợ n ch n, b ng cách dùng công th c ẵ ằ ứ xn = (xn/2 )2.
Bài t p 10 ậ (Bài t p này đ c d a trên trang 44 cu n sách Structure and Interpretation of Computer ậ ượ ự ố Programs c a Abelson và Sussman.) Kĩ thu t sau đây có tên g i Thu t toán Euclid vì nó xu t hi n trong ủ ậ ọ ậ ấ ệ t p C b n c a Euclid (Cu n s 7, kho ng năm 300 TCN). Có l đây là thu t toán đáng k t lâu đ i ậ ơ ả ủ ố ố ả ẽ ậ ể ừ ờ nh t ấ 1. Quy trình tính toán đ c d a theo quan sát th y, n u ượ ự ấ ế r là ph n d trong phép chia ầ ư a cho b, thì các c s chung c a ướ ố ủ a và b cũng b ng c s chung c a ằ ướ ố ủ b và r. Do v y ta có th dùng ph ng trình ậ ể ươ gcd(a, b) = gcd(b, r)
đ liên ti p rút g n bài toán tính c s chung (GCD) v bài toán tính GCD c a các c p s nguyên ngày ể ế ọ ướ ố ề ủ ặ ố càng nh h n. Ch ng h n, ỏ ơ ẳ ạ
gcd(36, 20) = gcd(20, 16) = gcd(16, 4) = gcd(4, 0) = 4
ng ý r ng GCD c a 36 và 20 thì b ng 4. Có th th y r ng v i b t kì hai s ban đ u nào, cách liên ti p ụ ằ ủ ằ ể ấ ằ ớ ấ ố ầ ế rút g n này cu i cùng s cho ta m t c p s mà s th hai b ng 0. Khi đó GCD s b ng s còn l i trong ọ ố ẽ ộ ặ ố ố ứ ằ ẽ ằ ố ạ c p. ặ
Hãy vi t m t ph ng th c có tên ế ộ ươ ứ gcd đ nh n tham s là hai s nguyên r i dùng Thu t toán Euclid đ ể ậ ố ố ồ ậ ể tính và tr l i c s chung l n nh t c a hai s . ả ạ ướ ố ớ ấ ủ ố
Ch ng 7: Phép l p và vòng ươ ặ l pặ
7.1 Phép gán nhi u l n ề ầ
B n có th khi n cho nhi u l nh gán ch t i cùng m t bi n; mà hi u qu c a nó là nh m thay th giá tr ạ ể ế ề ệ ỉ ớ ộ ế ệ ả ủ ằ ế ị cũ b ng giá tr m i. ằ ị ớ
int liz = 5;
System.out.print(liz);
liz = 7;
System.out.println(liz);
K t qu c a ch ng trình này b ng ế ả ủ ươ ằ 57, vì l n đ u tiên khi in ầ ầ liz bi n này có giá tr b ng 5, còn l n th ế ị ằ ầ ứ hai thì bi n có giá tr b ng 7. ế ị ằ
Hình th cứ gán nhi u l n ề ầ nh th này là lí do mà tôi mô t các bi n nh là ư ế ả ế ư h p ch a ộ ứ giá tr . Khi b n ị ạ
gán m t giá tr vào cho bi n, b n thay đ i n i dung c a h p ch a, nh hình v sau: ộ ị ế ạ ổ ộ ủ ộ ứ ư ở ẽ
Khi có nhi u phép gán đ i v i cùng m t bi n, thì r t chú tr ng vi c phân bi t gi a câu l nh gán và đ ng ề ố ớ ộ ế ấ ọ ệ ệ ữ ệ ẳ th c. Vì Java dùng d u ứ ấ = cho l nh gán nên ta b lôi cu n vào vi c di n gi i m t câu l nh nh ệ ị ố ệ ễ ả ộ ệ ư a = b là câu l nh đ ng th c. Th t ra không ph i v y! ệ ẳ ứ ậ ả ậ
Tr c h t, đ ng th c thì có tính giao hoán, còn l nh gán thì không. Ch ng h n trong toán h c, n u ướ ế ẳ ứ ệ ẳ ạ ọ ế a = 7 thì 7 = a. Nh ng trong Java ư a = 7; l i là m t l nh gán h p l , còn ạ ộ ệ ợ ệ 7 = a; thì không. H n n a, trong toán h c, m t đ ng th c thì luôn đúng. N u bây gi ơ ữ ọ ộ ẳ ứ ế ờ a = b, thì a s luôn b ng ẽ ằ b. Trong Java, m t l nh gán có th làm cho hai bi n b ng nhau, nh ng không có gì b t bu c chúng b ng nhau ộ ệ ể ế ằ ư ắ ộ ằ mãi!
int a = 5;
int b = a; // bây giờ thì a bằng b
a = 3; // a không còn bằng b nữa
Dòng l nh th ba đã thay đ i giá tr c a ệ ứ ổ ị ủ a mà không làm thay đ i giá tr c a ổ ị ủ b, vì v y chúng không còn ậ b ng nhau. M t s ngôn ng l p trình có dùng kí hi u khác cho phép gán, nh ằ ộ ố ữ ậ ệ ư <- ho cặ :=, đ tránh s ể ự nh m l n này. ầ ẫ
M c dù phép gán nhi u l n th ng có ích, so b n nên c n th n khi dùng. N u giá tr c a các bi n thay ặ ề ầ ườ ạ ẩ ậ ế ị ủ ế đ i th ng xuyên thì có có th khi n cho mã l nh khó đ c và g l i. ổ ườ ể ế ệ ọ ỡ ỗ
7.2 Câu l nh ệ while
Máy tính th ng đ c dùng đ t đ ng hóa các thao tác có tính l p l i. Th c hi n nh ng thao tác l p l i ườ ượ ể ự ộ ặ ạ ự ệ ữ ặ ạ này mà không ph m l i là đi u mà máy tính làm t t còn chúng ta làm r t d . ạ ỗ ề ố ấ ở
Ta đã th y các ph ng th c nh ấ ươ ứ ư countdown và factorial trong đó dùng đ quy đ th c hi n l p. Quá ệ ể ự ệ ặ trình này đ c g i là ượ ọ phép l pặ . Java có nh ng đ c đi m ngôn ng giúp cho vi c vi t các ph ng th c ữ ặ ể ữ ệ ế ươ ứ nêu trên m t cách d dàng h n. ch ng này ta xem xét câu l nh ộ ễ ơ Ở ươ ệ while. V sau ( M c ề ở ụ 12.4) ta xét đ nế
câu l nh ệ for.
Dùng câu l nh ệ while, ta có th vi t l i ể ế ạ countdown:
public static void countdown(int n) {
while (n > 0) {
System.out.println(n);
n = n-1;
}
System.out.println("Bum!");
}
G n nh là b n có th đ c đ c toàn b câu l nh ầ ư ạ ể ọ ượ ộ ệ while b ng ti ng Anh. L nh này di n t là, “Khi ằ ế ệ ễ ả n l n ớ h n không, hãy in giá tr c a ơ ị ủ n r i gi m giá tr c a ồ ả ị ủ n xu ng 1. Khi b n đ t đ n không, hãy in ra t ố ạ ạ ế ừ ‘Bum!”’
Theo cách quy c h n, lu ng th c thi c a m t l nh ủ ơ ồ ự ủ ộ ệ while nh sau: ư
1.Đ nh giá đi u ki n trong c p ngo c tròn, cho ra ị ề ệ ặ ặ true ho cặ false.
2.N u đi u ki n là sai, thì thoát kh i l nh ế ề ệ ỏ ệ while r i ti p t c th c thi câu l nh li n sau. ồ ế ụ ự ệ ề 3.N u đi u ki n là đúng, thì th c thi nh ng câu l nh trong ph m vi c p ngo c nh n, r i tr l i b c 1. ế ề ệ ự ữ ệ ạ ặ ặ ọ ồ ở ạ ướ Ki u lu ng th c thi này đ c g i là ể ồ ự ượ ọ vòng l pặ vì b c th ba vòng ng c tr lên đ u. Nh ng câu l nh ướ ứ ượ ở ầ ữ ệ bên trong vòng l p đ c g i là ặ ượ ọ thân c a vòng l p. N u đi u ki n là sai ngay l n đ u tiên qua vòng l p ủ ặ ế ề ệ ầ ầ ặ thì nh ng câu l nh bên trong vòng l p không bao gi đ c th c thi. ữ ệ ặ ờ ượ ự
Ph n thân vòng l p c n ph i thay đ i giá tr c a m t vài bi n sao cho cu i cùng thì đi u ki n tr nên sai ầ ặ ầ ả ổ ị ủ ộ ế ố ề ệ ở và vòng l p ch m d t. N u không, vòng s đ c l p l i mãi, và đ c g i là vòng l p ặ ấ ứ ế ẽ ượ ặ ạ ượ ọ ặ vô h nạ . M t câu ộ chuy n đùa luôn đ c nh c đ n trong gi i khoa h c máy tính là qua vi c nh n th y ch d n trên gói d u ệ ượ ắ ế ớ ọ ệ ậ ấ ỉ ẫ ầ g i đ u, “Xát, x n c, r i l p l i,” chính là m t vòng l p vô h n. ộ ầ ả ướ ồ ặ ạ ộ ặ ạ
Ở ườ ợ tr ng h p countdown, ta có th ch ng minh r ng vòng l p s k t thúc n u ể ứ ằ ặ ẽ ế ế n là s d ng. Còn trong ố ươ
nh ng tr ng h p khác thì không d nói tr c: ữ ườ ợ ễ ướ
public static void sequence(int n) {
while (n != 1) {
System.out.println(n);
if (n%2 == 0) { // n chẵn
n = n / 2;
} else { // n lẻ
n = n*3 + 1;
}
}
}
Đi u ki n c a vòng l p này là ề ệ ủ ặ n != 1, vì v y vòng l p s ti p di n đ n t n khi ậ ặ ẽ ế ễ ế ậ n b ng 1, và đi u này khi n ằ ề ế cho đi u ki n b sai đi. ề ệ ị
T i m i vòng l p, ch ng trình in ra giá tr c a ạ ỗ ặ ươ ị ủ n r i ki m tra xem li u s này ch n hay l . N u ch n, giá ồ ể ệ ố ẵ ẻ ế ẵ
tr c a ị ủ n đ c chia cho 2. N u l , giá tr đ c thay th b i 3 ượ ế ẻ ị ượ ế ở n+1. Ch ng h n, n u giá tr ban đ u (t c đ i ẳ ạ ế ị ầ ứ ố s đ c truy n vào ố ượ ề sequence) b ng 3, thì k t qu là ta có dãy 3, 10, 5, 16, 8, 4, 2, 1. ằ ế ả Vì đôi khi n tăng và đôi khi gi m, nên s không có cách ch ng minh nào d th y ràng cu i cùng ả ẽ ứ ễ ấ ố n s đ t ẽ ạ đ n 1, hay ch ng trình s k t thúc. V i m t s giá tr đ c bi t c a ế ươ ẽ ế ớ ộ ố ị ặ ệ ủ n, ta có th ch ng minh đ c s k t ể ứ ượ ự ế thúc đó. Ch ng h n, n u giá tr kh i đ u là m t s lũy th a c a hai, thì giá tr c a ẳ ạ ế ị ở ầ ộ ố ừ ủ ị ủ n s luôn ch n qua ẽ ẵ m i l n l p, cho đ n khi ta thu đ c 1. Ví d tr c s k t thúc v i m t dãy nh v y v i giá tr ban đ u ỗ ầ ặ ế ượ ụ ướ ẽ ế ớ ộ ư ậ ớ ị ầ b ng 16. ằ
Ngoài nh ng giá tr đ c bi t, thì m t câu h i thú v là li u ta có th ch ng minh đ c r ng đo n ch ng ữ ị ặ ệ ộ ỏ ị ệ ể ứ ượ ằ ạ ươ trình trên có k t thúc v i ế ớ t t c ấ ả nh ng giá tr c a n hay không. Cho đ n gi , ch a ai có th ch ng minh ữ ị ủ ế ờ ư ể ứ
ho c bác b nó! B n hãy tìm thêm thông tin ặ ỏ ạ ở http://en.wikipedia.org/wiki/Collatz_conjecture. 7.3 B ng s li u ả ố ệ
M t trong nh ng công vi c thích h p v i dùng vòng l p, đó là phát sinh ra b ng s li u. Tr c khi máy ộ ữ ệ ợ ớ ặ ả ố ệ ướ tính tr nên ph bi n, m i ng i đã ph i tính tay các phép logarit, sin, cosin, và nh ng hàm toán h c ở ổ ế ọ ườ ả ữ ọ khác.
Đ đ n gi n hóa vi c này, sách toán th ng in kèm nh ng b ng dài li t kê giá tr các hàm nói trên. Vi c ể ơ ả ệ ườ ữ ả ệ ị ệ t o ra các b ng nh v y r t ch m và nhàm chán, và d m c ph i nhi u l i. ạ ả ư ậ ấ ậ ễ ắ ả ề ỗ
Khi máy tính xu t hi n, đã có nh ng ph n ng ban đ u ki u nh : “Đi u này th t tuy t! Gi ta có th ấ ệ ữ ả ứ ầ ể ư ề ậ ệ ờ ể dùng máy tính đ t o ra các b ng, vì v y s không có l i.” Đi u này tr nên (g n nh là) s th t nh ng ể ạ ả ậ ẽ ỗ ề ở ầ ư ự ậ ư v n ch a đ ng t m nhìn h n h p. Không lâu sau đó, máy tính và máy b túi đã xu t hi n tràn lan và ẫ ứ ự ầ ạ ẹ ỏ ấ ệ b ng s tr nên l i th i. ả ố ở ỗ ờ
Ừ ầ ư ậ ữ ấ ố ừ ả ể ị ầ ồ ự ệ , g n nh v y. Có nh ng phép tính mà máy tính l y con s t b ng đ có giá tr g n đúng, r i th c hi n tính toán nh m c i thi n k t qu g n đúng này. tr ng h p khác, có nh ng l i n m ngay b ng s , ằ ả ệ ế ả ầ Ở ườ ợ ữ ỗ ằ ở ả ố đ c bi t đ n nhi u nh t là b ng mà máy Intel Pentium đã dùng đ th c hi n phép chia v i s có d u ượ ế ế ề ấ ả ể ự ệ ớ ố ấ ph y đ ng. ẩ ộ
M c dù b ng loga không còn h u d ng nh x a, song nó v n dùng đ c làm ví d v tính l p. Ch ng ặ ả ữ ụ ư ư ẫ ượ ụ ề ặ ươ trình sau in ra m t dãy các s c t bên trái cùng v i giá tr logarit c a chúng c t ph i: ộ ố ở ộ ớ ị ủ ở ộ ả
double x = 1.0;
while (x < 10.0) {
System.out.println(x + " " + Math.log(x));
x = x + 1.0;
}
K t qu c a ch ng trình này là: ế ả ủ ươ
1.0 0.0
2.0 0.6931471805599453
3.0 1.0986122886681098
4.0 1.3862943611198906
5.0 1.6094379124341003
6.0 1.791759469228055
7.0 1.9459101490553132
8.0 2.0794415416798357
9.0 2.1972245773362196
Nhìn vào nh ng giá tr này, b n có th nói r ng ph ng th c ữ ị ạ ể ằ ươ ứ log này dùng c s nào? ơ ố Vì các lũy th a c a 2 r t quan tr ng trong ngành khoa h c máy tính, nên ta th ng mu n l y loga theo ừ ủ ấ ọ ọ ườ ố ấ c s 2. Đ tính toán, ta có th dùng bi u th c: ơ ố ể ể ể ứ
log2 x = loge x / loge 2
Hãy thay câu l nh ệ print b ng ằ
System.out.println(x + " " + Math.log(x) / Math.log(2.0)); đ cho ra ể
1.0 0.0
2.0 1.0
3.0 1.5849625007211563
4.0 2.0
5.0 2.321928094887362
6.0 2.584962500721156
7.0 2.807354922057604
8.0 3.0
9.0 3.1699250014423126
Có th th y r ng 1, 2, 4, và 8 là các lũy th a c a 2 vì các giá tr logarit c s 2 c a chúng đ u là nh ng s ể ấ ằ ừ ủ ị ơ ố ủ ề ữ ố nguyên. N u mu n tìm logarit c a nh ng lũy th a khác c a 2, ta có th s a ch ng trình trên thành: ế ố ủ ữ ừ ủ ể ử ươ
double x = 1.0;
while (x < 100.0) {
System.out.println(x + " " + Math.log(x) / Math.log(2.0)); x = x * 2.0;
}
Bây gi thay vì c ng thêm m t s v i ờ ộ ộ ố ớ x trong m i vòng l p (đi u này cho ra dãy c p s c ng), ta đem ỗ ặ ề ấ ố ộ
nhân m t giá tr v i ộ ị ớ x (thu đ c ượ c p s nhân ấ ố ). K t qu là: ế ả
1.0 0.0
2.0 1.0
4.0 2.0
8.0 3.0
16.0 4.0
32.0 5.0
64.0 6.0
B ng logarit có th không còn có ích n a, nh ng v i nhà khoa h c máy tính, vi c nh đ c các lũy th a ả ể ữ ư ớ ọ ệ ớ ượ ừ
c a hai nh t thi t có ích! Khi nào r nh r i, b n hãy ghi nh các lũy th a c a hai đ n t n ủ ấ ế ả ỗ ạ ớ ừ ủ ế ậ 65536 (t c là ứ 216).
7.4 B ng hai chi u ả ề
Trong m t b ng hai chi u, b n đ c giá tr đi m giao c t gi a m t hàng v i m t c t. B ng c u ch ng ộ ả ề ạ ọ ị ở ể ắ ữ ộ ớ ộ ộ ả ử ươ là m t ví d đi n hình. Gi s b n mu n in ra m t b ng tính nhân v i các giá tr t 1 đ n 6. ộ ụ ể ả ử ạ ố ộ ả ớ ị ừ ế
M t cách b t đ u n th a là vi t m t vòng l p đ in ra các b i s c a ộ ắ ầ ổ ỏ ế ộ ặ ể ộ ố ủ 2 trên cùng m t dòng. ộ int i = 1;
while (i <= 6) {
System.out.print(2*i + " ");
i = i + 1;
}
System.out.println("");
Dòng đ u tiên kh i t o m t bi n có tên là ầ ở ạ ộ ế i; nó đóng vai trò m t bi n đ m ho c ộ ế ế ặ bi n vòng l p ế ặ . Khi vòng l p đ c th c thi, giá tr c a ặ ượ ự ị ủ i tăng t 1 lên 6. Khi ừ i b ng 7, vòng l p k t thúc. M i l n l p, ch ng ằ ặ ế ỗ ầ ặ ươ
trình s in ra giá tr c a ẽ ị ủ 2*i, theo sau là ba d u cách. ấ
M t l n n a, d u ph y trong câu l nh ộ ầ ữ ấ ẩ ệ print ngăn không cho xu ng dòng. Sau khi vòng l p k t thúc, ố ặ ế l nh ệ print th hai b t đ u m t dòng m i. Vì ta dùng ứ ắ ầ ộ ớ System.out.print, nên toàn b k t qu đ c ghi ộ ế ả ượ trên m t dòng. ộ
Có nh ng môi tr ng mà k t qu t ữ ườ ế ả ừ print đ c l u l i mà ch a hi n th đ n khi kích ho t ượ ư ạ ư ể ị ế ạ println. N u ế ch ng trình k t thúc, mà b n quên kích ho t ươ ế ạ ạ println, có th b n s không bao gi th y đ c k t qu ể ạ ẽ ờ ấ ượ ế ả đ c l u l i này. ượ ư ạ
K t qu c a ch ng trình là: ế ả ủ ươ
2 4 6 8 10 12
M i vi c đ n gi ti n tri n t t. B c ti p theo là ọ ệ ế ờ ế ể ố ướ ế bao b cọ và khái quát hóa.
7.5 Bao b c và khái quát hóa ọ
Bao b c là quá trình đ t m t đo n mã l nh vào trong m t ph ng th c; vi c này cho phép ta t n d ng ọ ặ ộ ạ ệ ộ ươ ứ ệ ậ ụ đ c nh ng u đi m c a ph ng th c. Ta đã th y hai ví d v bao b c, khi ta vi t ượ ữ ư ể ủ ươ ứ ấ ụ ề ọ ế printParity ở ụ M c 4.3 và isSingleDigit ở ụ M c 6.7.
Khái quát hóa nghĩa là ch n l y m t đi u c th , nh công vi c in ra ọ ấ ộ ề ụ ể ư ệ các b i s c a 2, r i làm cho nó tr ộ ố ủ ồ ở thành khái quát h n, ch ng h n nh in ra các b i s c a m t s nguyên b t kì. ơ ẳ ạ ư ộ ố ủ ộ ố ấ
Ph ng th c sau đây bao b c đo n mã l nh nói trên r i khái quát hóa nó đ in ra ươ ứ ọ ạ ệ ồ ể các b i s c a ộ ố ủ n. public static void printMultiples(int n) {
int i = 1;
while (i <= 6) {
System.out.print(n*i + " ");
i = i + 1;
}
System.out.println("");
}
Đ bao b c, ta ch c n vi t thêm dòng th nh t, t c là khai báo tên, tham s , và ki u tr l i. Đ khái quát ể ọ ỉ ầ ế ứ ấ ứ ố ể ả ạ ể hóa, ta ch c n thay th giá tr ỉ ầ ế ị 2 b i tham s ở ố n.
N u ta kích ho t ph ng th c này v i đ i s b ng ế ạ ươ ứ ớ ố ố ằ 2, ta s nh n đ c k t qu gi ng nh tr c. V i đ i ẽ ậ ượ ế ả ố ư ướ ớ ố s b ng 3, k t qu s là: ố ằ ế ả ẽ
3 6 9 12 15 18
V i đ i s b ng 4, k t qu là: ớ ố ố ằ ế ả
4 8 12 16 20 24
Bây gi có th b n đã đoán đ c cách in m t b ng tính nhân ờ ể ạ ượ ộ ả b ng cách kích ho t ằ ạ printMultiples l p ặ
l i v i nh ng đ i s khác nhau. Th c ra, ta có th dùng m t vòng khác đ l p qua các hàng trong b ng: ạ ớ ữ ố ố ự ể ộ ể ặ ả int i = 1;
while (i <= 6) {
printMultiples(i);
i = i + 1;
}
Tr c h t, hãy l u ý s gi ng nhau c a vòng l p này v i vòng l p bên trong ướ ế ư ự ố ủ ặ ớ ặ printMultiples. T t c ấ ả nh ng gì ta đã làm ch là vi c thay l nh ữ ỉ ệ ệ print b ng m t l i kích ho t ph ng th c. ằ ộ ờ ạ ươ ứ K t qu c a ch ng trình này là ế ả ủ ươ
1 2 3 4 5 6
2 4 6 8 10 12
3 6 9 12 15 18
4 8 12 16 20 24
5 10 15 20 25 30
6 12 18 24 30 36
v n là m t b ng tính nhân (h i lôi thôi). N u b n không thích lôi thôi, thì Java s n có nh ng ph ng ố ộ ả ơ ế ạ ẵ ữ ươ th c giúp b n ki m soát ch t ch h i đ nh d ng c a k t qu ; song bây gi ta không đ c p đ n đi u này. ứ ạ ể ặ ẽ ơ ị ạ ủ ế ả ờ ề ậ ế ề
7.6 Ph ng th c và bao b c ươ ứ ọ
Ở ụ M c 3.5 tôi đã li t kê vài lý do mà ph ng th c tr nên có ích. Sau đây còn thêm m t s lý do khác: ệ ươ ứ ở ộ ố
•B ng cách đ t tên cho m t dãy các câu l nh, b n có th làm cho ch ng trình mình vi t tr nên d đ c ằ ặ ộ ệ ạ ể ươ ế ở ễ ọ và g l i h n. ỡ ỗ ơ
•Vi c chia m t ch ng trình dài thành nhi u ph ng th c cho phép b n phân chia các ph n c a ch ng ệ ộ ươ ề ươ ứ ạ ầ ủ ươ trình, ti n hành g l i chúng m t cách đ c l p, r i ghép l i thành t ng th . ế ỡ ỗ ộ ộ ậ ồ ạ ổ ể
•Ph ng th c cho phép c đ quy l n l p l i. ươ ứ ả ệ ẫ ặ ạ
•Các ph ng th c đ c thi t k t t thì th ng h u ích cho nhi u ch ng trình khác nhau. M t khi đã ươ ứ ượ ế ế ố ườ ữ ề ươ ộ vi t ra và g l i xong m t ph ng th c, b n có th tái s d ng nó. ế ỡ ỗ ộ ươ ứ ạ ể ử ụ
Đ bi u di n ti p kĩ thu t bao b c, ta hãy l y đo n mã l nh cu i m c tr c r i b c nó vào trong m t ể ể ễ ế ậ ọ ấ ạ ệ ở ố ụ ướ ồ ọ ộ ph ng th c: ươ ứ
public static void printMultTable() {
int i = 1;
while (i <= 6) {
printMultiples(i); i = i + 1;
}
}
Quá trình mà tôi hi n đang gi i thi u đ c g i là ệ ớ ệ ượ ọ bao b c và khái quát hóa ọ . Ta phát tri n mã l nh ể ệ b ng cách vi t riêng nh ng dòng l nh vào ằ ế ữ ệ main ho c vào ph ng th c khác. Khi mã l nh này th c hi n ặ ươ ứ ệ ự ệ đ c, ta l y l i nó r i b c vào m t ph ng th c. R i b n khái quát hóa ph ng th c b ng cách b sung ượ ấ ạ ồ ọ ộ ươ ứ ồ ạ ươ ứ ằ ổ các tham s . ố
Lúc m i l p trình, đôi khi b n không bi t cách chia ch ng trình thành các ph ng th c. Quy trình trên ớ ậ ạ ế ươ ươ ứ giúp b n thi t k trong khi l p trình. ạ ế ế ậ
7.7 Các bi n đ a ph ng ế ị ươ
Có th b n t h i b ng cách nào mà ta dùng đ c cùng m t bi n, ể ạ ự ỏ ằ ượ ộ ế i, c ả
trong printMultiples l nẫ printMultTable. Ch ng ph i nó s gây r c r i khi m t trong hai ph ng th c ẳ ả ẽ ắ ố ộ ươ ứ thay đ i giá tr c a bi n sao? ổ ị ủ ế
L i gi i đáp cho c hai câu h i trên đ u là không, ờ ả ả ỏ ề
vì i trong printMultiples và i trong printMultTable không ph i cùng m t bi n. Chúng có cùng tên g i, ả ộ ế ọ nh ng không tham chi u đ n cùng v trí l u tr , và vi c thay đ i m t bi n này s không nh h ng gì ư ế ế ị ư ữ ệ ổ ộ ế ẽ ả ưở t i bi n kia. ớ ế
Nh ng bi n đ c t o ra bên trong ph n đ nh nghĩa ph ng th c đ c g i là ữ ế ượ ạ ầ ị ươ ứ ượ ọ bi n đ a ph ng ế ị ươ , vì chúng ch t n t i bên trong ph ng th c đó. B n không th truy c p bi n đ a ph ng t ngoài ph ng ỉ ồ ạ ươ ứ ạ ể ậ ế ị ươ ừ ươ th c “ch ” c a nó, và b n có th tùy ý đ t nhi u bi n cùng tên, mi n là chúng không ph i trong cùng ứ ủ ủ ạ ể ặ ề ế ễ ả m t hàm. ộ
M c dù đi u này có th gây nh m l n, song có nh ng lí do thích đáng đ s d ng l i các tên g i. Ch ng ặ ề ể ầ ẫ ữ ể ử ụ ạ ọ ẳ h n, các tên ạ i, j và k th ng đ c dùng làm bi n l p. N u b n tránh dùng chúng trong m t ph ng th c ườ ượ ế ặ ế ạ ộ ươ ứ
ch vì b n đã dùng chúng n i khác, thì ch ng trình vi t ra s khó đ c h n. ỉ ạ ở ơ ươ ế ẽ ọ ơ
7.8 Nói thêm v khái quát hóa ề
Xét m t ví d khác v khái quát hóa. Hãy hình dung r ng b n ộ ụ ề ằ ạ mu n có m t ch ng trình đ in ra b ng ố ộ ươ ể ả
tính nhân v i kích th c b t kì, ch không ch 6 × ớ ướ ấ ứ ỉ 6. B n có th thêm m t tham s vào ạ ể ộ ố printMultTable: public static void printMultTable(int high) {
int i = 1;
while (i <= high) {
printMultiples(i);
i = i + 1;
}
}
Tôi đã thay giá tr 6 b i tham s ị ở ố high. N u tôi kích ho t ế ạ printMultTable v i đ i s 7, tôi s đ c: ớ ố ố ẽ ượ 1 2 3 4 5 6
2 4 6 8 10 12
3 6 9 12 15 18
4 8 12 16 20 24
5 10 15 20 25 30
6 12 18 24 30 36
7 14 21 28 35 42
Th này t m đ c, nh ng có l ta mu n nh n đ c m t b ng hình vuông h n ế ạ ượ ư ẽ ố ậ ượ ộ ả ơ (s c t và s hàng ph i ố ộ ố ả b ng nhau). Đ làm đi u này, ta thêm m t tham s n a vào ằ ể ề ộ ố ữ printMultiples đ c th hóa xem b ng có ể ụ ể ả bao nhiêu c t. ộ
Ta g i tham s này là ọ ố high, nh m cho th y các ph ng th c khác nhau hoàn toàn có th ch a nh ng ằ ấ ươ ứ ể ứ ữ
tham bi n có cùng tên (cũng nh các bi n đ a ph ng): ế ư ế ị ươ
public static void printMultiples(int n, int high) {
int i = 1;
while (i <= high) {
System.out.print(n*i + " ");
i = i + 1;
}
System.out.println("");
}
public static void printMultTable(int high) {
int i = 1;
while (i <= high) {
printMultiples(i, high);
i = i + 1;
}
}
L u ý r ng khi thêm m t tham s m i, ta ph i s a l i dòng đ u tiên, đ ng th i ta cũng ph i s a ch ư ằ ộ ố ớ ả ử ạ ầ ồ ờ ả ử ỗ ph ng th c đ c kích ho t trong ươ ứ ượ ạ printMultTable. Đúng nh d ki n, ch ng trình này phát sinh ra ư ự ế ươ
b ng vuông 7 × 7: ả
1 2 3 4 5 6 7
2 4 6 8 10 12 14
3 6 9 12 15 18 21
4 8 12 16 20 24 28
5 10 15 20 25 30 35
6 12 18 24 30 36 42
7 14 21 28 35 42 49
Khi b n khái quát quá m t ph ng th c theo cách thích h p, th ng b n s thu đ c ch ng trình v i ạ ộ ươ ứ ợ ườ ạ ẽ ượ ươ ớ
nh ng tính năng mà b n ch a l ng tr c. Ch ng h n, có th b n nh n th y r ng b ng nhân có tính đ i ữ ạ ư ườ ướ ẳ ạ ể ạ ậ ấ ằ ả ố x ng, vì ứ ab = ba, nên t t c nh ng con s trong b ng đ u xu t hi n l p hai l n. L ra b n có th ti t ấ ả ữ ố ả ề ấ ệ ặ ầ ẽ ạ ể ế ki m m c b ng cách ch ệ ự ằ ỉ in ra n a b ng thôi. Đ làm đi u này, ch c n thay đ i m t dòng l nh ử ả ể ề ỉ ầ ổ ộ ệ
trong printMultTable. Hãy s a l nh ử ệ
printMultiples(i, high);
thành
printMultiples(i, i);
và thu đ c ượ
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
Tôi s đ b n t hình dung c ch c a cách máy tính đã x lí trong tr ng h p này. ẽ ể ạ ự ơ ế ủ ử ườ ợ 7.9 Thu t ng ậ ữ
vòng l p: ặ
M t câu l nh đ c l p đi l p l i nhi u l n khi m t đi u ki n nào đó đ c th a mãn. ộ ệ ượ ặ ặ ạ ề ầ ộ ề ệ ượ ỏ vòng l p vô h n: ặ ạ
M t vòng l p có đi u ki n luôn luôn đúng. ộ ặ ề ệ
ph n thân: ầ
Nh ng câu l nh bên trong vòng l p. ữ ệ ặ
l p: ặ
M t l t ch y (th c thi) qua ph n thân vòng l p, bao g m c vi c đ nh giá đi u ki n. ộ ượ ạ ự ầ ặ ồ ả ệ ị ề ệ bao b c: ọ
Vi c phân chia m t ch ng trình l n, ph c t p thành nhi u thành ph n (nh ph ng th c) r i cô l p ệ ộ ươ ớ ứ ạ ề ầ ư ươ ứ ồ ậ riêng các thành ph n (ch ng h n, b ng cách dùng các bi n đ a ph ng). ầ ẳ ạ ằ ế ị ươ
bi n đ a ph ng: ế ị ươ
M t bi n đ c khai báo bên trong m t ph ng th c; bi n này ch t n t i trong ph ng th c đó. Nh ng ộ ế ượ ộ ươ ứ ế ỉ ồ ạ ươ ứ ữ bi n đ a ph ng đ u không truy c p đ c t ngoài ph ng th c c a nó, và không can thi p t i b t kì ế ị ươ ề ậ ượ ừ ươ ứ ủ ệ ớ ấ ph ng th c nào khác. ươ ứ
khái quát hóa:
Vi c thay th nh ng th c th m t cách không c n thi t (nh m t giá tr không đ i) b ng nh ng th ệ ế ữ ứ ụ ể ộ ầ ế ư ộ ị ổ ằ ữ ứ có tính khái quát thích h p (nh ng m t bi n ho c m t tham s ). Vi c khái quát hóa khi n cho mã l nh ợ ư ộ ế ặ ộ ố ệ ế ệ linh ho t h n, d s d ng l i h n, và đôi khi d vi t h n. ạ ơ ễ ử ụ ạ ơ ễ ế ơ
phát tri n ch ng trình: ể ươ
M t quá trình đ vi t nên nh ng ch ng trình máy tính. Cho đ n bây gi ta đã g p “phát tri n ộ ể ế ữ ươ ế ờ ặ ể tăng d n” và “bao b c và khái quát hóa”. ầ ọ
7.10 Bài t pậ
Bài t p 1 ậ Xét đo n mã l nh sau: ạ ệ
public static void main(String[] args) {
loop(10);
}
public static void loop(int n) {
int i = n;
while (i > 0) {
System.out.println(i);
if (i%2 == 0) {
i = i/2;
} else {
i = i+1;
}
}
}
1. Hãy k m t b ng đ ch ra giá tr c a các bi n ẻ ộ ả ể ỉ ị ủ ế i và n trong quá trình th c thi ự loop. B ng ch đ c phép ả ỉ ượ ch a m t c t cho m i bi n và m t hàng cho m i vòng l p. ứ ộ ộ ỗ ế ộ ỗ ặ
2. K t qu c a ch ng trình này là gì? ế ả ủ ươ
Bài t p 2 ậ Gi s b n có m t s , ả ử ạ ộ ố a, và b n mu n tính căn b c hai c a nó. M t cách làm đi u này là kh i ạ ố ậ ủ ộ ề ở đ u b ng m t ph ng đoán s l c v đáp s , ầ ằ ộ ỏ ơ ượ ề ố x0, và r i c i thi n ph ng đoán này theo công th c sau: ồ ả ệ ỏ ứ x1 =(x0 + a/x0) / 2
Ch ng h n, n u ta mu n tìm căn b c hai c a 9, và b t đ u v i ẳ ạ ế ố ậ ủ ắ ầ ớ x0 = 6, thì x1 =(6 + 9/6) /2 = 15/4 = 3.75, giá tr này đã sát h n. Ta có th l p l i quy trình này, dùng ị ơ ể ặ ạ x1 đ tính ra ể x2, và c nh v y. Trong tr ng ứ ư ậ ườ h p này, ợ x2 = 3.075 và x3 = 3.00091. Nh v y nó h i t r t nhanh v đáp s đúng (v n b ng 3). ư ậ ộ ụ ấ ề ố ố ằ
Hãy vi t m t ph ng th c có tên ế ộ ươ ứ squareRoot nh n vào tham s là m t ậ ố ộ double và tr l i m t giá tr x p ả ạ ộ ị ấ
x cho căn b c hai c a tham s đó, theo kĩ thu t tính nêu trên. B n không đ c phép dùng ỉ ậ ủ ố ậ ạ ượ Math.sqrt. V i giá tr ban đ u, b n nên l y ớ ị ầ ạ ấ a/2. Ph ng th c b n vi t c n ph i l p l i đ n khi nó đ t đ c hai giá ươ ứ ạ ế ầ ả ặ ạ ế ạ ượ tr c tính liên ti p ch sai khác nhau ch a đ n 0.0001; nói cách khác, là đ n khi giá tr tuy t đ i ị ướ ế ỉ ư ế ế ị ệ ố c aủ xn − xn−1 nh h n 0.0001. B n có th dùng ỏ ơ ạ ể Math.abs đ tính giá tr tuy t đ i này. ể ị ệ ố Bài t p 3 ậ Ở ậ Bài t p 9 ta đã vi t m t d ng đ quy c a ế ộ ạ ệ ủ power, trong đó nh n m t bi n double có ậ ộ ế tên x cùng m t bi n nguyên ộ ế n and r i tr l i ồ ả ạ xn. Bây gi hãy vi t m t ph ng th c l p đ th c hi n tính ờ ế ộ ươ ứ ặ ể ự ệ toán nh v y. ư ậ
Bài t p 4 ậ M cụ 6.8 có trình bày m t ph ng th c đ quy đ tính hàm giai th a. Hãy vi t m t d ng ộ ươ ứ ệ ể ừ ế ộ ạ
tính l p cho ặ factorial.
Bài t p 5 ậ M t cách đ tính ộ ể ex là dùng khai tri n chu i vô h n ể ỗ ạ
ex = 1 + x + x2 / 2! + x3 / 3! + x4 / 4! + …
N u bi n vòng l p có tên ế ế ặ i, thì s h ng th i s là ố ạ ứ ẽ xi / i!.
1. Hãy vi t m t ph ng th c có tên ế ộ ươ ứ myexp đ tính t ng c a ể ổ ủ n s h ng đ u tiên trong dãy này. B n có th ố ạ ầ ạ ể dùng ph ng th c ươ ứ factorial ở ụ M c 6.8 ho c dùng phiên b n tính l p nh bài t p tr c. ặ ả ặ ư ở ậ ướ 2. B n có th khi n ph ng th c này hi u qu h n nhi u n u nh n th y r ng m i l n l p, t s c a s ạ ể ế ươ ứ ệ ả ơ ề ế ậ ấ ằ ở ỗ ầ ặ ử ố ủ ố h ng thì đúng b ng t s c a s h ng li n tr c đó nhân v i ạ ằ ử ố ủ ố ạ ề ướ ớ x còn m u s thì đúng b ng m u c a s ẫ ố ằ ẫ ủ ố h ng tr c đó nhân v i ạ ướ ớ i. Hãy t n d ng k t qu c a quan sát này đ tránh dùng ậ ụ ế ả ủ ể
cả Math.pow l nẫ factorial, r i ki m tra r ng b n v n có th đ t đ c k t qu y h t. ồ ể ằ ạ ẫ ể ạ ượ ế ả ệ
3. Hãy vi t m t ph ng th c có tên ế ộ ươ ứ check nh n vào m t tham s , ậ ộ ố x, đ in ra giá tr ể ị
c aủ x, Math.exp(x) và myexp(x) cho các giá trị x khác nhau. K t qu ph i có d ng nh sau: ế ả ả ạ ư 1.0 2.708333333333333 2.718281828459045
G I Ý: b n có th dùng String Ợ ạ ể "\t" đ in ra m t d u tab gi a các c t trong b ng. ể ộ ấ ữ ộ ả
4. Hãy thay đ i s các s h ng trong chu i (chính là đ i s th hai mà ổ ố ố ạ ỗ ố ố ứ check g i đ n ử ế myexp) r i xem s ồ ự ả ưở ế ộ ủ ế ả ề ỉ ị ế ị ướ ợ ớ nh h ng đ n đ chính xác c a k t qu . Đi u ch nh giá tr này đ n khi giá tr c tính phù h p v i đáp s “đúng” khi ố x b ng 1. ằ
5. Hãy vi t m t vòng l p trong ế ộ ặ main đ kích ho t ể ạ check v i nh ng giá tr 0.1, 1.0, 10.0, và 100.0. Đ chính ớ ữ ị ộ xác c a k t qu s thay đ i th nào khi ủ ế ả ẽ ổ ế x bi n đ i? So sánh s ch s gi ng nhau thay vief hi u s gi a ế ổ ố ữ ố ố ệ ố ữ các giá tr đúng và giá tr c tính đ c. ị ị ướ ượ
6. Thêm vào m t vòng l p trong ộ ặ main nh m ki m tra ằ ể myexp v i các giá tr -0.1, -1.0, -10.0, và -100.0. Hãy ớ ị
nh n xét v đ chính xác. ậ ề ộ
Bài t p 6 ậ M t cách đ tính exp(−x ộ ể 2) là dùng khai tri n chu i vô h n ể ỗ ạ
exp(−x2) = 1 − x2 + x4/2 − x6/6 + …
Nói cách khác, ta c n ph i c ng các s h ng l i, trong đó s h ng th i b ng (−1) ầ ả ộ ố ạ ạ ố ạ ứ ằ i x2i /i!. Hãy vi t m t ế ộ ph ng th c có tên ươ ứ gauss nh n vào các đ i s ậ ố ố x và n r i tr l i t ng c a ồ ả ạ ổ ủ n s h ng đ u tiên trong chu i ố ạ ầ ỗ này. B n không đ c dùng c ạ ượ ả factorial l nẫ pow.
Ch ng 8: Chu i kí ươ ỗ tự
8.1 Kí tự
Trong Java cũng nh các ngôn ng h ng đ i t ng khác thì ư ữ ướ ố ượ đ i t ng ố ượ là t p h p nh ng d li u có ậ ợ ữ ữ ệ liên quan, cùng v i m t t p các ph ng th c. Nh ng ph ng th c nafyhoajt đ ng trên đ i t ng k ớ ộ ậ ươ ứ ữ ươ ứ ộ ố ượ ể trên, th c hi n tính toán và đôi lúc thay đ i d li u trong đ i t ng đó. ự ệ ổ ữ ệ ố ượ
String (chu i kí t ) là các đ i t ng, b i v y b n có th h i “Có d li u nào đ c ch a trong m t đ i ỗ ự ố ượ ở ậ ạ ể ỏ ữ ệ ượ ứ ộ ố t ng ượ String?” và “Có nh ng ph ng th c nào mà ta có th kích ho t đ c t đ i t ng ữ ươ ứ ể ạ ượ ừ ố ượ String?” Nh ng ữ thành ph n trong m t đ i t ng ầ ộ ố ượ String là các ch cái, hay t ng quát h n, là nh ng kí t . Không ph i ữ ổ ơ ữ ự ả m i kí t đ u là ch cái; còn nh ng kí t là ch s , kí hi u, và các th khác. Đ đ n gi n tôi s g i chúng ọ ự ề ữ ữ ự ữ ố ệ ứ ể ơ ả ẽ ọ đ u là các ch cái. Có nhi u ph ng th c khác nhau, nh ng trong sách này ch dùng m t s ít. Các ề ữ ề ươ ứ ư ỉ ộ ố ph ng th c còn l i đ c ch d n ươ ứ ạ ượ ỉ ẫ
ởhttp://download.oracle.com/javase/6/docs/api/java/lang/String.html.
Ph ng th c đ u tiên mà ta xét đ n là ươ ứ ầ ế charAt; ph ng th c này cho phép b n k t xu t nh ng ch cái t ươ ứ ạ ế ấ ữ ữ ừ m t ộ String. char là ki u bi n dùng đ c đ l u tr t ng kí t riêng l (trái ng c l i v i m t chu i các ể ế ượ ể ư ữ ừ ự ẻ ượ ạ ớ ộ ỗ kí t ). ự
char cũng ho t đ ng nh các ki u d li u khác ta đã g p: ạ ộ ư ể ữ ệ ặ
char ltr = 'c';
if (ltr == 'c') {
System.out.println(ltr);
}
Nh ng giá tr c a kí t đ u xu t hi n trong c p d u nháy đ n, nh ữ ị ủ ự ề ấ ệ ặ ấ ơ ư ’c’. Khác v i giá tr c a chu i (xu t ớ ị ủ ỗ ấ hi n gi a c p d u nháy kép), các giá tr kí t ch có th ch a m t ch cái ho c m t kí hi u. ệ ữ ặ ấ ị ự ỉ ể ứ ộ ữ ặ ộ ệ
Sau đây là cách dùng ph ng th c ươ ứ charAt:
String fruit = "banana";
char letter = fruit.charAt(1);
System.out.println(letter);
fruit.charAt() có nghĩa r ng tôi đang kích ho t ph ng th c ằ ạ ươ ứ charAt lên đ i t ng có tên ố ượ fruit. Tôi đang truy n đ i s ề ố ố 1 vào ph ng th c này, t c là tôi đang mu n bi t ch cái đ u tiên c a chu i là gì. K t qu ươ ứ ứ ố ế ữ ầ ủ ỗ ế ả
là m t kí t , và đ c l u vào trong m t ộ ự ượ ư ộ char có tên letter. Khi tôi in ra giá tr c a ị ủ letter, tôi b b t ng : ị ấ ờ a
a không ph i là ch cái đ u tiên c a ả ữ ầ ủ "banana". Tr khi b n nghiên c u khoa h c máy tính. Vì nh ng lí ừ ạ ứ ọ ữ do kĩ thu t mà gi i khoa h c máy tính đ u đ m t s không. Ch cái th 0 c a ậ ớ ọ ề ế ừ ố ữ ứ ủ "banana" là chữ b. Ch ữ cái th 1 là ứ a và th 2 là ứ n.
N u b n mu n bi t ch cái th 0 c a m t chu i, b n ph i truy n tham s là 0: ế ạ ố ế ữ ứ ủ ộ ỗ ạ ả ề ố char letter = fruit.charAt(0);
8.2 Length
Ph ng th c ti p theo đ i v i ươ ứ ế ố ớ String mà ta xét đ n là ế length, v n tr l i s kí t có trong chu i. Ch ng ố ả ạ ố ự ỗ ẳ
h n: ạ
int length = fruit.length();
length không nh n đ i s truy n vào, và tr l i m t s nguyên, trong tr ng h p này b ng 6. L u ý r ng ậ ố ố ề ả ạ ộ ố ườ ợ ằ ư ằ vi c có m t bi n trùng tên v i ph ng th c là hoàn toàn h p l (m c dù đi u này có th gây nh m l n ệ ộ ế ớ ươ ứ ợ ệ ặ ề ể ầ ẫ đ i v i ng i đ c mã l nh). ố ớ ườ ọ ệ
Đ tìm ch cái cu i cùng trong chu i, b n có th b xui khi n đ th theo cách làm sau: ể ữ ố ỗ ạ ể ị ế ể ử int length = fruit.length();
char last = fruit.charAt(length); // SAI!!
Cách này không có tác d ng. Lý do là không có ch cái th 6 nào trong ụ ữ ứ "banana". Vì ta đã b t đ u đ m ắ ầ ế t 0, nên sáu ch cái trong chu i đ c đ m t 0 t i 5. Đ l y ch cái cu i cùng, ta ph i tr ừ ữ ỗ ượ ế ừ ớ ể ấ ữ ố ả ừ length đi
m t. ộ
int length = fruit.length();
char last = fruit.charAt(length-1);
8.3 Duy t chu i ệ ỗ
M t công vi c th ng làm v i m t chu i là b t đ u t đi m đ u c a chu i, l n l t ch n t ng kí t , ộ ệ ườ ớ ộ ỗ ắ ầ ừ ể ầ ủ ỗ ầ ượ ọ ừ ự th c hi n m t s thao tác đ i v i ch cái đó, và công vi c đ c ti p di n cho các ch cái còn l i đ n h t ự ệ ộ ố ố ớ ữ ệ ượ ế ễ ữ ạ ế ế chu i. Ki u x lý nh th này đ c g i là ỗ ể ử ư ế ượ ọ duy t ệ . M t cách t nhiên đ th c hi n vi c duy t là dùng ộ ự ể ự ệ ệ ệ
vòng l pặ while:
int index = 0;
while (index < fruit.length()) {
char letter = fruit.charAt(index);
System.out.println(letter);
index = index + 1;
}
Vòng l p này đ duy t chu i và hi n th t ng ch cái trên m t dòng riêng. L u ý đi u ki n l p là ặ ể ệ ỗ ể ị ừ ữ ộ ư ề ệ ặ index < fruit.length(), nghĩa là khi index b ng v i chi u dài c a chu i, thì đi u ki n b vi ph m, và ph n ằ ớ ề ủ ỗ ề ệ ị ạ ầ thân c a vòng l p không đ c th c hi n. Kí t cu i cùng đ c truy c p đ n s t ng ng v i ch ủ ặ ượ ự ệ ự ố ượ ậ ế ẽ ươ ứ ớ ỉ số fruit.length()-1.
Tên c a bi n vòng l p là ủ ế ặ index (có nghĩa là “ch s ”). M t ỉ ố ộ ch sỉ ố là m t bi n hay giá tr đ c dùng đ ch ộ ế ị ượ ể ỉ đ nh m t thành viên c a m t t p h p đ c x p th t , trong tr ng h p này là chu i các kí t . Ch s có ị ộ ủ ộ ậ ợ ượ ế ứ ự ườ ợ ỗ ự ỉ ố
nhi m v ch đ nh thành viên nào b n c n bi t (vì v y mà nó có tên “ch s ”). ệ ụ ỉ ị ạ ầ ế ậ ỉ ố
8.4 L i th c thi ỗ ự
Tr v M c ở ề ụ 1.3.2 tôi đã nói t i các l i th c thi, nh ng l i không xu t hi n đ n t n khi ch ng trình b t ớ ỗ ự ữ ỗ ấ ệ ế ậ ươ ắ đ u ch n. Trong Java, nh ng l i th c thi đ c g i là các ầ ạ ữ ỗ ự ượ ọ bi t l ệ ệ.
Có th b n không th y nhi u l i th c thi, song vì ta ch a th c hi n nhi u thao tác có kh năng gây nên ể ạ ấ ề ỗ ự ư ự ệ ề ả nh ng l i lo i này. Và bây gi ta s gây l i. N u b n dùng ph ng th c ữ ỗ ạ ờ ẽ ỗ ế ạ ươ ứ charAt r i cung c p m t ch s ồ ấ ộ ỉ ố là s âm ho c l n h n ố ặ ớ ơ length-1, Java sẽ phát ra m t bi t l . B n có th hình dung vi c “phát” bi t l ộ ệ ệ ạ ể ệ ệ ệ cũng nh phát ra m t c n gi n d . ư ộ ơ ậ ữ
Khi đi u này x y đ n, Java in ra m t thông báo l i có ghi ki u bi t l và m t ề ả ế ộ ỗ ể ệ ệ ộ l n v t ngăn x p ầ ế ế , trong đó có bi u th nh ng ph ng th c đang ho t đ ng khi có bi t l x y ra. Sau đây là m t ví d : ể ị ữ ươ ứ ạ ộ ệ ệ ả ộ ụ
public class BadString {
public static void main(String[] args) {
processWord("banana");
}
public static void processWord(String s) {
char c = getLastLetter(s);
System.out.println(c);
}
public static char getLastLetter(String s) {
int index = s.length(); // SAI!
char c = s.charAt(index);
return c;
}
}
L u ý r ng l i n m trong ư ằ ỗ ằ getLastLetter: ch s c a kí t cu i cùng đáng ra ph i là ỉ ố ủ ự ố ả s.length()-1. Sau đây là
k t qu b n thu đ c: ế ả ạ ượ
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 6
at java.lang.String.charAt(String.java:694)
at BadString.getLastLetter(BadString.java:24)
at BadString.processWord(BadString.java:18)
at BadString.main(BadString.java:14)
Sau đó ch ng trình k t thúc. L n v t ngăn x p này có th khó đ c, song nó ch a đ ng r t nhi u thông ươ ế ầ ế ế ể ọ ứ ự ấ ề tin.
8.5 Đ c tài li u ọ ệ
N u b n truy c p đ n ế ạ ậ ế http://download.oracle.com/javase/6/docs/api/java/lang/String.html và kích
chu t vào ộ charAt, b n s xem đ c tài li u sau đây (ho c v i n i dung t ng t ): ạ ẽ ượ ệ ặ ớ ộ ươ ự public char charAt(int index)
Returns the char value at the specified index. An index ranges from 0 to length() - 1. The first char value of the sequence is at index 0, the next at index 1, and so on, as for array indexing.
Parameters: index - the index of the char value.
Returns: the char value at the specified index of this string. The first char value is at index 0.
Throws: IndexOutOfBoundsException - if the index argument is
negative or not less than the length of this string.
Dòng đ u tiên là ầ nguyên m uẫ c a ph ng th c, có nhi m v quy đ nh tên c a ph ng th c, ki u d ủ ươ ứ ệ ụ ị ủ ươ ứ ể ữ li u c a các tham s cũng nh ki u tr l i. ệ ủ ố ư ể ả ạ
Dòng ti p theo miêu t nh ng công vi c mà ph ng th c th c hi n. Các dòng sau đó gi i thích các tham ế ả ữ ệ ươ ứ ự ệ ả s và giá tr tr l i. Trong tr ng h p này, vi c gi i thích là quá th a, nh ng tài li u luôn đ c thi t k ố ị ả ạ ườ ợ ệ ả ừ ư ệ ượ ế ế đ phù h p m t d ng m u tiêu chu n. Còn dòng cu i cùng mô t các bi t l mà ph ng th c này có th ể ợ ộ ạ ẫ ẩ ố ả ệ ệ ươ ứ ể phát ra.
Có l b n s m t chút th i gian đ làm quen v i ki u tài li u th này, nh ng th i gian công s c b ra ẽ ạ ẽ ấ ờ ể ớ ể ệ ế ư ờ ứ ỏ cũng đáng.
8.6 Ph ng th c ươ ứ indexOf
indexOf là phép ngh ch đ o c a ị ả ủ charAt: charAt nh n vào m t ch s r i tr l i kí t v trí ch s ậ ộ ỉ ố ồ ả ạ ự ở ị ỉ ố đó; indexOf nh n m t kí t r i tìm ch s mà kí t đó xu t hi n. ậ ộ ự ồ ỉ ố ự ấ ệ
charAt th t b i n u ch s n m ngoài ph m vi chu i, khi đó ph ng th c này s phát bi t ấ ạ ế ỉ ố ằ ạ ỗ ươ ứ ẽ ệ
l . ệ indexOf th t b i n u kí t không có m t trong chu i, và tr l i giá tr ấ ạ ế ự ặ ỗ ả ạ ị -1.
String fruit = "banana";
int index = fruit.indexOf('a');
Đo n mã l nh này tìm ch s c a ch cái ạ ệ ỉ ố ủ ữ ’a’ trong chu i. V i tr ng h p này, ch cái nêu trên xu t hi n ỗ ớ ườ ợ ữ ấ ệ ba l n, nên ta ch a th y ngay r ng ầ ư ấ ằ indexOf nên làm gì. Nh ng theo tài li u, thì ph ng th c này s tr ư ệ ươ ứ ẽ ả l i ch s c a l n xu t hi n ạ ỉ ố ủ ầ ấ ệ đ u tiên ầ .
Đ tìm các l n xu t hi n ti p theo, còn có m t d ng khác c a ể ầ ấ ệ ế ộ ạ ủ indexOf. Nó nh n vào m t đ i s th hai ậ ộ ố ố ứ quy đ nh xem c n b t đ u tìm ki m t v trí nào trong chu i. Đây là m t d ng quá t i toán t , đ bi t ị ầ ắ ầ ế ừ ị ỗ ộ ạ ả ử ể ế thêm chi ti t, b n hãy xem M c ế ạ ụ 6.4.
N u ta kích ho t: ế ạ
int index = fruit.indexOf('a', 2);
nó s b t đ u ch cái s hai (ch ẽ ắ ầ ở ữ ố ữ n đ u tiên) r i tìm ch ầ ồ ữ a th hai, v n có ch s là 3. N u tình c ch ứ ố ỉ ố ế ờ ữ
cái đó xu t hi n ngay ch s kh i đ u, thì câu tr l i chính là ch s đ u này. B i v y ấ ệ ở ỉ ố ở ầ ả ờ ỉ ố ầ ở ậ int index = fruit.indexOf('a', 5);
s tr l i 5. ẽ ả ạ
8.7 L p quay vòng và đ m ặ ế
Ch ng trình d i đây đ m s l n xu t hi n c a ch ươ ướ ế ố ầ ấ ệ ủ ữ ’a’ trong m t chu i: ộ ỗ
String fruit = "banana";
int length = fruit.length();
int count = 0;
int index = 0;
while (index < length) {
if (fruit.charAt(index) == 'a') {
count = count + 1;
}
index = index + 1;
}
System.out.println(count);
Ch ng trình này cho th y m t cách vi t quen tay thông d ng, đó là m t ươ ấ ộ ế ụ ộ bi n đ m ế ế . Bi nế count đ c ượ kh i t o b ng không và sau đó tăng thêm m t ng v i m i l n ta tìm th y m t ch ở ạ ằ ộ ứ ớ ỗ ầ ấ ộ ữ ’a’. Vi cệ tăng ở đây là ch tăng thêm m t đ n v ; nó ng c l i v i thao tác ỉ ộ ơ ị ượ ạ ớ gi mả . Khi ta thoát kh i vòng l p, ỏ ặ count s ch a ẽ ứ
k t qu , đó là t ng s các ch a. ế ả ổ ố ữ
8.8 Các toán t tăng và gi m ử ả
Tăng và gi m là nh ng thao tác thông d ng đ n n i Java có nh ng toán t riêng cho chúng. Toán t ả ữ ụ ế ỗ ữ ử ử + + c ng thêm m t vào giá tr hi n th i c a m t ộ ộ ị ệ ờ ủ ộ int hay char. -- thì tr đi m t. Hai toán t trên đ u không ừ ộ ử ề có tác d ng đ i v i ụ ố ớ double, boolean hay String.
V khía c nh kĩ thu t, s hoàn toàn h p l n u ta tăng m t bi n r i đ ng th i s d ng nó trong m t ề ạ ậ ẽ ợ ệ ế ộ ế ồ ồ ờ ử ụ ộ bi u th c. Ch ng h n, b n có th th y l nh ki u nh sau: ể ứ ẳ ạ ạ ể ấ ệ ể ư
System.out.println(i++);
Nhìn vào câu l nh này, th t không rõ là li u vi c tăng s ti n hành tr c hay sau khi giá tr đ c in ra. ệ ậ ệ ệ ẽ ế ướ ị ượ B i vì nh ng bi u th c th này có xu h ng gây nh m l n, tôi khuyên b n nên h n ch s d ng chúng. ở ữ ể ứ ế ướ ầ ẫ ạ ạ ế ử ụ Th m chí, đ h n ch h n n a, tôi s không nói cho b n bi t k t qu b ng bao nhiêu. N u th c s ậ ể ạ ế ơ ữ ẽ ạ ế ế ả ằ ế ự ự mu n bi t, b n có th th xem. ố ế ạ ể ử
B ng cách dùng toán t tăng, ta có th vi t l i mã l nh đ m ch :\ ằ ử ể ế ạ ệ ế ữ
int index = 0;
while (index < length) {
if (fruit.charAt(index) == 'a') {
count++;
}
index++;
}
M t l i sai th ng g p là vi t l nh ki u nh sau: ộ ỗ ườ ặ ế ệ ể ư
index = index++; // SAI!!
Tuy nhiên, cách này l i h p l v m t cú pháp, nên trình biên d ch s không c nh báo b n. Hi u ng c a ạ ợ ệ ề ặ ị ẽ ả ạ ệ ứ ủ l nh này là gi nguyên giá tr c a ệ ữ ị ủ index. Đây th ng là m t l i khó tìm ra. ườ ộ ỗ
Hãy nh , b n có th vi t ớ ạ ể ế index = index+1, hay index++, nh ng đ ng tr n l n hai cách vi t này. ư ừ ộ ẫ ế 8.9 String có tính không đ i ổ
Nh đã đ c tài li u v các ph ng th c c a ư ọ ệ ề ươ ứ ủ String, có th b n phát hi n ra hai ph ng ể ạ ệ ươ th cứ toUpperCase và toLowerCase. Hai ph ng th c này th ng gây nh m l n, vì chúng có tên g i nghe ươ ứ ườ ầ ẫ ọ nh th chúng có tác d ng thay đ i chu i hi n có. Song th c ra, ch ng có ph ng th c nào nói chung và ư ể ụ ổ ỗ ệ ự ẳ ươ ứ hai ph ng th c này nói riêng, có th thay đ i đ c chu i, vì chu i có ươ ứ ể ổ ượ ỗ ỗ tính không đ i ổ .
Khi b n kích ho t ạ ạ toUpperCase đ i v i m t ố ớ ộ String, b n s thu đ c m t ạ ẽ ượ ộ String m i ớ làm k t qu tr l i. ế ả ả ạ
Ch ng h n: ẳ ạ
String name = "Alan Turing";
String upperName = name.toUpperCase();
Sau khi dòng l nh th hai đ c th c thi, ệ ứ ượ ự upperName s ch a giá tr ẽ ứ ị "ALAN TURING", còn name v n ẫ
ch aứ "Alan Turing".
8.10 String có tính không so sánh đ c ượ
Ta th ng c n so sánh hai chu i đ xem chúng có gi ng nhau không, hay chu i nào s x p tr c theo ườ ầ ỗ ể ố ỗ ẽ ế ướ th t b ng ch cái. Th t tuy t n u ta s d ng đ c các toán t so sánh nh ứ ự ả ữ ậ ệ ế ử ụ ượ ử ư == và >, song ta không th ể làm v y. ậ
Đ so sánh các ể String, ta ph i dùng các ph ng th c ả ươ ứ equals và compareTo. Ch ng h n: ẳ ạ String name1 = "Alan Turing";
String name2 = "Ada Lovelace";
if (name1.equals (name2)) {
System.out.println("hai tên này là một.");
}
int flag = name1.compareTo (name2);
if (flag == 0) {
System.out.println("Hai tên gọi này là một.");
} else if (flag < 0) {
System.out.println("tên 1 xếp trước tên 2.");
} else if (flag > 0) {
System.out.println("tên 2 xếp trước tên 1.");
}
Cú pháp đây h i kì qu c. Đ so sánh hai ở ơ ặ ể String, b n ph i kích ho t m t ph ng th c lên m t chu i ạ ả ạ ộ ươ ứ ộ ỗ r i truy n chu i còn l i làm tham s . ồ ề ỗ ạ ố
Giá tr tr v t ị ả ề ừ equals th t d hi u; ậ ễ ể true n u hai chu i có ch a cùng các kí t , và ế ỗ ứ ự false trong tr ng h p ườ ợ còn l i. ạ
Giá tr tr v t ị ả ề ừ compareTo l i kì qu c. Đó là kho ng cách gi a hai ch cái đ u tiên có s khác bi t hai ạ ặ ả ữ ữ ầ ự ệ ở chu i. N u hai chu i b ng nhau thì kho ng cách này b ng 0. N u chu i th nh t (chu i mà ta kích ho t ỗ ế ỗ ằ ả ằ ế ỗ ứ ấ ỗ ạ ph ng th c lên) đ ng tr c theo th t b ng ch cái, thì kho ng cách này có giá tr âm. Ng c l i, ươ ứ ứ ướ ứ ự ả ữ ả ị ượ ạ kho ng cách có giá tr d ng. Trong tr ng h p này, giá tr tr l i b ng 8, vì ch cái th hai c a “Ada” đi ả ị ươ ườ ợ ị ả ạ ằ ữ ứ ủ tr c ch cái th hai c a “Alan” là 8 v trí. ướ ữ ứ ủ ị
Đ tr n v n, tôi cũng nói th t r ng vi c dùng toán t ể ọ ẹ ậ ằ ệ ử == đ i v i các ố ớ Strings là h p l ợ ệ nh ng ít khi ư đúng
đ nắ . Tôi s gi i thích lí do trong M c ẽ ả ụ 13.4; song bây gi thì ch a. ờ ư
8.11 Thu t ng ậ ữ
đ i t ng: ố ượ
M t t p h p các d li u có liên quan cùng v i m t t p các ph ng th c ho t đ ng v i nó. Các đ i ộ ậ ợ ữ ệ ớ ộ ậ ươ ứ ạ ộ ớ ố t ng mà ta dùng cho đ n gi g m có ượ ế ờ ồ String, Bug, Rock, và nh ng đ i t ng khác trong ữ ố ượ GridWorld.
ch s : ỉ ố
M t bi n hay giá tr đ c dùng đ ch n m t trong các thành viên (ph n t ) c a m t t p h p đ c x p ộ ế ị ượ ể ọ ộ ầ ử ủ ộ ậ ợ ượ ế th t , nh ch n kí t t m t chu i. ứ ự ư ọ ự ừ ộ ỗ
bi t l : ệ ệ
M t l i khi th c thi ch ng trình. ộ ỗ ự ươ
phát:
Gây nên m t bi t l . ộ ệ ệ
l n v t ngăn x p: ầ ế ế
M t b n báo cáo cho th y tr ng thái ch ng trình khi có bi t l x y ra.occurs. ộ ả ấ ạ ươ ệ ệ ả
nguyên m u: ẫ
Dòng đ u tiên c a m t ph ng th c, trong đó quy đ nh tên, các tham s và ki u tr l i. ầ ủ ộ ươ ứ ị ố ể ả ạ duy t: ệ
Vi c l p qua t t c m i ph n t c a m t t p h p nh m th c hi n m t công vi c t ng t đ i v i t ng ệ ặ ấ ả ọ ầ ử ủ ộ ậ ợ ằ ự ệ ộ ệ ươ ự ố ớ ừ ph n t . ầ ử
bi n đ m: ế ế
M t bi n dùng đ đ m th gì đó; bi n này th ng đ c kh i t o b ng không sau đó tăng thêm. ộ ế ể ế ứ ế ườ ượ ở ạ ằ tăng:
Vi c tăng giá tr c a bi n thêm m t đ n v . Toán t tăng trong Java là ệ ị ủ ế ộ ơ ị ử ++.
gi m: ả
Vi c gi m giá tr c a bi n thêm đi đ n v . Toán t gi m trong Java là ệ ả ị ủ ế ơ ị ử ả --.
8.12 Bài t pậ
Bài t p 1 ậ Hãy vi t m t ph ng th c nh n vào m t ế ộ ươ ứ ậ ộ String làm đ i s r i in t t c các ch cái theo ố ố ồ ấ ả ữ chi u ng c l i trên cùng m t dòng. ề ượ ạ ộ
Bài t p 2 ậ Hãy đ cọ n i dung l n v t ngăn x p M c ộ ầ ế ế ở ụ 8.4 r i tr l i nh ng câu h i sau: ồ ả ờ ữ ỏ • Nh ng lo i bi t l nào đã x y ra, và nh ng bi t l này đ c đ nh nghĩa trong các gói (package) nào? ữ ạ ệ ệ ả ữ ệ ệ ượ ị • Giá tr nào c a ch s gây nên bi t l ? ị ủ ỉ ố ệ ệ
• Ph ng th c nào phát ra bi t l , và ph ng th c đó đ c đ nh nghĩa đâu? ươ ứ ệ ệ ươ ứ ượ ị ở
• Ph ng th c nào kích ho t ươ ứ ạ charAt?
• Trong BadString.java, charAt đ c kích ho t t i dòng s m y? ượ ạ ạ ố ấ
Bài t p 3 ậ Hãy bao b c đo n mã M c ọ ạ ở ụ 8.7 vào m t ph ng th c có tên ộ ươ ứ countLetters, sau đó khái quát hoá sao cho nó ch p nh n các đ i s là chu i và ch cái c n đ m. Ti p theo, vi t l i ph ng th c sao ấ ậ ố ố ỗ ữ ầ ế ế ế ạ ươ ứ cho nó s d ng ử ụ indexOf đ đ nh v các ch a, thay vì ki m tra t ng ch cái m t. ể ị ị ữ ể ừ ữ ộ
Bài t p 4 ậ M c đích c a bài t p này là ôn l i phép bao b c và khái quát hoá. ụ ủ ậ ạ ọ
1. Hãy bao b c đo n mã l nh sau, chuy n đ i nó thành m t ph ng th c nh n vào đ i s là m t String ọ ạ ệ ể ổ ộ ươ ứ ậ ố ố ộ r i tr l i giá tr cu i cùng c a ồ ả ạ ị ố ủ count.
2. Mô t ng n g n công d ng c a ph ng th c v a l p nên (mà không đi vào chi ti t các b c th c hi n ả ắ ọ ụ ủ ươ ứ ừ ậ ế ướ ự ệ nh th nào). ư ế
3. Bây gi khi b n đã khái quát hoá đ mã l nh ho t đ ng đ c v i chu i b t kì r i, b n còn có th khái ờ ạ ể ệ ạ ộ ượ ớ ỗ ấ ồ ạ ể
quát hoá theo cách nào n a? ữ
String s = "((3 + 7) * 2)";
int len = s.length();
int i = 0;
int count = 0;
while (i < len) {
char c = s.charAt(i);
if (c == '(') {
count = count + 1;
} else if (c == ')') {
count = count - 1;
}
i = i + 1;
}
System.out.println(count);
Bài t p 5 ậ M c đích c a bài t p này là khám phá nh ng ki u d li u trong Java và đi n vào m t s ụ ủ ậ ữ ể ữ ệ ề ộ ố thông tin chi ti t ch a đ c đ c p đ n trong ch ng này. ế ư ượ ề ậ ế ươ
1. Hãy t o nên m t ch ng trình m i có tên ạ ộ ươ ớ Test.java r i vi t m t ph ng th c ồ ế ộ ươ ứ main có ch a nh ng bi u ứ ữ ể th c có k t h p nhi u ki u d li u b ng toán t ứ ế ợ ề ể ữ ệ ằ ử +. Ch ng h n, đi u gì s x y ra n u b n “c ng” ẳ ạ ề ẽ ả ế ạ ộ m t ộ String và m t ộ char? Li u nó có th c hi n tính t ng hay k t n i? Ki u c a k t qu s là gì? (B n xác ệ ự ệ ổ ế ố ể ủ ế ả ẽ ạ đ nh đ c ki u c a k t qu nh th nào?) ị ượ ể ủ ế ả ư ế
2. Hãy sao chép l i và m r ng b ng d i đây r i đi n vào nó. Trong t ng ô giao c t gi a hai ki u d li u, ạ ở ộ ả ướ ồ ề ừ ắ ữ ể ữ ệ b n c n ph i xác đ nh xem li u có h p l n u dùng toán t ạ ầ ả ị ệ ợ ệ ế ử + v i nh ng ki u này không, phép toán nào ớ ữ ể
đ c th c hi n (c ng hay k t n i), và ki u k t qu s là gì. ượ ự ệ ộ ế ố ể ế ả ẽ
boolean char int String
boolean
char
int
String
3. Hãy t ng t ng xem các nhà thi t k nên ngôn ng Java đã l a ch n th nào khi h đi n vào b ng ưở ượ ế ế ữ ự ọ ế ọ ề ả trên. Trong s các ô đi n, có bao nhiêu ô d ng nh là l a ch n ch c ch n? Có bao nhiêu ô d ng nh ố ề ườ ư ự ọ ắ ắ ườ ư là l a ch n tuỳ ý mà có vài ph ng án t t nh nhau? Có bao nhiêu ô có v còn ch a đ ng v n đ ? ự ọ ươ ố ư ẻ ứ ự ấ ề
4. Sau đây là m t câu đ : thông th ng, câu l nh ộ ố ườ ệ x++ đúng b ng ằ x = x + 1. Nh ng n u ư ế x là m t ộ char, thì nó s không còn đúng! Trong tr ng h p này, ẽ ườ ợ x++ là h p l , nh ng ợ ệ ư x = x + 1 s gây ra l i. Hãy th l i và ẽ ỗ ử ạ xem thông báo l i là gì, và sau đó xem li u b n có th hình dung đ c đi u gì đang di n ra không. ỗ ệ ạ ể ượ ề ễ Bài t p 6 ậ K t qu c a ch ng trình d i đây là gì? B ng m t câu, hãy mô t xem ế ả ủ ươ ướ ằ ộ ả mystery làm gì (ch ứ
không ph i các b c th c hi n ra sao). ả ướ ự ệ
public class Mystery {
public static String mystery(String s) {
int i = s.length() - 1;
String total = "";
while (i >= 0 ) {
char ch = s.charAt(i);
System.out.println(i + " " + ch);
total = total + ch;
i--;
}
return total;
}
public static void main(String[] args) {
System.out.println(mystery("Allen"));
}
}
Bài t p 7 ậ M t ng i b n cho b n xem ph ng th c sau đây và di n gi i r ng n u ộ ườ ạ ạ ươ ứ ễ ả ằ ế number là s có hai ố ch s b t kì, thì ch ng trình s in các ch s theo chi u ng c l i. Ng i y kh ng đ nh r ng ữ ố ấ ươ ẽ ữ ố ề ượ ạ ườ ấ ẳ ị ằ n uế number là 17, thì ph ng th c s cho ra k t qu b ng ươ ứ ẽ ế ả ằ 71. Li u ng i đó có đúng không? N u không, ệ ườ ế
hãy gi i thích ch ng trình th c s làm gì và s a ch a đ nó cho k t qu đúng. ả ươ ự ự ử ữ ể ế ả
int number = 17;
int lastDigit = number%10;
int firstDigit = number/10;
System.out.println(lastDigit + firstDigit);
Bài t p 8 ậ K t qu c a ch ng trình sau là gì? ế ả ủ ươ
public class Enigma {
public static void enigma(int x) {
if (x == 0) {
return;
} else {
enigma(x/2);
}
System.out.print(x%2);
}
public static void main(String[] args) {
enigma(5);
System.out.println("");
}
}
Hãy gi i thích ng n g n b ng 4-5 t xem ph ng th c ả ắ ọ ằ ừ ươ ứ enigma th c s làm đi u gì. ự ự ề Bài t p 9 ậ
1. Hãy l p m t ch ng trình m i có tên ậ ộ ươ ớ Palindrome.java.
2. Vi t m t ph ng th c có tên ế ộ ươ ứ first nh n vào m t String r i tr l i ch cái đ u tiên, và m t ph ng ậ ộ ồ ả ạ ữ ầ ộ ươ th cứ last đ tr l i ch cái cu i cùng. ể ả ạ ữ ố
3. Vi t m t ph ng th c có tên ế ộ ươ ứ middle nh n vào m t String r i tr l i m t chu i con có ch a m i th tr ậ ộ ồ ả ạ ộ ỗ ứ ọ ứ ừ hai ch cái đ u và cu i. G i ý: hãy đ c tài li u v ph ng th c ữ ầ ố ợ ọ ệ ề ươ ứ substring trong l pớ String. Hãy ch y m t ạ ộ vài phép th đ ch c r ng b n hi u rõ cách ho t đ ng c a ử ể ắ ằ ạ ể ạ ộ ủ substring tr c khi th vi t ướ ử ế middle. Đi u gì ề
s x y ra n u b n kích ho t ẽ ả ế ạ ạ middle lên m t chu i ch có hai ch cái? M t ch cái? Không có ch cái ộ ỗ ỉ ứ ộ ữ ữ nào?
4. Cách đ nh nghĩa thông th ng c a m t palindrome là m t t mà đ c xuôi ng c đ u gi ng nhau, ch ng ị ườ ủ ộ ộ ừ ọ ượ ề ố ẳ h n “otto” và “palindromeemordnilap.” M t cách khác đ đ nh nghĩa m t thu c tính nh th baft là quy ạ ộ ể ị ộ ộ ư ế đ nh m t cách ki m tra thu c tính đó. Ch ng h n, ta có th nói “m t ch cái là m t palindrome, và m t ị ộ ể ộ ẳ ạ ể ộ ữ ộ ộ t hai ch là m t palindrome n u hai ch cái c a nó gi ng nhau, và m t t b t kì khác là m t ừ ữ ộ ế ữ ủ ố ộ ừ ấ ộ
palindrome n u ch cái đ u gi ng ch cái cu i và khúc gi a cũng là m t palindrome.” Hãy vi t m t ế ữ ầ ố ữ ố ữ ộ ế ộ ph ng th c đ quy có tên ươ ứ ệ isPalindrome nh n vào m t ậ ộ String và tr l i m t boolean cho bi t t đó có ả ạ ộ ế ừ ph i là palindrome hay không. ả
5. M t khi b n đã có đo n mã đ ki m tra palindrome, hãy tìm cách đ n gi n hoá nó b ng cách gi m s ộ ạ ạ ể ể ơ ả ằ ả ố đi u ki n trong phép ki m tra. G i ý: vi c l y đ nh nghĩa chu i r ng cũng là palindrome có th giúp ích. ề ệ ể ợ ệ ấ ị ỗ ỗ ể 6. Hãy vi t ra trên gi y m t chi n l c có tính l p đ ki m tra palindrome. Có m t s ph ng án kh dĩ, ế ấ ộ ế ượ ặ ể ể ộ ố ươ ả b i v y b n hãy đ m b o ch c ch n m t k ho ch rõ ràng tr c khi b t đ u vi t mã l nh. ở ậ ạ ả ả ắ ắ ộ ế ạ ướ ắ ầ ế ệ 7. Hãy t o l p chi n l c b n ch n thành m t ph ng th c có tên ạ ậ ế ượ ạ ọ ộ ươ ứ isPalindromeIter. 8. Câu h i ph : Ph l c ỏ ụ ụ ụ B có mã l nh đ đ c m t danh sách các t v ng t m t file. Hãy đ c m t danh ệ ể ọ ộ ừ ự ừ ộ ọ ộ sách các t r i in ra nh ng palindrome. ừ ồ ữ
Bài t p 10 ậ M t t đ c g i là “abecedarian” n u các ch cái trong t đó xu t hi n theo th t b ng ộ ừ ượ ọ ế ữ ừ ấ ệ ứ ự ả ch cái. Ch ng h n, sau đây là t t c nh ng t abecedarian g m 6 ch cái trong ti ng Anh. ữ ẳ ạ ấ ả ữ ừ ồ ữ ế abdest, acknow, acorsy, adempt, adipsy, agnosy, befist, behint, beknow, bijoux, biopsy, cestuy, chintz, deflux, dehors, dehort, deinos, diluvy, dimpsy
1. Hãy miêu t m t quy trình ki m tra xem m t t (String) cho tr c là abecedarian hay không, n u coi ả ộ ể ộ ừ ướ ế r ng t đó ch g m các ch cái th ng. Quy trình này có th mang tính l p hay đ quy. ằ ừ ỉ ồ ữ ườ ể ặ ệ 2. T o d ng quy trình trên thành m t ph ng th c mang tên ạ ự ộ ươ ứ isAbecedarian.
Bài t p 11 ậ M t dupledrome là m t t ch ch a các ch cái ghép đôi, ch ng h n nh “llaammaa” hay ộ ộ ừ ỉ ứ ữ ẳ ạ ư “ssaabb”. Tôi đ ra gi thi t ràng trong ti ng Anh thông d ng không h có dupledrome nào. Đ ki m ề ả ế ế ụ ề ể ể ch ng gi thi t đó, tôi mu n có ch ng trình đ c l n l t các t v ng t m t cu n t đi n r i ki m tra ứ ả ế ố ươ ọ ầ ượ ừ ự ừ ộ ố ừ ể ồ ể xem t đó có ph i là dupledrome hay không. Hãy vi t m t ph ng th c mang tên ừ ả ế ộ ươ ứ isDupledrome nh n ậ vào m t String r i tr l i m t boolean đ cho bi t t đó có ph i là dupledrome không. ộ ồ ả ạ ộ ể ế ừ ả Bài t p 12 ậ
1. Vòng gi i mã Captain Crunch ho t đ ng b ng cách l y m i ch cái trong m t chu i r i c ng 13 vào nó. ả ạ ộ ằ ấ ỗ ữ ộ ỗ ồ ộ Ch ng h n, ’a’ tr thành ’n’ và ’b’ tr thành ’o’. Đ n cu i, các ch cái “quay vòng l i”, b i v y ’z’ tr ẳ ạ ở ở ế ố ữ ạ ở ậ ở thành ’m’. Hãy vi t m t ph ng th c nh n vào m t String r i tr l i m t String m i có ch a chu i sau ế ộ ươ ứ ậ ộ ồ ả ạ ộ ớ ứ ỗ mã hoá. B n c n coi ràng String ban đ u ch ch a các ch in, ch th ng, d u cách, mà không có d u ạ ầ ầ ỉ ứ ữ ữ ườ ấ ấ ch m ph y gì khác. Các ch th ng thì đ c mã hoá thành ch th ng, ch in thành ch in. B n không ấ ẩ ữ ườ ượ ữ ườ ữ ữ ạ đ c mã hoá ượ các d u cách. ấ
2. Hãy khái quát hoá ph ng th c Captain Crunch sao cho thay vì c ng 13 vào t ng ch cái, nó có th c ng ươ ứ ộ ừ ữ ể ộ thêm b t kì s nào. Bây gi b n có th mã hoá b n cách c ng 13 r i gi i mã b ng cách c ng -13. Hãy th ấ ố ờ ạ ể ằ ộ ồ ả ằ ộ ử làm đi u này. ề
Bài t p 13 ậ N u b n đã gi i các bài t p GridWorld trong Ch ng ế ạ ả ậ ươ 5, có th b n s thích bài t p này. ể ạ ẽ ậ M c đích là dùng toán l ng giác đ khi n các con b (Bug) đu i b t l n nhau. Hãy sao chép ụ ượ ể ế ọ ổ ắ ẫ file BugRunner.java thành ChaseRunner.java r i nh p nó vào môi tr ng phát tri n c a b n. Tr c khi ồ ậ ườ ể ủ ạ ướ