M cl c Gi i thi u...........................................................................................................6 Chương 1. 1.1. 1.2. M u .........................................................................................

8

Chương trình là gì?.............................................................................8 L p trình là gì? ...................................................................................8 M c cao c l p v i máy tính ......................................................8

1.2.1. 1.2.2. 1.3. 1.4. 1.5. 1.6. 1.7.

M c th p ph thu c vào máy tính ..............................................10

Ngôn ng l p trình và chương trình d ch ..........................................10 Môi trư ng l p trình b c cao.............................................................11 L i và tìm l i ....................................................................................13 L ch s C và C++ .............................................................................14 Chương trình C++ u tiên ...............................................................15

Bài t p .........................................................................................................19 Chương 2. 2.1. Bi n, ki u d li u và các phép toán ............................................20

Ki u d li u......................................................................................22 Ki u d li u cơ b n ....................................................................22 Ki u d li u d n xu t .................................................................24

2.1.1. 2.1.2. 2.2.

Khai báo và s d ng bi n .................................................................24 nh danh và cách t tên bi n ...................................................24

2.2.1. 2.2.2. 2.3. 2.4.

Khai báo bi n .............................................................................25

H ng.................................................................................................25 Các phép toán cơ b n........................................................................26 Phép gán.....................................................................................26 Các phép toán s h c..................................................................26 Các phép toán quan h ................................................................27 1

2.4.1. 2.4.2. 2.4.3.

2.4.4. 2.4.5. 2.4.6.

Các phép toán lô-gic...................................................................28 ưu tiên c a các phép toán......................................................28 Tương thích gi a các ki u ..........................................................29

Bài t p .........................................................................................................30 Chương 3. 3.1. 3.2. Các c u trúc i u khi n ..............................................................32

Lu ng i u khi n..............................................................................32 Các c u trúc r nhánh .......................................................................33 L nh if-else ...........................................................................33 L nh switch .............................................................................39

3.2.1. 3.2.2. 3.3.

Các c u trúc l p ................................................................................43 Vòng while...............................................................................43 Vòng do-while ........................................................................46 Vòng for ...................................................................................49

3.3.1. 3.3.2. 3.3.3. 3.4. 3.5.

Các l nh break và continue .........................................................54 Bi u th c i u ki n trong các c u trúc i u khi n.............................57

Bài t p .........................................................................................................59 Chương 4. 4.1. 4.2. 4.3. 4.4. Hàm............................................................................................61

Các hàm có s n.................................................................................62 C u trúc chung c a hàm ...................................................................63 Cách s d ng hàm ............................................................................64 Bi n toàn c c và bi n a phương .....................................................65

4.4.1. 4.4.2. 4.5.

Ph m vi c a bi n ........................................................................65 Th i gian s ng c a bi n..............................................................67 i s , và cơ ch truy n tham s cho hàm .........................68

Tham s ,

4.5.1.

Truy n giá tr ..............................................................................68

2

4.5.2. 4.5.3. 4.6. 4.7.

Truy n tham chi u......................................................................69 Tham s m c nh ......................................................................72

Hàm trùng tên...................................................................................74 Hàm quy ......................................................................................76

Bài t p .........................................................................................................78 Chương 5. 5.1. M ng ..........................................................................................80

M ng m t chi u................................................................................80 Khai báo và kh i t o m ng .........................................................81 ng d ng c a m ng ...................................................................83 Trách nhi m ki m soát tính h p l c a ch s m ng....................85 M ng làm tham s cho hàm........................................................85

5.1.1. 5.1.2. 5.1.3. 5.1.4. 5.2. 5.3.

M ng nhi u chi u .............................................................................86 M ng và xâu kí t .............................................................................88 Kh i t o giá tr cho xâu kí t ......................................................90 Thư vi n x lý xâu kí t .............................................................90

5.3.1. 5.3.2. 5.4.

Tìm ki m và s p x p d li u trong m ng ..........................................91 Tìm ki m tuy n tính ...................................................................91 Tìm ki m nh phân .....................................................................92 S p x p ch n ..............................................................................94

5.4.1. 5.4.2. 5.4.3.

Bài t p .........................................................................................................96 Chương 6. 6.1. 6.2. 6.3. 6.4. Con tr và b nh .......................................................................99

B nh máy tính ...............................................................................99 Bi n và a ch c a bi n....................................................................99

Bi n con tr ....................................................................................100 M ng và con tr ..............................................................................105

3

6.5.

B nh

ng ...................................................................................107 ng...............................................................107 ng ...........................................................108

6.5.1. 6.5.2. 6.6. 6.7.

C p phát b nh Gi i phóng b nh

M ng

ng và con tr .....................................................................109

Truy n tham s là con tr ...............................................................111

Bài t p .......................................................................................................115 Chương 7. 7.1. 7.2. 7.2.1. 7.2.2. 7.2.3. 7.3. 7.4. Các ki u d li u tr u tư ng ......................................................118 nh nghĩa ki u d li u tr u tư ng b ng c u trúc struct .................118 nh nghĩa ki u d li u tr u tư ng b ng c u trúc class ...............124 Quy n truy nh p .......................................................................127 Toán t ph m vi và nh nghĩa các hàm thành viên ..................128

Hàm kh i t o và hàm h y.........................................................129 i tư ng.............................................132

L i ích c a l p trình hư ng

Biên d ch riêng r ...........................................................................133

Bài t p .......................................................................................................137 Chương 8. 8.1. 8.2. 8.3. Vào ra d li u...........................................................................140

Khái ni m dòng d li u ..................................................................140 T p văn b n và t p nh phân ...........................................................141 Vào ra t p .......................................................................................141 M t p......................................................................................142 óng t p...................................................................................143 X lý t p văn b n .....................................................................144 X lý t p nh phân ....................................................................147

8.3.1. 8.3.2. 8.3.3. 8.3.4.

Bài t p .......................................................................................................151 Ph l c A. Phong cách l p trình .................................................................153

4

Ph l c B. Ph l c C.

D ch chương trình C++ b ng GNU C++...................................157 X lý xâu b ng thư vi n cstring................................................160

Tài li u tham kh o .........................................................................................162

5

Gi i thi u
L p trình là m t trong nh ng bư c quan tr ng nh t trong quy trình gi i quy t m t bài toán. Nhi u ngôn ng l p trình ã ư c ra i nh m giúp chúng ta gi i quy t các bài toán m t cách hi u qu nh t. M i ngôn ng l p trình có nh ng th m nh và như c i m riêng. Các ngôn ng l p trình có th chia ra thành hai lo i chính là ngôn ng l p trình b c th p (g n gũi v i ngôn ng máy), và ngôn ng l p trình b c cao (ng n gũi v i ngôn ng t nhiên c a con ngư i). Giáo trình này trang b cho sinh viên nh ng ki n th c cơ b n v l p trình. Ngôn ng l p trình C++ ư c s d ng minh h a cho vi c l p trình. Vi c l a ch n C++ b i vì nó là m t ngôn ng l p trình hư ng i tư ng chuyên nghi p ư c s d ng r ng rãi trên toàn th gi i phát tri n các chương trình t ơn gi n n ph c t p. Hơn th n a, s m m d o c a C++ cho phép chúng ta gi i quy t nh ng bài toán th c t m t cách nhanh chóng, ngoài ra cho phép chúng ta qu n lý và tương tác tr c ti p n h th ng, b nh nâng cao hi u qu c a chương trình. Giáo trình ư c chia thành 8 chương, m i chương trình bày m t v n lý thuy t trong l p trình. Các v n lý thuy t ư c mô t b ng các ví d th c t . K t thúc m i chương là ph n bài t p sinh viên gi i quy t và n m rõ hơn v lý thuy t. C u trúc c a giáo trình như sau: • Chương 1: gi i thi u các khái ni m cơ b n v l p trình và quy trình gi i quy t m t bài toán. Sinh viên s hi u v ngôn ng l p trình b c cao và ngôn ng l p trình b c th p. Cu i chương chúng tôi gi i thi u v môi trư ng l p trình cũng như ngôn ng l p trình C++. • Chương 2: Chúng tôi gi i thi u các khái ni m cơ b n v bi n s , h ng s , các ki u d li u cơ b n và các phép toán cơ b n. Sau khi h c, sinh viên s bi t cách khai báo và s d ng bi n s , h ng s , và các phép toán trên bi n và h ng s . • Chương 3: Trương này gi i thi u v c u trúc chương trình cũng như các c u trúc i u khi n. C th là các c u r nhánh (if-else, switch), c u trúc l p (for, while, do-while) s ư c gi i thi u. • Chương 4: Chương trình con và hàm s ư c gi i thi u sinh viên hi u ư c chi n lư c l p trình “chia tr ”. Chúng tôi s trình bày chi ti t v

6

cách khai báo và s d ng hàm, cũng như cách truy n tham s , truy n giá tr cho hàm. • Chương 5: Chương này trình bày c u trúc d li u ki u m ng và xâu kí t . Cách khai báo và s d ng m ng m t chi u cũng như m ng nhi u chi u và ví d liên quan ư c trình bày chi ti t chương này. • Chương 6: ây là m t chương tương i c thù cho C++, khi chúng tôi trình bày v b nh và ki u d li u con tr . C u trúc b nh , cách qu n lý và xin c p phép b nh ng thông qua vi c s d ng bi n con tr s ư c trình bày. • Chương 7: Trong chương này chúng tôi s trình bày v c u trúc d li u tr u tư ng (c th là struct và class trong C++). Sinh viên s hi u và bi t cách t o ra nh ng c u trúc d li u tr u tư ng phù h p v i các ki u i tư ng d li u c n bi u di n. Cu i chương, chúng tôi cũng gi i thi u v l p trình hư ng i tư ng, m t th m nh c a ngôn ng l p trình C++. • Chương 8: Chúng tôi gi i thi u v cách vào ra d li u. Sinh viên s gi i thi u chi ti t v cách làm vi c v i các t p d li u. ư c

7

Chương 1. M

u

Trong chương này, chúng tôi s gi i thi u qua m t s khái ni m cơ b n v : chương trình, l p trình, ngôn ng l p trình.

1.1. Chương trình là gì?
B n ch c ch n ã dùng qua nhi u chương trình khác nhau, ví d như chương trình so n th o văn b n “Microsoft Word”. Chương trình, hay ph n m m, ư c hi u ơn gi n là m t t p các l nh máy tính th c hi n theo. Khi b n ưa cho máy tính m t chương trình và yêu c u máy tính th c hi n theo các l nh c a chương trình, b n ang ch y chương trình ó.

1.2. L p trình là gì?
L p trình là có th hi u ơn gi n là quá trình vi t ra các l nh hư ng d n máy tính th c hi n gi i quy t m t bài toán c th nào ó. L p trình là m t bư c quan tr ng trong quy trình gi i quy t m t bài toán như mô t Hình 1.1.

Hình 1.1: Quy trình gi i quy t m t bài toán.

Quy trình trên có th ư c chia ra thành hai m c: m c cao c l p v i máy tính (machine independent) và m c th p ph thu c vào máy tính (machine specific). 1.2.1. M c cao M c cao nh v n c l p v i máy tính

c l p v i máy tính thư ng ư c chia thành ba bư c chính là: xác , thi t k thu t toán và l p trình.

8

chương trình d ch

trình so n th o

bút/gi y

bút/gi y

Xác nh v n : Bư c này nh nghĩa bài toán, xác nh d li u u vào, các ràng bu c, yêu c u c n gi i quy t và k t qu u ra. Bư c này thư ng s d ng bút/gi y và ngôn ng t nhiên như ti ng Anh, ti ng Vi t mô t và xác nh v n c n gi i quy t. Thi t k thu t toán: M t thu t toán là m t b các ch d n nh m gi i quy t m t bài toán. Các ch d n này c n ư c di n t m t cách hoàn ch nh và chính xác sao cho m i ngư i có th hi u và ti n hành theo. Thu t toán thư ng ư c mô t dư i d ng mã gi (pseudocode). Bư c này có th s d ng gi y bút và thư ng không ph thu c vào ngôn ng l p trình. Ví d v thu t toán “tìm ư c s chung l n nh t (UCLN) c a hai s x và y” vi t b ng ngôn ng t nhiên: • Bư c 1: N u x>y thì thay x b ng ph n dư c a phép chia x/y. • Bư c 2: N u không, thay y b ng ph n dư c a phép chia y/x. • Bư c 3: N u trong hai s x và y có m t s b ng 0 thì k t lu n UCLN là s còn l i. • Bư c 4: N u không, quay l i Bư c 1. ho c b ng mã gi : repeat if x > y then x := x mod y else y := y mod x until x = 0 or y = 0 if x = 0 then UCLN := y else UCLN := x L p trình là bư c chuy n i thu t toán sang m t ngôn ng l p trình, ph bi n là các ngôn ng l p trình b c cao, ví d như các ngôn ng C++, Java. Bư c này, l p trình viên s d ng m t chương trình so n th o văn b n vi t chương trình. Trong và sau quá trình l p trình, ngư i ta ph i ti n hành ki m th và s a l i chương trình. Có ba lo i l i thư ng g p: l i cú pháp, l i trong th i gian ch y, và l i lô-gic (xem chi ti t M c 1.5).

9

1.2.2. M c th p ph thu c vào máy tính Các ngôn ng l p trình b c cao, ví d như C, C++, Java, Visual Basic, C#, ư c thi t k con ngư i tương i d hi u và d s d ng. Tuy nhiên, máy tính không hi u ư c các ngôn ng b c cao. Do ó, trư c khi m t chương trình vi t b ng ngôn ng b c cao có th ch y ư c, nó ph i ư c d ch sang ngôn ng máy, hay còn g i là mã máy, mà máy tính có th hi u và th c hi n ư c. Vi c d ch ó ư c th c hi n b i m t chương trình máy tính g i là chương trình d ch.

1.3. Ngôn ng l p trình và chương trình d ch
Như chúng ta th y, quá trình gi i quy t m t bài toán thông qua các bư c khác nhau chuy n i t ngôn ng t nhiên mà con ngư i hi u ư c sang ngôn ng máy mà máy tính có th hi u và th c hi n ư c. Ngôn ng l p trình thư ng ư c chia ra thành hai lo i: ngôn ng l p trình b c th p và ngôn ng l p trình b c cao. Ngôn ng l p trình b c th p như h p ng (assembly language) ho c mã máy c i m là ngôn ng g n v i ngôn ng máy mà máy tính có th hi u ư c. chính c a các ngôn ng này là chúng có liên quan ch t ch n ph n c ng c a máy tính. Các h máy tính khác nhau s d ng các ngôn ng khác nhau. Chương trình vi t b ng các ngôn ng này có th ch y mà không c n qua chương trình d ch. Các ngôn ng b c th p có th dùng vi t nh ng chương trình c n t i ưu hóa v t c . Tuy nhiên, chúng thư ng khó hi u i v i con ngư i và không thu n ti n cho vi c l p trình. Ngôn ng l p trình b c cao như Pascal, Ada, C, C++, Java, Visual Basic, Python, … là các ngôn ng có m c tr u tư ng hóa cao, g n v i ngôn ng t nhiên c a con ngư i hơn. Vi c s d ng các ngôn ng này cho vi c l p trình do ó d dàng hơn và nhanh hơn r t nhi u so v i ngôn ng l p trình b c th p. Khác v i ngôn ng b c th p, chương trình vi t b ng các ngôn ng b c cao nói chung có th s d ng ư c trên nhi u lo i máy tính khác nhau. Các chương trình vi t b ng m t ngôn ng b c cao mu n ch y ư c thì ph i ư c d ch sang ngôn ng máy b ng cách s d ng chương trình d ch. Chương trình d ch có th chia ra thành hai lo i là trình biên d ch và trình thông d ch. M t s ngôn ng b c cao như C, C++ yêu c u lo i chương trình d ch ư c g i là trình biên d ch (compiler). Trình biên d ch d ch mã ngu n thành mã máy – d ng có th th c thi ư c. K t qu c a vi c d ch là m t chương trình th c thi ư c và có th ch y nhi u l n mà không c n d ch l i. Ví d , v i ngôn ng C++ 10

m t trình biên d ch r t ph bi n là gcc/g++ trong b GNU Compiler Collection (GCC) ch y trong các môi trư ng Unix/Linux cũng như Windows. Ngoài ra, Microsoft Visual C++ là trình biên d ch C++ ph bi n nh t trong môi trư ng Windows. M t s ngôn ng b c cao khác như Perl, Python yêu c u lo i chương trình d ch g i là trình thông d ch (interpreter). Khác v i trình biên d ch, thay vì d ch toàn b chương trình m t l n, trình thông d ch v a d ch v a ch y chương trình, d ch n âu ch y chương trình n ó. Trong môn h c này, C++ ư c ch n làm ngôn ng th hi n. ây là m t trong nh ng ngôn ng l p trình chuyên nghi p ư c s d ng r ng rãi nh t trên th gi i. Trong ph m vi nh p môn c a môn h c này, C++ ch ư c gi i thi u m c r t cơ b n, r t nhi u tính năng m nh c a C++ s không ư c nói n ho c ch ư c gi i thi u sơ qua. Ngư i h c nên ti p t c tìm hi u v ngôn ng C++, vư t ra ngoài gi i h n c a cu n sách này.

1.4. Môi trư ng l p trình b c cao
l p trình gi i quy t m t bài toán b ng ngôn ng l p trình b c cao, b n c n có công c chính là: chương trình so n th o, chương trình d ch dành cho ngôn ng s d ng, và các thư vi n chu n c a ngôn ng s d ng (standard library), và chương trình tìm l i (debugger). Các bư c cơ b n xây d ng và th c hi n m t chương trình:

1. So n th o: Mã ngu n chương trình ư c vi t b ng m t ph n m m so n th o văn b n d ng text và lưu trên ĩa. Ta có th dùng nh ng ph n m m so n th o văn b n ơn gi n nh t như Notepad (trong môi trư ng Windows) hay vi (trong môi trư ng Unix/Linux), ho c các công c so n th o trong môi trư ng tích h p vi t mã ngu n chương trình. Mã ngu n C++ thư ng t trong các t p v i tên có ph n m r ng là .cpp, cxx, .cc, ho c .C (vi t hoa). 2. D ch: Dùng trình biên d ch d ch mã ngu n chương trình ra thành các o n mã máy riêng l (g i là “object code”) lưu trên ĩa. Các trình biên d ch ph bi n cho C++ là vc.exe trong b Microsoft Visual Studio hay gcc trong b GNU Compiler v i các tham s thích h p d ch và liên k t t o ra t p ch y ư c. V i C++, ngay trư c khi d ch còn có giai o n ti n x lý (preprocessing) khi các nh hư ng ti n x lý ư c th c thi làm các thao tác như b sung các t p văn b n c n d ch hay thay th m t s chu i văn b n. M ts nh hư ng ti n x lý quan tr ng s ư c gi i thi u d n trong cu n sách này. 11

3. Liên k t: M t t p mã ngu n thư ng không ch a y nh ng ph n c n thi t cho m t chương trình hoàn ch nh. Nó thư ng dùng n d li u ho c hàm ư c nh nghĩa trong các t p khác ho c trong thư vi n chu n. Trình liên k t (linker) k t n i các o n mã máy riêng l v i nhau và v i các thư vi n có s n t o ra m t chương trình mã máy hoàn ch nh ch y ư c. 4. N p: Trình n p (loader) s n p chương trình dư i d ng mã máy vào b nh . Các thành ph n b sung t thư vi n cũng ư c n p vào b nh . 5. Ch y: CPU nh n và th c hi n l n lư t các l nh c a chương trình, d li u và k t qu thư ng ư c ghi ra màn hình ho c ĩa. Thư ng thì không ph i chương trình nào cũng ch y ư c và ch y úng ngay l n ch y th u tiên. Chương trình có th có l i cú pháp nên không qua ư c bư c d ch, ho c chương trình d ch ư c nhưng g p l i trong khi ch y. Trong nh ng trư ng h p ó, l p trình viên ph i quay l i bư c so n th o s a l i và th c hi n l i các bư c sau ó.

Hình 1.2: Các bư c cơ b n

xây d ng m t chương trình.

thu n ti n cho vi c l p trình, các công c so n th o, d ch, liên k t, ch y... nói trên ư c k t h p l i trong m t môi trư ng l p trình tích h p (IDE – integrated development environment), trong ó, t t c các công o n i v i ngư i dùng ch còn là vi c ch y các tính năng trong m t ph n m m duy nh t. IDE r t h u ích cho các l p trình viên. Tuy nhiên, i v i nh ng ngư i m i h c l p trình, th i gian u nên t th c hi n các bư c d ch và ch y chương trình thay vì thông qua các ch c năng c a IDE. Như v y, ngư i h c s có th n m ư c b n ch t các bư c c a quá trình xây d ng chương trình, hi u ư c b n 12

ch t và c th .

c i m chung c a các IDE, tránh tình tr ng b ph thu c vào m t IDE

Ví d v các IDE ph bi n là Microsoft Visual Studio – môi trư ng l p trình thương m i cho môi trư ng Windows, và Eclipse – ph n m m mi n phí v i các phiên b n cho c môi trư ng Windows cũng như Unix/Linux, c hai u h tr nhi u ngôn ng l p trình. Dành cho C++, m t s môi trư ng l p trình tích h p ph bi n là Microsoft Visual Studio, Dev-C++, Code::Blocks, KDevelop. M i môi trư ng có th h tr m t ho c nhi u trình biên d ch. Ch ng h n Code::Blocks h tr c GCC và MSVC Do C++ có các phiên b n khác nhau. Có nh ng b n cài t khác nhau c a C++. Các b n ra i trư c chu n C++ 1998 (ISO/IEC 14882) có th không h tr y các tính năng ư c c t trong chu n ANSI/ISO 1998. B n C++ do Microsoft phát tri n khác v i b n C++ c a GNU. Tuy nhiên, các trình biên d ch hi n i h u h t h tr C++ chu n, ta cũng nên ch n dùng các ph n m m này. Ngôn ng C++ ư c dùng trong cu n sách này tuân theo chu n ISO/IEC 14882, còn g i là "C++ thu n túy" (pure C++).

1.5. L i và tìm l i
Trong và sau quá trình l p trình, chúng ta ph i ti n hành ki m th và s a l i chương trình. Có ba lo i l i thư ng g p: l i cú pháp, l i run-time và l i lô-gic. L i cú pháp là do l p trình viên vi t sai v i các quy t c cú pháp c a ngôn ng l p trình, ch ng h n thi u d u ch m ph y cu i l nh. Chương trình biên d ch s phát hi n ra các l i cú pháp và cung c p thông báo v v trí mà nó cho là có l i. N u trình biên d ch nói r ng chương trình có l i cú pháp thì ch c ch n là có l i cú pháp trong chương trình. Tuy nhiên, l i là ch nào thì trình biên d ch ch có th oán, và nó có th oán sai. L i run-time là l i xu t hi n trong khi chương trình ang ch y. L i d ng này s gây ra thông báo l i và ng ng chương trình. Ví d là khi chương trình th c hi n phép chia cho 0. L i lô-gic có nguyên nhân là do thu t toán không úng, ho c do l p trình viên g p sai sót khi th hi n thu t toán b ng ngôn ng l p trình (ví d vi t nh m d u c ng thành d u tr ). Khi có l i lô-gic, chương trình c a b n có th d ch và ch y bình thư ng, nhưng k t qu c a chương trình ưa ra l i có trư ng h p sai ho c

13

ho t ng c a chương trình không như mong ra nh t.

i. L i lô-gic là lo i l i khó tìm

N u chương trình c a b n d ch và ch y không phát sinh thông báo l i, th m chí chương trình cho ra k t qu có úng v i m t vài b d li u test, i u ó không có nghĩa chương trình c a b n hoàn toàn không có l i. có th ch c ch n hơn v tính úng n c a chương trình, b n c n ch y th chương trình v i nhi u b d li u khác nhau và so sánh k t qu mà chương trình t o ra v i k t qu mong i.

1.6. L ch s C và C++
Ngôn ng l p trình C ư c t o ra b i Dennis Ritchie (phòng thí nghi m Bell) và ư c s d ng phát tri n h i u hành UNIX. M t trong nh ng c i m n i b t c a C là c l p v i ph n c ng (portable), t c là chương trình có th ch y trên các lo i máy tính và các h i u hành khác nhau. Năm 1983, ngôn ng C ã ư c chu n hóa và ư c g i là ANSI C b i Vi n chu n hóa qu c gia Hoa Kỳ (American National Standards Institute). Hi n nay ANSI C v n là ngôn ng l p trình chuyên nghi p và ư c s d ng r ng rãi phát tri n các h th ng tính toán hi u năng cao. Ngôn ng l p trình C++ do Bjarne Stroustrup (thu c phòng thí nghi m Bell) phát tri n trên n n là ngôn ng l p trình C và c m h ng chính t ngôn ng l p trình Simula67. So v i C, C++ là ngôn ng an toàn hơn, kh năng di n t cao hơn, và ít òi h i các k thu t b c th p. Ngoài nh ng th m nh th a k t C, C++ h tr tr u tư ng hóa d li u, l p trình hư ng i tư ng và l p trình t ng quát, C++ giúp xây d ng d dàng hơn nh ng h th ng l n và ph c t p. B t u t phiên b n u tiên năm 1979 v i cái tên "C with Classes" (C kèm l p i tư ng)1 v i các tính năng cơ b n c a l p trình hư ng i tư ng, C++ ư c phát tri n d n theo th i gian. Năm 1983, cái tên "C++" chính th c ra i, các tính năng như hàm o (virtual function), hàm trùng tên và nh nghĩa l i toán t (overloading), h ng ... ư c b sung. Năm 1989, C++ có thêm l p tr u tư ng, a th a k , hàm thành viên tĩnh, h ng hàm, và thành viên ki u protected. Các b sung cho C++ trong th p k sau ó là khuôn m u (template), không gian tên (namespace), ngo i l (exception), các toán t i ki u d li u m i, và ki u d

1

Theo l i k c a Bjarne Stroustrup t i trang cá nhân c a ông t i trang web c a phòng thí nghi m AT&T http://www2.research.att.com/~bs/bs_faq.html#invention

14

li u Boolean. Năm 1998, l n u tiên C++ ư c chính th c chu n hóa qu c t b i t ch c ISO, k t qu là chu n ISO/IEC 148822. i kèm v i s phát tri n c a ngôn ng là s phát tri n c a thư vi n chu n C++. Bên c nh vi c tích h p thư vi n chu n truy n th ng c a C v i các s a i nh cho phù h p v i C++, thư vi n chu n C++ còn có thêm thư vi n stream I/O ph c v vi c vào ra d li u d ng dòng. Chu n C++ năm 1998 tích h p thêm ph n l n thư vi n STL (Standard Template Library – thư vi n khuôn m u chu n)3. Ph n này cung c p các c u trúc d li u r t h u ích như vector, danh sách, và các thu t toán như s p x p và tìm ki m. Hi n nay, C++ là m t trong các ngôn ng l p trình chuyên nghi p ư c s d ng r ng rãi nh t.

1.7. Chương trình C++

u tiên

Chương trình ơn gi n trong Hình 1.3 s hi n ra màn hình dòng ch “Hello world!”. Trong chương trình có nh ng c i m quan tr ng c a C++. Ta s xem xét t ng dòng.

2

Văn b n này (ISO/IEC 14882:1998) sau ó ư c phát hi n l i ch nh s a vào năm 2003, thành phiên b n ISO/IEC 14882:2003. STL v n không n m trong thư vi n chu n mà là m t thư vi n riêng do HP và sau ó là SGI phát tri n.

3

15

Hình 1.3: Chương trình C++

u tiên.

Hai dòng u tiên b t u b ng chu i // là các dòng chú thích chương trình. ó là ki u chú thích dòng ơn. Các dòng chú thích không gây ra ho t ng gì c a chương trình khi ch y, trình biên d ch b qua các dòng này. Ngoài ra còn có d ng chú thích ki u C dùng chu i /* và */ ánh d u i m b t u và k t thúc chú thích. Các l p trình viên dùng chú thích gi i thích và gi i thi u v n i dung chương trình. Dòng th ba, #include <iostream> là m t nh hư ng ti n x lý (preprocessor directive) – ch d n v m t công vi c mà trình biên d ch c n th c hi n trư c khi d ch chương trình. #include là khai báo v thư vi n s ư c s d ng trong chương trình, trong trư ng h p này là thư vi n vào ra d li u iostream trong thư vi n chu n C++. Ti p theo là hàm main, ph n không th thi u c a m i chương trình C++. Nó b t u t dòng khai báo header c a hàm:
int main()

M i chương trình C++ thư ng bao g m m t ho c nhi u hàm, trong ó có úng m t hàm có tên main, ây là nơi chương trình b t u th c hi n và k t thúc. Bên trái t main là t khóa int, nó có nghĩa là hàm main s tr v m t giá tr là s nguyên. T khóa là nh ng t c bi t mà C++ dành riêng cho nh ng m c

16

ích c th . Chương 4 s cung c p thông tin chi ti t v khái ni m hàm và vi c hàm tr v giá tr . Thân hàm main ư c b t u và k t thúc b i c p ngo c {}, bên trong ó là chu i các l nh mà khi chương trình ch y chúng s ư c th c hi n tu n t t l nh àu tiên cho n l nh cu i cùng. Hàm main trong ví d ang xét có ch a hai l nh. M i l nh u k t thúc b ng m t d u ch m ph y, các nh hư ng ti n x lý thì không. L nh th nh t g m cout, toán t <<, xâu kí t "Hello world!", và d u ch m ph y. Nó ch th cho máy tính th c hi n m t nhi m v : in ra màn hình chu i kí t n m gi a hai d u nháy kép – "Hello world!". Khi l nh ư c th c thi, chu i kí t Hello world s ư c g i cho cout – lu ng d li u ra chu n c a C++, thư ng ư c n i v i màn hình. Chi ti t v vào ra d li u s ư c nói n trong Chương 8. Chu i kí t n m gi a hai d u nháy kép ư c g i là m t xâu kí t (string). ý dòng
using namespace std;

n m g n u chương trình. T t c thành ph n c a thư vi n chu n C++, trong ó có cout ư c dùng n trong hàm main, ư c khai báo trong m t không gian tên (namespace) có tên là std. Dòng trên thông báo v i trình biên d ch r ng chương trình ví d c a ta s s d ng n m t s thành ph n n m trong không gian tên std. N u không có khai báo trên, ti n t std:: s ph i i kèm theo tên c a t t c các thành ph n c a thư vi n chu n ư c dùng trong chương trình, ch ng h n cout s ph i ư c vi t thành std::cout. Chi ti t v không gian tên n m ngoài ph m vi c a cu n sách này, ngư i c có th tìm hi u t i các tài li u [1] ho c [2]. N u không có lưu ý c bi t thì t t c các chương trình ví d trong cu n sách này u s d ng khai báo s d ng không gian tên std như trên. L nh th hai nh y ra kh i hàm và tr v giá tr 0 làm k t qu c a hàm. ây là bư c có tính ch t quy trình do C++ quy nh hàm main c n tr l i m t giá tr là s nguyên cho bi t tr ng thái k t thúc c a chương trình. Giá tr 0 ư c tr v cu i hàm main có nghĩa r ng hàm ã k t thúc thành công. ý r ng t t các l nh n m bên trong c p ngo c {} c a thân hàm u ư c lùi u dòng m t m c. V i C++, vi c này không có ý nghĩa v cú pháp. Tuy nhiên, nó l i giúp cho c u trúc chương trình d th y hơn và chương trình d hi u hơn i v i ngư i l p trình. ây là m t trong các i m quan tr ng trong các quy ư c v phong cách l p trình. Ph l c A s hư ng d n chi ti t hơn v các quy ư c này. 17

n ây ta có th s a chương trình trong Hình 1.3 in ra l i chào "Hello world!" theo các cách khác nhau. Ch ng h n, ta có th in ra cùng m t n i dung như cũ nhưng b ng hai l nh g i cout:
cout << "Hello "; cout << "world!";

ho c in ra l i chào trên nhi u dòng b ng cách chèn vào gi a xâu kí t các kí t xu ng dòng (kí t c bi t ư c kí hi u là \n):
cout << "Hello \n world!\n";

Ph l c B hư ng d n v cách s d ng b công c GNU C++ chương trình.

d ch và ch y

18

Bài t p
1. Trình bày các bư c chính gi i quy t m t bài toán. Phân tích n i dung và c i m chính c a t ng bư c. 2. T i sao c n ph i có chương trình d ch, s khác bi t gi a trình biên d ch và trình thông d ch? Li t kê các ngôn ng l p trình c n có trình biên d ch, và các ngôn ng l p trình c n có trình thông d ch. 3. S khác bi t, ưu i m và như c i m gi a ngôn ng l p trình b c cao và ngôn ng l p trình b c th p? Nêu m t ví d mà nên s d ng ngôn ng l p trình b c th p gi i quy t, và m t ví d mà nên s d ng ngôn ng l p trình b c cao gi i quy t. 4. Trình bày các ngôn ng l p trình b c th p mà b n bi t, nêu ra các i m n i b t c a t ng ngôn ng l p trình ó. 5. Trình bày các ngôn ng l p trình b c cao mà b n bi t, nêu ra các i m n i b t c a t ng ngôn ng l p trình ó. c c

6. Trình bày s khác bi t, ưu i m và như c i m gi a ngôn ng l p trình C và C++. 7. Trình bày các lo i l i thư ng g p khi l p trình. Phân tích t ng lo i l i trên. c i mc a

8. Trình bày 5 ví d v l i logic mà b n có th g p trong l p trình. 9. Làm quen v i môi trư ng l p trình Dev-C++. Li t kê ra các ch c năng chính c a môi trư ng Dev-C++. Tìm hi u và so sánh các môi trư ng l p trình khác cho C và C++. 10. Vi t m t chương trình C++ hi n ra màn hình tên c a b n. S d ng biên d ch dòng l nh b ng b công c GNU C++ d ch và ch y chương trình.

19

Chương 2. Bi n, ki u d li u và các phép toán
a s chương trình không ch có nh ng ho t ng ơn gi n như là hi n th m t xâu kí t ra màn hình mà còn ph i thao tác v i d li u. Trong m t chương trình, bi n là tên c a m t vùng b nh ư c dùng lưu d li u trong khi chương trình ch y. D li u lưu trong m t bi n ư c g i là giá tr c a bi n ó. Chúng ta có th truy nh p, gán hay thay i giá tr c a các bi n, khi bi n ư c gán m t giá tr m i, giá tr cũ s b ghi è lên.
#include <iostream> using namespace std; int total pples; int main() { int number f askets int apple er asket;
Khai báo bi n a phương numberOfBaskets sau ó gán giá tr 5 cho nó Khai báo bi n toàn c c totalApples ki u int

;

cout << " nter number apples per baskets: "; cin >> apple er asket; Gán giá tr nh p t bàn phím cho bi n applePerBasket total pples number f askets apple er asket; cout << " umber of apples is " << total pples; return } ;

Hình 2.1: Khai báo và s d ng bi n.

Hình 2.1 minh h a vi c khai báo và s d ng bi n. Trong ó, các dòng
int total pples; int number f askets int apple er asket; ;

khai báo bi n. total pples, number f askets, và apple er asket là các tên bi n. Các khai báo trên có nghĩa r ng total pples, number f askets, và apple er asket là d li u thu c ki u int, nghĩa là các bi n này s gi giá tr ki u nguyên. Dòng khai báo number f askets có m t i m khác v i hai dòng còn l i, ó là number f askets ư c kh i t o v i giá tr 5. C++ quy nh r ng t t c các bi n u ph i ư c khai báo v i m t cái tên là các dòng

20

và m t ki u d li u trư c khi bi n ó ư c s d ng. Các bi n thu c cùng m t ki u có th ư c khai báo trên cùng m t dòng, cách nhau b i m t d u ph y. Ch ng h n, có th thay hai dòng khai báo cho number f askets, và apple er asket b ng:
int number f askets , apple er asket;

Chương trình trong Hình 2.1 yêu c u ngư i dùng nh p s táo trong m i gi (apple er asket), tính t ng s táo (total pples) v i d ki n ã bi t là s gi táo (number f asket), r i in ra màn hình. C th , dòng
cout << " nter number apples per baskets: ";

in ra màn hình xâu kí t nter number apples per baskets: . ó là l i m i nh p d li u, là hư ng d n dành cho ngư i s d ng chương trình. Dòng ti p theo
cin >> apple er asket;

c d li u ư c ngư i dùng nh p vào t u vào chu n – thư ng là t bàn phím. Khi ch y l nh này, chương trình s i ngư i dùng nh p vào m t giá tr cho bi n apple er asket. Ngư i dùng áp ng b ng cách gõ vào m t s nguyên dư i d ng chu i các ch s r i nh n phím Enter g i các ch s ó cho máy tính. n lư t nó, máy tính bi n i chu i các ch s nó nh n ư c thành m t giá tr ki u nguyên r i chép giá tr này vào bi n apple er asket. Tương ng v i cout là i tư ng qu n lý dòng d li u ra chu n c a thư vi n C++, cin là i tư ng qu n lý dòng d li u vào chu n, thư ng là t bàn phím. Ti p theo là l nh gán
total pples number f askets apple er asket;

L nh này tính tích giá tr c a hai bi n number f askets và apple er asket r i gán k t qu cho bi n total pples, trong ó là kí hi u c a phép nhân và là kí hi u c a phép gán. L nh in k t qu ra màn hình
cout << " umber of apples is " << total pples;

hi n th liên ti p hai thành ph n: xâu kí t " umber of apples is " và giá tr c a bi n total pples.

21

Ngoài vi c in giá tr c a m t bi n, C++ còn cho phép ta in k t qu c a m t bi u th c. Do ó, ta có m t l a ch n khác là g p công vi c c a hai l nh trên (tính tích hai bi n và in tích ra màn hình) vào m t l nh:
cout << " umber of apples is " << number f askets apple er asket;

Khi ó, bi n total pples v n ư c dùng lưu tr k t qu c a phép tính tr nên không còn c n thi t, ta có th xóa b dòng khai báo bi n này. ý là l nh trên dài và chi m c sang dòng th hai. C++ cho phép m t l nh n m trên nhi u dòng, d u ch m ph y cu i m i l nh s giúp trình biên d ch hi u âu là k t thúc c a l nh.

2.1. Ki u d li u
M i bi n ph i ư c khai báo lưu gi giá tr thu c m t ki u d li u nào ó. Ngôn ng l p trình b c cao thư ng có hai lo i ki u d li u: các ki u d li u cơ b n và các ki u d li u d n xu t. 2.1.1. Ki u d li u cơ b n Ki u d li u cơ b n là ki u d li u do ngôn ng l p trình nh nghĩa s n. Ví d như các ki u s nguyên – char, int, long int. Bi n thu c ki u nguyên ư c dùng lưu các s có giá tr nguyên. i v i ki u cơ b n chúng ta thư ng quan tâm n kích thư c b nh c a ki u d li u, gi i h n giá tr mà ki u d li u ó có th lưu gi . i v i các ki u d u ch m ng (floating-point) lưu các giá tr thu c ki u s th c, chúng ta còn quan tâm n chính xác c a ki u d li u ó. Tài li u chu n C++ không quy nh chính xác s byte c n dùng lưu các bi n thu c các ki u d li u cơ b n trong b nh mà ch quy nh yêu c u v kích thư c c a ki u d li u này so v i ki u d li u kia. Các ki u nguyên có d u, signed char, short int, int và long int, ph i có kích thư c tăng d n. M i ki u nguyên có d u tương ng v i m t ki u nguyên không d u v i cùng kích thư c. Các ki u nguyên không d u không th bi u di n giá tr âm nhưng có th bi u di n s giá tr dương nhi u g p ôi ki u có d u tương ng. Tương t , các ki u ch m ng, float, double và long double cũng ph i có kích thư c tăng d n. B ng 2.1 li t kê m t s ki u d li u cơ b n c a C++ v i kích thư c ư c nhi u b n cài t C++ s d ng.

22

Ki u

Mô t

Kích thư c thông d ng (byte)

Ph m vi (tương ng v i kích thư c)

char

ký t / s nguyên nh giá tr Boolean s nguyên

1

các kí t ASCII signed char: -128 → 127, ho c unsighed char: 0 → 255 true ho c false signed short: -32767→ 32767 unsigned short: 0→ 65536 signed int: 2147483648 → 2147483647 unsigned int: 0 → -4294967296 signed long: 2147483648 → 2147483647 unsigned long: 0 → -4294967296

bool short

1 2

int

s nguyên l n s nguyên r tl n s th c s th c v i chính xác cao s th c v i chính xác r t cao

4

long float double

4 4 8

+/- 1.4023x10-45 → 3.4028x10+38 +/- 4.9406x10-324 → 1.7977x10308

long double

8

+/- 4.9406x10-324 → 1.7977x10308

B ng 2.1: M t s ki u d li u cơ b n trong C++.

M t s lưu ý: • Kích thư c và ph m vi c a các ki u d li u cơ b n ph thu c vào h th ng mà chương trình ư c biên d ch t i ó. Tuy nhiên, t t c các h th ng, ki u char bao gi cũng có kích thư c là 1 byte; các ki u d li u char, short, int, long ph i có kích thư c tăng d n; còn các ki u float, double, long double ph i có chính xác cao d n. • Ki u char dùng lưu các kí t ơn (có mã nh hơn 256), ch ng h n như ch cái La-tinh, ch s , hay các kí hi u. Trong C++, m t kí t ơn ư c óng trong c p nháy ơn, ví d ' '. lưu các kí t có mã l n hơn 255, ta có th s d ng ki u wchar_t. 23

• Ki u d li u bool ch có hai giá tr true và false. Ta có th dùng bi n thu c ki u này lưu câu tr l i c a nh ng câu h i úng/sai ch ng h n như "Có ph i index l n hơn 100?" hay lưu các tr ng thái "Ta ã tìm th y giá tr âm chưa?". Các giá tr true và false trong C++ th c ra ch là 0 và 1. 2.1.2. Ki u d li u d n xu t Ki u d li u d n xu t là ki u d li u ư c xây d ng t các ki u d li u cơ b n b ng các toán t như * (con tr ), & (tham chi u), [] (m ng), () hàm, ho c ư c nh nghĩa b ng cơ ch struct hay class. Các ki u d li u ư c nh nghĩa b ng cơ ch struct hay class còn ư c g i là các ki u d li u có c u trúc ho c ki u d li u tr u tư ng. Chi ti t v các ki u d li u d n xu t s ư c trình bày d n d n trong các chương sau.

2.2. Khai báo và s d ng bi n
b t u s d ng m t bi n, chúng ta ph i ti n hành hai bư c: m t cái tên h p l và khai báo bi n. 2.2.1. nh danh và cách t tên bi n t cho bi n

nh danh (identifier) là thu t ng trong ngôn ng l p trình khi nói n tên (tên bi n, tên hàm, tên l p…). nh danh là m t chu i kí t (bao g m các ch cái a..z, A..Z, ch s 0..9, d u g ch chân ‘_’) vi t li n nhau. nh danh không ư c b t u b ng ch s và không ư c trùng v i các t khóa (nh ng t mang ý nghĩa c bi t) c a ngôn ng l p trình. Lưu ý, C++ phân bi t ch cái hoa và ch cái thư ng. Cách t tên bi n tuân th theo cách t tên nh danh. Ví d v các tên bi n:

• _sinhvien, sinhvien_ 1, sinhVien_ 1 là các tên bi n h p l khác nhau •
1sinhvien, sinhviên, "sinhvien" là các tên bi n không h p l

Tên bi n nên d c, và g i nh n công d ng c a bi n hay ki u d li u mà bi n s lưu tr . Ví d , n u c n dùng m t bi n lưu s lư ng qu táo, ta có th t tên là total pples. Không nên s d ng các tên bi n ch g m m t kí t và không có ý nghĩa như a hay b.

24

2.2.2. Khai báo bi n Các ngôn ng l p trình nh ki u m nh, trong ó có C++, yêu c u m i bi n trư c khi dùng ph i ư c khai báo và bi n ph i thu c v m t ki u d li u nào ó. Có th chia các bi n thành hai lo i: • các bi n ư c khai báo ngoài t t c các chương trình con là bi n toàn c c, có hi u l c trên toàn b chương trình, ch ng h n bi n total pples trong Hình 2.1. • các bi n ư c khai báo t i m t chương trình con là bi n a phương, có hi u l c bên trong chương trình con ó, ch ng h n number f askets và apple er asket trong Hình 2.1 là các bi n a phương c a hàm main và ch có hi u l c bên trong hàm main. Chương 4 s nói kĩ hơn v hai lo i bi n trên. Trong C++, bi n có th ư c khai báo g n như b t c âu trong chương trình, mi n là trư c dòng u tiên s d ng n bi n ó (xem Hình 2.1). M t bi n a phương ã ư c khai báo nhưng chưa ư c gán m t giá tr nào ư c g i là bi n chưa ư c kh i t o. Giá tr c a bi n chưa ư c kh i t o thư ng là không xác nh. tránh tình tr ng này, ta có th kh i t o giá tr c a các bi n b ng cách gán giá tr ngay t i l nh khai báo bi n.

2.3. H ng
H ng là m t lo i bi n c bi t mà giá tr c a nó ư c xác nh t i th i i m khai báo và không ư c thay i trong su t chương trình. khai báo m t h ng, ta thêm t khóa const vào phía trư c l nh khai báo bi n. Ví d :
const float I const float SCR 3.141 926 3 ; _WIDTH 317.24;

H ng ư c dùng t tên cho các giá tr không thay i ư c dùng trong chương trình, ch ng h n như r ng màn hình như trong ví d trên. Công d ng c a h ng là m i khi c n thay i giá tr ó, ta ch c n s a l nh khai báo h ng thay vì tìm và s a giá tr tương ng t i t t c các v trí dùng n nó. Ngoài ra, m t cái tên có ý nghĩa t cho m t giá tr ư c dùng i dùng l i s giúp cho chương trình d c và d hi u hơn.

25

2.4. Các phép toán cơ b n
2.4.1. Phép gán Phép gán là cách g n m t giá tr cho m t bi n ho c thay bi n. L nh gán trong C++ là: bi n = bi u th c; trong ó d u b ng (“=”) ư c g i là d u gán hay toán t gán. Lưu ý, d u b ng trong C++ không dùng so sánh giá tr như trong m t s ngôn ng l p trình khác. Ví d
symbol ' ';

i giá tr c a m t

là phép gán giá tr ‘A’ cho bi n symbol, không ph i là bi u th c so sánh xem giá tr c a symbol có ph i là 'A' hay không. Công vi c c a phép gán là tính giá tr c a bi u th c bên ph i d u gán r i lưu giá tr ó vào trong bi n n m bên trái d u gán. Bi u th c có th là m t s , m t bi n, ho c m t bi u th c ph c t p. Lưu ý r ng m t bi n có th xu t hi n c hai bên c a d u gán. Ví d l nh sau tăng giá tr c a bi n apples thêm 2.
apples apples + 2;

i m c bi t c a C++ là b n thân phép gán cũng chính là m t bi u th c v i giá tr tr v là k t qu c a phép gán. Ví d , phép gán x = 3 là m t bi u th c có giá tr b ng 3. 2.4.2. Các phép toán s h c C++ h tr năm phép toán s h c sau: + (c ng), - (tr ), (nhân), / (chia), % (modulo – l y ph n dư c a phép chia). Phép chia ư c th c hi n cho hai giá tr ki u nguyên s cho k t qu là thương nguyên. Ví d bi u th c 4 / 3 cho k t qu b ng 1, còn 3 / 5 cho k t qu b ng 0. M t s phép gán kèm theo bi u th c xu t hi n nhi u l n trong m t chương trình, vì v y C++ cho phép vi t các phép gán bi u th c ó m t cách g n ng n hơn, s d ng các phép gán ph c h p (+ , - , , / , % , >> , << , & , ^ , | ). Cách s d ng phép gán ph c h p + như sau: bi n += bi u th c; tương ương bi n = bi n + bi u th c; 26

Ví d :
apples + 2; tương ương apples apples + 2;

Các phép gán ph c h p khác ư c s d ng tương t . C++ còn cung c p các phép toán ++ (hay --) m t ơn v . Ví d : tăng (gi m) giá tr c a bi n lên

apples++ hay ++apple có tác d ng tăng apples thêm 1 ơn v apples-- hay --apple có tác d ng gi m apples i 1 ơn v

Khác bi t gi a vi c vi t phép tăng/gi m trư c bi n (tăng/gi m trư c) và vi t phép tăng/gi m sau bi n (tăng/gi m sau) là th i i m th c hi n phép tăng/gi m, th hi n giá tr c a bi u th c. Phép tăng/gi m trư c ư c th c hi n trư c khi bi u th c ư c tính giá tr , còn phép tăng/gi m sau ư c th c hi n sau khi bi u th c ư c tính giá tr . Ví d , n u apples v n có giá tr 1 thì các bi u th c ++apples hay apples++ u có hi u ng là apples ư c tăng t 1 lên 2. Tuy nhiên, ++apples là bi u th c có giá tr b ng 2 (tăng apples trư c tính giá tr ), trong khi apples++ là bi u th c có giá tr b ng 1 (tăng apples sau khi tính giá tr bi u th c). N u ta ch quan tâm n hi u ng tăng hay gi m c a các phép ++ hay – thì vi c phép toán ư c t trư c hay t sau không quan tr ng. ó cũng là cách dùng ph bi n nh t c a các phép toán này. Lưu ý, c n h t s c c n th n khi s d ng các phép tăng và gi m trong các bi u th c. Vi c này không ư c khuy n khích vì tuy nó có th ti t ki m ư c m t hai dòng l nh nhưng l i làm gi m tính trong sáng c a chương trình. 2.4.3. Các phép toán quan h so sánh giá tr hai bi u th c. Các phép Các phép toán quan h ư c s d ng toán này cho k t qu b ng 0 n u úng và khác 0 n u sai. Ta s d ng giá tr c a m t bi u th c quan h như là m t giá tr thu c ki u bool. Ví d :
bool enough pples (total pples > 1 );

Các phép toán quan h trong ngôn ng C++ ư c li t kê trong B ng 2.2.

27

Ký hi u toán h c
> <

Toán t c a C++
> < > < !

Ví d
x > y x < y x > y x < x x ! y y y

Ý nghĩa
x l n hơn y x nh hơn y x l n hơn ho c b ng y x nh hơn ho c b ng y x b ng y x khác y

≥ ≤ ≠

B ng 2.2: Các phép toán quan h .

Chú ý tránh nh m l n gi a phép gán giá tr “ ” và phép so sánh b ng “ ”. Nh ng nh m l n gi a các phép toán ki u này thư ng d n n nh ng l i lôgic r t khó phát hi n. 2.4.4. Các phép toán lô-gic
Toán t C++
&

Ý nghĩa and

Ví d
x && y

Ý nghĩa c a ví d Cho giá tr úng khi c x và y úng, ngư c l i cho giá tr sai. Cho giá tr úng khi ho c x úng ho c y úng, ngư c l i cho giá tr sai Ph nh c a x. Cho giá tr cho giá tr sai khi x úng úng khi x sai;

||

or

x || y

!

not

!x

B ng 2.3: Các phép toán lô-gic.

Các phép toán lô-gic dành cho các toán h ng là các bi u th c quan h ho c các giá tr bool. K t qu c a bi u th c lôgic là giá tr bool. Ví d :
bool enough pples (apples > 3) && (apples < 1 );

có k t qu là bi n enough pples nh n giá tr là câu tr l i c a câu h i "bi n apples có giá tr l n hơn 3 và nh hơn 10 hay không?". 2.4.5. ưu tiên c a các phép toán ưu tiên c a m t s phép toán thư ng g p. Th t c a chúng

Dư i ây là m c như sau:

28

Các phép toán n m trong c p d u ngo c ( ) có 2 * (1 + 3) cho k t qu b ng 8 Các phép toán , /, +, -. Trong ó , / có Ví d : 2 * 1 + 3 cho k t qu là 5 Các phép toán so sánh <, >, <=, >=. Ví d : 3 + 4 < 2 + 6 cho k t qu úng

ưu tiên l n nh t. Ví d :

ưu tiên như nhau và cao hơn +, -.

Các phép toán lô-gic có th th t ưu tiên như sau: !, &&, ||. Ví d : 1 || 0 && 0 tương ương v i 1 || (0 && 0) và cho k t qu 1 2.4.6. Tương thích gi a các ki u V cơ b n, giá tr gán cho m t bi n nên cùng ki u v i bi n ó. Khi m t bi n ư c gán m t giá tr không úng v i ki u d li u c a bi n ó, thì giá tr ó s ư c chuy n i sang ki u c a bi n (type conversion). M t vài trư ng h p thư ng g p trong vi c chuy n ki u là: Chuy n i gi a s th c và s nguyên
// x nh n giá tr 2 // y nh n giá tr 3, // x nh n giá tr 3

int x 2. ; double y 3. ; x y;

Phép chia c a s nguyên
int divisor 4; int dividend 6; int quo dividend/divisor;

// quo nh n giá tr

1.

Lưu ý: Phép chia m t s nguyên cho m t s nguyên s cho k t qu là m t s nguyên. Mu n k t qu là m t s th c thì ít nh t m t trong hai s ph i là s th c.

29

Bài t p
1. Vi t chương trình tính di n tích c a m t hình tròn. Bán kính là m t s th c và ư c nh p vào t bàn phím. Di n tích hình tròn ư c hi n ra màn hình. 2. Nh p t bàn phím hai s nguyên là chi u cao c a Peter và Essen. Hãy tính xem Peter cao g p bao nhiêu l n Essen. Ví d , n u chi u cao c a Peter là 180, chi u cao c a Essen là 150, thì hi n ra màn hình dòng ch “Peter is 1.2 times as tall as Essen”. 3. Nh p t bàn phím m t s nguyên là nhi t hãy hi n ra màn hình nhi t dư i d ng hi u công th c chuy n i. dư i d ng F (Fahrenheit), C (Celsius). Sinh viên t tìm

4. Vi t m t chương trình trong ó có hai h ng s WIDTH v i giá tr b ng 3.17654, và h ng s LENGTH v i giá tr b ng 10.03212. Tính và hi n ra màn hình di n tích c a hình ch nh t v i hai c nh là WIDTH và LENGTH. 5. Nh p t bàn phím b n s nguyên a, b, c, d. Hãy tính và hi n ra màn hình giá tr c a bi u th c: (a + b) > (c + d) || (a - b) > (c - d) 6. Trình bày s khác bi t gi a bi n a phương và bi n toàn c c. Khi nào thì nên dùng bi n a phương, khi nào thì nên dùng bi n toàn c c. Nêu các lưu y khi s d ng bi n toàn c c. 7. Vi t m t chương trình có ch a hai bi n: bi n a phương bonus và bi n toàn c c score. Nh p giá tr hai bi n t bàn phím, tính và hi n ra màn hình t ng c a score và bonus. 8. Hãy tính (không dùng chương trình) giá tr c a các bi u th c sau: a) 1 + 3 < 2 * 4 – 1 && 1 b) 2 * 2 – 1 + 5 / 1 & 4 – 3 c) (2 – 3 * 1) && 0 / 5 * 2 + 1 9. Tính giá tr c a bi n c t o n chương trình sau:

a) int a = 3; int b = 2; int c = a/b; b) double a = 3.1; int b = 2; int c = a/b;

30

c) int a = 3; int b = 2; double c = a/b; 10. Nh p hai s nguyên dương x và y t bàn phím, hãy tính: a) Thương c a phép toán x chia cho y b) Tích c a phép toán x nhân y c) Ph n nguyên c a x chia cho y d) Ph n dư c a x chia cho y 11. Nh p t bàn phím 3 s th c x, y, và z. Hãy tính a) Trung bình c ng c a ba s trên b) Hi n ra màn hình s 1 n u x là s l n nh t trong ba s trên, ngư c l i hi n ra màn hình s 0. c) Hi n ra màn hình s 1 n u z là s nh trong ba s trên, ngư c l i hi n ra màn hình s 0. 12. Tính giá tr (không dùng chương trình) c a bi u th c so sánh dư i ây: a) x = 1; y = 2; x++ < y b) x = 2; y = 1; x-- < y++ c) x = 2; y = 2; x++ == y

31

Chương 3. Các c u trúc i u khi n
Như ã nói ph n trên, chương trình máy tính mà chúng ta l p trình t o ra th c ch t là m t t p các l nh. Các chương trình ư c vi t b ng ngôn ng b c cao thư ng ch a m t hàm chính (trong C++ là hàm main), nơi chương trình b t u th c hi n các l nh. Trong chương này chúng ta s tìm hi u th t th c hi n các l nh trong m t chương trình.

3.1. Lu ng i u khi n
Lu ng i u khi n c a chương trình là th t các l nh (hành ng) mà chương trình th c hi n. Cho n chương này, chúng ta m i g p th t ơn gi n: th t tu n t , nghĩa là các hành ng ư c th c hi n úng theo th t mà chúng ư c vi t trong chương trình. Ví d , Hình 3.1 là sơ minh h a m t c u trúc tu n t i n hình, trong ó hai hành ng và các mũi tên bi u di n th t th c hi n các hành ng.

Hình 3.1: Sơ

chuy n tr ng thái c a m t o n l nh có th t th c thi tu n t .

Trong chương này, ta s làm quen v i các lu ng i u khi n ph c t p hơn. H u h t các ngôn ng l p trình, trong ó có C++, cung c p hai lo i l nh ki m soát lu ng i u khi n: • l nh r nhánh (branching) ch n m t hành hành ng. ng t danh sách g m nhi u ng cho n khi m t

• l nh l p (loop) th c hi n l p i l p l i m t hành i u ki n d ng nào ó ư c th a mãn. 32

Hai lo i l nh ó t o thành các c u trúc i u khi n (control structure) bên trong chương trình.

3.2. Các c u trúc r nhánh
3.2.1. L nh if-else L nh if-else (hay g i t t là l nh if) cho phép r nhánh b ng cách l a ch n th c hi n m t trong hai hành ng. Ví d , trong m t chương trình x p lo i i m thi, n u i m c a sinh viên nh hơn 60, sinh viên ó ư c coi là trư t, n u không thì ư c coi là .

[score < 60]

[score >= 60]

in "Failed"

in "Passed"

Hình 3.2: Sơ

m t l nh if.

Thu t toán nh này ư trám bi u di n i m r theo hư ng nào. T i m t i u ki n. Lu ng ư c th a mãn.

c th hi n b ng sơ trong Hình 3.2. Trong ó hình qu nhánh, nơi chương trình ưa ra quy t nh xem nên r m r nhánh có các mũi tên i ra, m i mũi tên kèm theo i u khi n s i theo mũi tên nào mà i u ki n c a nó

Cũng có th trình bày thu t toán b ng mã gi như sau: If student’s score is less than 60 print “Failed” else print “Passed” Th hi n thu t toán trên b ng m t l nh if-else c a C++, ta có o n mã:

33

if (score < 6 ) cout << "Failed"; else cout << " assed";

Khi chương trình ch y m t l nh if-else, u tiên nó ki m tra bi ki n n m trong c p ngo c ơn sau t khóa if. N u bi u th c có true thì l nh n m sau t khóa if s ư c th c hi n. Ngư c l i, l else s ư c th c hi n. Chú ý là bi u th c i u ki n ph i ư c c p ngo c ơn.
#include <iostream> using namespace std; int main() { int score; cout << " nter your score: "; cin >> score; //get the score from the keyboard

u th c i u giá tr b ng nh n m sau t trong m t

if (score < 6 ) cout << "Sorry. ou ve failed the course.\n"; else cout << "Congratulations! ou ve passed the course.\n"; return } ươ ;

Hình 3.3: Ví d v c u trúc

-

.

Chương trình ví d trong Hình 3.3 yêu c u ngư i dùng nh p i m r i in ra các ho c trư t. ý r ng các l nh n m thông báo khác nhau tùy theo i m s bên trong kh i c n ư c lùi u dòng m t m c chương trình trông sáng s a d c.

34

Trong c u trúc r nhánh , ta có th b ph n n u không mu n chương trình th c hi n hành ng nào n u i u ki n không th a mãn. Ch ng h n, n u mu n thêm m t l i khen c bi t cho i m s xu t s c t 90 tr lên, ta có th thêm l nh sau vào trong chương trình t i Hình 3.3.
( >= 9 ) << " x ";

Ta có th dùng các c u trúc l ng nhau t o ra i u ki n r nhánh ph c t p. Hình 3.3 là m t ví d ơn gi n v i ch hai trư ng h p và m t l nh . Xét m t ví d ph c t p hơn: cho trư c i m s (lưu t i bi n ki u ), xác nh x p lo i h c l c A, B, C, D, F tùy theo i m ó. Quy t c x p lo i là: n u i m t 90 tr lên thì t lo i A, i m t 80 t i dư i 90 t lo i B, v.v.. T i o n mã xét các trư ng h p c a x p lo i i m, ta có th dùng c u trúc l ng nhau như sau:
( >= 9 ) = 'A'; ( >= 8 ) = 'B'; ( >= ) = ' '; ( >= 6 ) = 'D'; = 'F';

ý r ng m i kh i l nh sau n m trong ph n li n trư c. N u không dư i 90, i u ki n c a c u cho k t qu . Tuy nhiên, do i u ki n c a l nh th a mãn, ch có l nh gán u tiên = 'A' ư c th ph n c a l nh ngoài cùng, bao g m ba l nh b qua.

c a kh i l nh b n l nh ngoài cùng c thi, còn toàn b còn l i, b

V i các kh i l nh l ng nhau như trên, khi ph i lùi u dòng quá xa v bên ph i, dòng còn l i quá ng n khi n m i l nh có th ph i tr i trên vài dòng, d n n vi c chương trình khó c. Do ó, a s l p trình viên C++ thư ng

35

dùng ki u lùi u dòng như dư i ây. (Hai cách lùi i v i trình biên d ch vì nó b qua các kí t tr ng.)
( >= 9 ) = 'A'; ( >= 8 ) = 'B'; ( >= ) = ' '; ( >= 6 ) = 'D'; = 'F';

u dòng này là như nhau

Hình 3.4 là chương trình hoàn ch nh th c hi n nhi m v yêu c u ngư i dùng nh p i m s sau ó tính và in ra x p lo i h c l c tương ng.

36

<

> ;

() ; ; << " >> ( "; ;

>= 9 ) = 'A'; ( >= 8 ) = 'B'; ( >= ) = ' '; ( >= 6 ) = 'D'; = 'F'; << " ;
Hình 3.4: C u trúc if-else l ng nhau.

= " <<

<<

;

M t i u c n c bi t lưu ý là n u mu n th c hi n nhi u hơn m t l nh trong m i trư ng h p c a l nh , ta c n dùng c p ngo c {} b c t p l nh ó thành m t kh i chương trình. Ví d , phiên b n ph c t p hơn c a l nh trong Hình 3.3:

37

(

< 6 ) << "F << "

" << k

; " << ;

<< " << "

" << ";

;

tránh l i quên c p ngo c, có m t l i khuyên là t p thói quen dùng c p ngo c ngay c khi kh i l nh ch bao g m úng m t l nh. Ch ng h n, xét kh i l nh l ng nhau dư i ây:
( ( == 'A') == 'A') << " << " '

w

A' A

" <<

; " << ;

Thông báo trong ph n áng ra c n ư c th c thi khi x p h ng c a môn Toán ( ) không t A. Tuy nhiên, trong th c t , trình biên d ch l i hi u r ng ph n ó cùng c p v i l nh th hai – l nh g n nh t, nghĩa là:
( ( == 'A') == 'A') << " << " '

w

A'

" << A

; " << ;

Các l i lôgic d ng này thư ng khó phát hi n. i v i C++, vi c lùi u dòng ch nh m m c ích l p trình viên d c chương trình ch không có ý nghĩa v i trình biên d ch. Cách gi i quy t là s d ng c p ngo c {} ch rõ cho trình biên d ch r ng l nh th hai n m trong l nh ngoài cùng và r ng ph n cùng c p v i l nh ngoài cùng ó:

38

( (

== 'A') == 'A') << "

w

A'

" <<

;

<< "

'

A

" <<

;

3.2.2. L nh swi Khi chúng ta mu n vi t m t c u trúc r nhánh có nhi u l a ch n, ta có th s d ng nhi u l nh l ng nhau. Tuy nhiên, trong trư ng h p vi c l a ch n r nhánh ph thu c vào giá tr (ki u s nguyên ho c kí t ) c a m t bi n hay bi u th c, ta có th s d ng c u trúc w chương trình d hi u hơn. L nh w i n hình có d ng như sau:
w (bi u_th c)

h ng_1 t p_l nh_1; b h ng_2 t p_l nh_2; b

k; k;

t p_l nh_m c_ nh; Khi l nh w ư c ch y, bi u_th c ư c tính giá tr và so sánh v i h ng_1. N u b ng nhau, chu i l nh k t t p_l nh_1 ư c th c thi cho n khi g p l nh b k u tiên, n ây chương trình s nh y t i i m k t thúc c u trúc w . N u bi u_th c không có giá tr b ng h ng_1, nó s ư c so sánh v i h ng_2, n u b ng nhau, chương trình s th c thi chu i l nh k t t p_l nh_2 t i khi g p l nh b k u tiên thì nh y t i cu i c u trúc w . Quy trình c ti p di n như v y. Cu i cùng, n u bi u_th c có giá tr khác v i t t c các giá tr ã ư c li t kê (h ng_1, h ng_2, ...), chương trình s th c thi t p_l nh_m c_ nh n m n u như có nhãn này (không b t bu c). sau nhãn Ví d , l nh sau so sánh giá tr c a bi n v i các h ng kí t 'A', 'B', 'C' và in ra các thông báo khác nhau cho t ng trư ng h p.

39

w

( 'A'

) << " 'B' << " ' ' << " << " = "; b k; A, B, "; = B"; b k; = A"; b k;

Nó tương ương v i kh i l nh
(

-

l ng nhau sau:

== 'A') << " = A"; ( == 'B') << " = B"; ( == ' ') << " = "; << " A, B, ";

Lưu ý, các nhãn trong c u trúc w ph i là h ng ch không th là bi n hay bi u th c. N u c n so sánh v i bi n hay bi u th c, ta nên dùng kh i l nh l ng nhau. V n c bi t c a c u trúc w là các l nh b k. N u ta không t g n m t l nh b k vào cu i chu i l nh c n th c hi n cho m i trư ng h p, chương trình s ch y ti p chu i l nh c a trư ng h p sau ch không t ng nh y t i cu i c u trúc w . Ví d , o n chương trình sau s ch y l nh in th nh t n u grade nh n m t trong ba giá tr 'A', 'B', 'C' và ch y l nh in th hai trong trư ng h p còn l i:

40

w

( 'A' 'B' ' '

)

<< " << "

A, B A, B

"; b ";

k;

Chương trình trong Hình 3.5 là m t ví d hoàn ch nh s d ng c u trúc w in ra các thông báo khác nhau tùy theo x p lo i h c l c ( ) mà ngư i dùng nh p t bàn phím. Trong ó, 'A' k t thúc v i b k sau ch m t l nh, còn 'B' ch y ti p qua ' ', 'D' r i m i g p b k và thoát . Nhãn ư c dùng x lý trư ng h p bi n grade gi kh i l nh w giá tr không h p l i v i x p lo i h c l c. Trong nhi u chương trình, ph n thư ng ư c dùng x lý các trư ng h p không mong i, ch ng h n như b t l i các kí hi u h c l c không h p l mà ngư i dùng có th nh p sai trong Hình 3.5.

41

<

> ;

() ; << " >> w ( 'A' << " x 'B' << " ' ' 'D' << " 'F' << " << " , "; b "; k; "; b k; "; "; b k; "; ; )

;

}
ươ
A x B

D

F ,
Hình 3.5: Ví d s d ng c u trúc switch.

42

3.3. Các c u trúc l p
Các chương trình thư ng c n ph i l p i l p l i m t ho t ng nào ó. Ví d , m t chương trình x p lo i h c l c s ch a các l nh r nhánh gán x p lo i A, B, C… cho m t sinh viên tùy theo i m s c a sinh viên này. x p lo i cho c m t l p, chương trình s ph i l p l i thao tác ó cho t ng sinh viên trong l p. Ph n chương trình l p i l p l i m t l nh ho c m t kh i l nh ư c g i là m t vòng l p. L nh ho c kh i l nh ư c l p i l p l i ư c g i là thân c a vòng l p. C u trúc l p cho phép l p trình viên ch th cho chương trình l p i l p l i m t ho t ng trong khi m t i u ki n nào ó v n ư c th a mãn. Khi thi t k m t vòng l p, ta c n xác nh thân vòng l p th c hi n hành ng gì. Ngoài ra, ta còn c n m t cơ ch quy t nh khi nào vòng l p s k t thúc. M c này s gi i thi u v các l nh l p mà C++ cung c p. 3.3.1. Vòng w ile Vòng w ile l p i l p l i chu i hành ng, g i là thân vòng l p, n u như i u ki n l p v n còn ư c th a mãn. Cú pháp c a vòng l p w như sau:
w ( i u_ki n_l p)

thân_vòng_l p C u trúc này b t u b ng t khóa w , ti p theo là i u ki n l p t trong m t c p ngo c ơn, cu i cùng là thân vòng l p. Thân vòng l p hay ch a nhi u hơn m t l nh và khi ó thì ph i ư c gói trong m t c p ngo c {}. , u tiên chương trình ki m tra giá tr c a bi u Khi th c thi m t c u trúc w th c i u ki n, n u bi u th c cho giá tr (th c ch t là b ng 0) thì nh y n i m k t thúc l nh w , còn n u i u ki n l p có giá tr (th c ch t là m t giá tr nào ó khác 0) thì ti n hành th c hi n t p l nh trong thân vòng l p r i quay tr l i ki m tra i u ki n l p, n u không th a mãn thì k t thúc, n u th a mãn thì l i th c thi thân vòng l p r i quay l i... T p l nh thân vòng l p có th làm thay i giá tr c a bi u th c i u ki n t sang (th c ch t là t khác 0 sang b ng 0) d ng vòng l p. Ví d , xét m t chương trình có nhi m v m t 1 n m t ngư ng trư c. o n mã m t 1 n b có th ư c vi t như sau:
b

cho

43

w

= 1; ( << ++;

<=

b

)

<< ", ";

Gi s bi n b có giá tr b ng 2, o n mã trên ho t ng như sau: u tiên, bi n ư c kh i t o b ng 1. Vòng while b t u b ng vi c ki m tra i u ki n ( <= b ), nghĩa là 1 ≤ 2, i u ki n th a mãn. Thân vòng l p ư c th c thi l n th nh t: giá tr 1 c a ư c in ra màn hình kèm theo d u ph y, sau ó ư c tăng lên 2. Vòng l p quay v i m xu t phát: ki m tra i u ki n l p, gi là 2 ≤ 2, v n th a mãn. Thân vòng l p ư c ch y l n th hai (in giá tr 2 c a và tăng lên 3) trư c khi quay l i i m xu t phát c a vòng l p. T i l n ki m tra i u ki n l p này, bi u th c 3 ≤ 2 cho giá tr , vòng l p k t thúc do i u ki n l p không còn ư c th a mãn, chương trình ch y ti p l nh n m sau c u trúc w ang xét. trong o n mã trên có th ư c bi u di n b ng sơ trong Hình C u trúc w 3.6. Trong sơ , mũi tên sau chu i hành ng in bi n và tăng bi n quay ngư c tr l i i m ki m tra i u ki n r nhánh, chu i hành ng s l p l i n u i u ki n <= b v n ti p t c ư c th a mãn. Còn n u > b , vòng while i n i m k t thúc, trao i u khi n cho l nh ti p theo trong chu i l nh c a chương trình.

Hình 3.6: Sơ

m t vòng l p while.

Chương trình hoàn ch nh trong Hình 3.7 minh h in ra các s nguyên (bi n ) t 1 cho dùng nh p vào t bàn phím (lưu t i bi n b l n ch y khác nhau v i các giá tr khác nhau c 44

a cách s d ng vòng l p w n m t ngư ng giá tr do ngư i ). Kèm theo là k t qu c a các a b . c bi t, khi ngư i

dùng nh p giá tr 0 cho b , thân vòng w không ch y m t l n nào, th hi n vi c không m t s nào ư c in ra màn hình. Lí do là vì n u b b ng 0 thì bi u th c <= b ngay t u vòng w ã có giá tr .
< > ;

() , << " >> b = 1; ( << ++; << "B ; b ; b ; ";

w

<=

b

)

<< ", ";

" <<

;

ươ
b 1, , B b 1, B b B
Hình 3.7: Ví d v vòng l p while.

1

Vòng l p vô t n M t trong nh ng l i chương trình thư ng g p là m t vòng l p không th k t thúc, thân vòng l p ó ư c l p i l p l i mà không bao gi ng ng. M t vòng l p như v y ư c g i là vòng l p vô t n. Thông thư ng, m t vài l nh trong thân m t vòng w hay -w s làm thay i giá tr c a m t vài bi n bi u th c i u ki n cho giá tr (ho c 0), ch ng h n l nh tăng bi n m 45

trong Hình 3.7. N u (các) bi n ó không ư c thay i giá tr m t cách thích h p ho c khi i u ki n l p ư c vi t không chính xác (có th do thu t toán sai hay nh m l n khi vi t mã chương trình), ta s nh n ư c m t vòng l p vô t n do i u ki n l p không bao gi nh n giá tr . Hình 3.8 minh h a m t vòng l p vô t n khi bi n tăng d n n vô h n nhưng luôn nh n giá tr l và không bao gi có th có giá tr b ng 12 k t thúc vòng l p w . ây có th g i là l i lô-gic. N u o n chương trình có nhi m v tính t ng các s 1, 3, 5, 7, 9, 11 thì i u ki n l p nên ư c s a thành ( < 1 ) chương trình có th ch y úng.
< > ; , ; = 1; w ( = = ; = 1 ) + + )

(

; ;

}
Hình 3.8: Ví d v vòng l p vô t n.

3.3.2. Vòng do-w ile Vòng do-w ile r t gi ng v i vòng w , khác bi t chính là ch thân vòng l p s ư c th c hi n trư c, sau ó m i ki m tra i u ki n l p, n u úng thì quay l i ch y thân vòng l p, n u sai thì d ng vòng l p. Khác bi t ó có nghĩa r ng thân c a vòng -w luôn ư c ch y ít nh t m t l n, trong khi thân vòng w có th không ư c ch y l n nào.

46

Công th c c a vòng

-w

t ng quát là:

thân_vòng_l p w ( i u_ki n_l p); Tương t như vòng w , thân_vòng_l p c a vòng -w có th ch g m m t l nh ho c thư ng g p hơn là m t chu i l nh ư c b c trong m t c p ngo c {}. Lưu ý d u ch m ph y t cu i toàn b kh i -w . Công th c t ng quát c a vòng n u dùng vòng w : thân_vòng_l p w ( i u_ki n_l p) thân_vòng_l p minh h a ho t o n mã dư i ây:
w -w

trên tương ương v i công th c sau

ng c a hai c u trúc l p w

-w = 1;

, ta so sánh hai

= 1; ( <= << ++;

b ) << ", "; w (

<< ++; <=

<< ", "; b );

Hai o n mã ch khác nhau ch m t bên trái dùng vòng w , bên ph i dùng vòng -w , còn l i, các ph n thân vòng l p, i u ki n, kh i t o u gi ng h t nhau. o n bên trái ư c l y t ví d trong m c trư c, nó in ra các s t 1 n b . o n mã dùng vòng -w bên ph i cũng th c hi n công vi c gi ng h t o n bên trái, ngo i tr m t i m: khi b nh hơn 1 thì nó v n m 1 trư c khi d ng vòng l p – thân vòng l p ch y 01 l n trư c khi ki m tra i u ki n. minh h a rõ hơn, ta xem xét Hình 3.9 là b n s a i c a ví d trong Hình 3.7 b ng cách thay c u trúc w b ng c u trúc -w và gi nguyên các ph n còn l i. K t qu ch y chương trình cho th y ho t ng c a chương trình trong Hình 3.9 không hoàn toàn như mong mu n. C th , khi b ư c nh p giá tr 0, chương trình v n m m t l n trong khi áng ra không nên m l n nào như chương trình nguyên g c trong Hình 3.7. ó là m t minh h a v s khác bi t gi a ho t ng c a hai c u trúc w và -w . Trong bài toán c th này, c u trúc -w không ph i là l a ch n t t so v i c u trúc w .

47

<

> ;

() , << " >> b = 1; do << ++; w ile o << "B ; << ", "; e " << ; ; b ; b ; ";

ươ
b 1, , B b 1, B b 1, B
Hình 3.9: Ví d v vòng l p do-w ile.

1

T n d ng c i m ch y m t l n trư c khi ki m tra i u ki n, chương trình trong Hình 3.10 làm nhi m v nh p t bàn phím m t chu i s k t thúc b ng s 0 và tính t ng c a chúng. Công vi c l p i l p l i là nh p vào m t s ( )r i c ng d n giá tr c a s ó vào t ng ( ). i u ki n l p là s v a nh p ph i khác 0. Rõ ràng, không c n và không nên ki m tra i u ki n l p trư c khi l n u th c hi n thân vòng l p. Trong trư ng h p này, c u trúc -w là l a ch n t t hơn so v i c u trúc w . Chương trình trong Hình 3.10 còn là m t ví d v m t vòng l p không dùng con m i u khi n vòng l p mà dùng m t bi n canh hay c tr ng thái ánh

48

d u i m k t thúc. ây, 0 là giá tr canh ánh d u ph n t d li u cu i cùng mà ngư i dùng nh p vào chương trình.
< > ;

() = ; ;

w

<< " >> = ( << " ;

b ; + = ); b ;

(

) ";

" <<

;

ươ b b b b ( ( ( ( b
Hình 3.10: Vòng l p do-while dùng bi n canh.

) ) ) 1 )

3.3.3. Vòng fo Vòng fo là c u trúc h tr vi c vi t các vòng l p mà s l n l p ư c ki m soát b ng bi n m. Ch ng h n, o n mã gi sau ây mô t thu t toán in ra các s t 1 n b :

49

Làm nhi m v sau ây i v i m i giá tr c a ra màn hình In o n mã gi
(

t 1

n

b

:

ó có th

ư c vi t b ng vòng
<= << ", "; b ;

c a C++ như sau:
++)

= 1; <<

V i

b 1,

có giá tr b ng 3, o n trình trên cho k t qu in ra màn hình là:
, 3,

C u trúc t ng quát c a vòng l p thân_vòng_l p

là:

( kh i_t o; i u_ki n_l p; c p_nh t)

Trong ó, bi u th c kh i_t o thư ng kh i t o con m i u khi n vòng l p, i u_ki n_l p xác nh xem thân vòng l p có nên ch y ti p hay không ( i u ki n này thư ng ch a ngư ng cu i cùng c a con m), và bi u th c c p_nh t làm tăng hay gi m con m. Cũng tương t như các c u trúc , w ..., n u thân_vòng_l p có nhi u hơn m t l nh thì c n ph i b c nó trong m t c p ngo c {}. Lưu ý r ng c p ngo c ơn bao quanh b ba kh i_t o, i u_ki n_l p, c p_nh t, cũng như hai d u ch m ph y ngăn cách ba thành ph n ó, là các thành b t bu c c a cú pháp c u trúc . Ba thành ph n ó cũng có th là bi u th c r ng n u c n thi t, nhưng k c khi ó v n ph i có hai d u ch m ph y. Trong h u h t các trư ng h p, c u trúc c u trúc l p w sau (ngo i l ư c nói kh i_t o; w ( i u_ki n_l p) thân_vòng_l p c p_nh t; Ta có th khai báo bi n ngay trong ph n kh i_t o c a vòng , ch ng h n i v i bi n con m. Nhưng các bi n ư c khai báo t i ó ch có hi u l c bên trong c u trúc l p (chi ti t v ph m vi c a bi n s ư c nói n trong M c 4.4). Ví d : t ng quát trên tương ương v i n trong M c 0):

50

( <<

= 1; <= << ", ";

b

;

++)

Hình 3.11 minh h a cách s d ng vòng l p tính i m trung bình t i m c a 10 môn h c (s môn h c lưu trong bi n bj ). Ngư i dùng s ư c yêu c u nh p t bàn phím i m s c a 10 môn h c trong khi chương trình c ng d n t ng c a 10 i m s này. Công vi c mà chương trình c n l p i l p l i 10 l n là: nh p i m c a m t môn h c, c ng d n i m ó vào t ng i m. u tiên vòng s ti n hành bư c kh i t o v i m c ích chính là kh i t o bi n m. Vi c kh i t o ch ư c ti n hành duy nh t m t l n. Trong ví d này, bi n ư c khai báo ngay t i vòng và kh i t o giá tr b ng 0. Ti p theo vòng s ti n hành ki m tra i u ki n l p < bj . N u i u ki n sai, vòng l p s k t thúc. N u i u ki n úng, thân vòng l p s ư c th c hi n (nh p m t giá tr ki u r i c ng d n vào bi n ). Sau ó là bư c c p nh t v i nhi m v tăng bi n m thêm 1. K t qu là vòng l p s ch y 10 l n v i các giá tr b ng 0, 1, .., 9 (khi nh n giá tr 10 thì i u ki n l p không còn úng và vòng l p k t thúc).
< > ;

() = bj << " ( >> += << "A ; = k; k; k; ; ; = 1 ; k < " << bj bj ; << " ++) bj ";

k = " <<

bj

;

Hình 3.11: Ví d v vòng l p for.

Xét m t bài toán khác: Tính lãi g i ti n ti t ki m. M t ngư i g i m t s ti t ki m kì h n 12 tháng v i s ti n ban u là 1.000.000 VN , lãi su t 12% m t năm. Gi s ti n lãi hàng năm không ư c rút ra mà g p chung vào v n. S ti n

51

n m trong s ti t ki m sau m i năm (kì h n 12 tháng) ư c tính theo công th c sau: amount = principal * (1 + interest_rate)year trong ó amount là s ti n trong s ti t ki m, principal là v n ban u, interest_rate là lãi xu t hàng năm, và year là s năm ã g i. Hãy tính và in ra s ti n trong s ti t ki m vào th i i m cu i các kì 12 tháng hàng năm trong vòng 5 năm theo d ng
1 A xxxx xxxx

Thu t toán cho bài toán ó như sau: Kh i t o các bi n amount, principal, interestRate In m c hai c t Year và Amount in deposit ra màn hình V i year ch y t 1 n 5, th c hi n các công vi c sau: tính amount sau year năm theo công th c in amount theo c t Chương trình hoàn ch nh cho trong Hình 3.12. Trong ó có m t s chú ý. i mc n

Th nh t, v n nh d ng các giá tr s khi in ra màn hình. nh d ng m c nh khi in ra màn hình là nh d ng khoa h c, ch ng h n s 1120000 h th p phân s có d ng 1.12e+006. Ta s nhìn th y k t qu này n u xóa b dòng sau kh i chương trình:
<< x << ( ); b

Dòng trên không hi n th gì ra màn hình mà ch t c u hình cho các l n in ti p theo. C th , x giúp quy nh r ng các giá tr th c in ra theo d ng có d u ch m th p phân (h o lư ng Anh-M , tương ương v i d u ph y th p phân c a h mét), còn ( ) quy nh r ng các giá tr th c ư c in ra v i chính xác 2 ch s sau d u ch m. ó là hai trong nhi u phép nh d ng lu ng d li u (stream manipulator). Các phép nh d ng này n m trong thư vi n iomanip c a thư vi n chu n. Do ó, s d ng chúng, ta ph i có nh hư ng ti n x lý < > u t p mã ngu n (xem ph n u c a chương trình trong Hình 3.12).

52

Th hai là s d ng hàm thư vi n toán h c tính lũy th a. C++ không có phép tính lũy th a. Thay vào ó, thư vi n <cmath> trong thư vi n chu n C++ cung y c p hàm w. Hàm w( x, ) cho k t qu là giá tr c a phép tính x . dùng hàm này, ta cũng c n có nh hư ng ti n x lý < > u t p mã ngu n.
< < < > > > ; () b b b << " ; = 1 = A ; 1 ; " << ; ++ b

<<

x

<<

(

);

b

( = <<

= 1; << "

<= ; w( 1 " <<

++) + <<

, ;

);

;

ươ A 11 1 1 9 8 1 3 19 36 1 6 3 1 68
Hình 3.12: Tính ti n ti t ki m hàng năm s d ng vòng for.

1 3

53

3.4. Các l nh

eak và o

i

e
-w

Như ã gi i thi u các m c trư c, các vòng l p w , k t thúc khi ki m tra bi u th c i u ki n ư c giá tr vòng l p trong trư ng h p còn l i. Các l nh b k và nh y cho phép thay i lu ng i u khi n ó. L nh b
k khi

, và u và ch y ti p thân là các l nh

ư c th c thi bên trong m t c u trúc l p hay m t c u trúc w có tác d ng l p t c ch m d t c u trúc ó, chương trình s ch y ti p l nh n m ti p sau c u trúc ó. L nh b k thư ng ư c dùng k t thúc s m vòng l p (thay vì i n lư t ki m tra i u ki n l p) ho c b qua ph n còn l i c a c u trúc w (như t i các ví d trong M c 3.2.2). V ví d s d ng l nh b k trong vòng l p. Ch ng h n, n u ta s a ví d trong Hình 3.11 vòng ng ng l i khi ngư i dùng nh p i m s có giá tr âm, ta có chương trình trong Hình 3.13. V i cài t này, khi ngư i dùng nh p m t i m s có giá tr âm, i u ki n ( k < ) s cho k t qu , chương trình thoát kh i vòng và ch y ti p t l nh n m sau ó. Trong trư ng h p ó, bi n chưa k p tăng n ngư ng bj ( i u ki n l p c a vòng chưa k p b phá v ). Do ó, bi u th c ( >= bj ) trong l nh sau ó có nghĩa "vòng có ch y bj l n hay không?" ho c "vòng có b ng t gi a ch ng b i l nh b k hay không?", hay là "d li u nh p vào có thành công hay không?".

54

<

> ;

() = , << " ( = >> a k += ; k; k; k; ) k = " << k "; bj ; ; bj

= 1 ; k < " << ; bj ++) << " bj ";

bj

if

eak

(

>= bj << "A << " ;

Hình 3.13: Ví d v l nh b

k.

L nh n m trong m t vòng l p có tác d ng k t thúc l n l p hi n hành c a vòng l p ó. Hình 3.14 là m t b n s a i khác c a chương trình trong Hình 3.11. Trong phiên b n này, chương trình không ghi nh n i m s có giá tr âm, cũng không k t thúc chương trình sau khi báo l i như b n trong Hình 3.13, mà yêu c u nh p l i cho n khi nào thành công. Khi g p i m s âm ư c nh p vào (bi n k), l nh ư c th c thi có tác d ng b qua o n l nh ghi nh n i m n a sau c a thân vòng w ( o n c ng d n vào t ng và tăng bi n m ). L n l p ư c th c hi n sau ó s yêu c u nh p l i i m cho môn h c ang nh p d (xem k t qu ch y chương trình trong Hình 3.14).

55

<

> ;

() = = << " ( ; ,

bj k )

= 3; " << bj << " bj ";

w

< bj k; << " " << >> k; ( k < ) << i e k;

+ 1 << "

";

k << "

";

o

+= ++; << "A ;

k = " <<

;

ươ
k 1 3 3 A 8 1 k = 8
Hình 3.14: Ví d v l nh .

3

bj

M t i m c n lưu ý là các l nh b k hay ch có tác d ng i v i vòng l p trong cùng ch a nó. Ch ng h n, n u có hai vòng l p l ng nhau và l nh b k n m trong vòng l p bên trong, thì khi ư c th c thi, l nh b k ó ch có tác d ng k t thúc vòng l p bên trong. M t vòng l p không có b k hay có c u trúc ơn gi n và d hi u vì th i i m ki m tra i u ki n l p là i m duy nh t quy t nh l p hay d ng. V i 56

m t l nh b k k t thúc s m vòng l p ho c m t l nh k t thúc s m l n l p hi n hành, c u trúc l p s khó hi u. V y nên ngư i ta khuyên nên tránh hai l nh này n u có th .

3.5. Bi u th c i u ki n trong các c u trúc i u khi n
H u h t các c u trúc i u khi n mà ta nói n trong chương này u dùng n m t thành ph n quan tr ng: bi u th c i u ki n. Trong các ví d trư c, ta m i ch dùng n các i u ki n ơn gi n, ch ng h n <= b hay == 'A', v i duy nh t m t phép so sánh. Khi c n vi t nh ng i u ki n ph c t p hơn, c n n nhi u i u ki n nh , ta có th k t h p chúng b ng các phép toán lôgic && (AND – và), || (OR – ho c) và (NOT – ph nh). Ví d : Khi ki m tra i u ki n 8 ≤ < 9 , b t ng th c toán h c này c n ư c tách thành hai i u ki n ơn. B t ng úng khi c hai i u ki n ơn u th a mãn. ó là khi ta c n dùng phép toán lôgic && (AND).
( >= 8 && = 'B'; < 9 )

Khi m t trong hai i u ki n x y ra, ho c ti n ã h t ho c túi ã y, thì không th mua thêm hàng. Trư ng h p này, ta c n dùng phép toán lôgic || (OR).
( L <= << " ' || b b F ) ";

Ti p t c l p trong khi d li u vào chưa có giá tr b ng giá tr canh – ánh d u i m cu i c a chu i d li u:
w ( ( == ))

ây, ta có th dùng phép ph nh. Ho c nhi u ngư i ch n cách ơn gi n hơn là dùng phép so sánh khác ( =):
w ( = )

M t i u c n c bi t lưu ý khi dùng toán t so sánh b ng (==): tránh nh m l n v i phép gán (=). Nh m l n d ng này s d n n nh ng l i lôgic r t khó phát hi n. Ch ng h n câu l nh s in ra l i khen " x " n u x p lo i h c l c t lo i A:

57

(

ade

'A') << " x

";

N u ta vi t nh m thành:
( ade 'A') << " x ";

thì khi ki m tra i u ki n, câu l nh này s s a giá tr c a bi n thành 'A' thay vì so sánh. Bi u th c gán = 'A' có giá tr b ng giá tr ư c gán ('A'), giá tr này khác 0 nên ư c hi u là . Khi bi u th c i u ki n c a l nh này luôn có giá tr , o n l nh s hi n th l i khen cho m i lo i h c l c. M t g i ý cách tránh l i này là nên t p thói quen vi t các bi u th c so sánh theo ki u ('A' == ) thay vì ( == 'A') theo thói quen thông thư ng. V i v trí giá tr h ng bên trái, bi n bên ph i, thì khi ta ch ng may vi t nh m == thành = thì trình biên d ch s phát hi n l i biên d ch "sai cú pháp c a phép gán 'A' = " thay vì im l ng do không th phát hi n l i lôgic.

58

Bài t p
1. Nh p vào t bàn phím m t s nguyên n m trong kho ng t 0 n 10 là i m c a m t sinh viên. Hãy s d ng c u trúc switch phân lo i sinh viên ó theo quy t c dư i ây. Hi n k t qu phân lo i ra màn hình: • i m < 5: kém

• 5 ≤ i m ≤ 7: trung bình • 8 ≤ i m ≤ 9: gi i • i m = 10: xu t s c

2. Nh p vào t bàn phím hai s nguyên a và b. N u • a > b: hi n ra màn hình dòng ch “a is greater than b”. • a < b: hi n ra màn hình dòng ch “a is smaler than b”. • a = b: hi n ra màn hình dòng ch “a is equal to b”. 3. Nh p vào t bàn phím ba s a, b, c. Hãy ki m tra xem ba s ó có th a mãn là dài các c nh c a m t tam giác hay không? N u có, hi n ra màn hình thông báo v di n thích c a tam giác ó. N u không, thông báo ra màn hình ba s ó không ph i là 3 c nh c a m t tam giác. 4. Nh p t bàn phím 3 s a, b, c. Hãy tìm và hi n k t qu ra màn hình. a. Giá tr l n nh t c a ba s trên b. Giá tr nh nh t c a ba s trên 5. Nh p t bàn phím ba s nguyên a, b, c. Tính t ng c a s nh nh t và s l n nh t trong ba s trên. Hi n k t qu tính ư c ra màn hình. 6. Nh p vào t bàn phím danh sách các s nguyên th hi n cho i m c a m t l p h c. Quá trình nh p d ng l i khi s nh p vào là m t s âm. Vi t chương trình gi i quy t các bài toán sau (hi n k t qu tìm ư c ra màn hình) a. Tính s lư ng sinh viên trong l p b. Tính i m trung bình c a l p h c v a nh p. c. Tìm sinh viên có i m cao nh t 59

d. Tìm sinh viên có i m th p nh t. 7. Nh p vào t bàn phím m t s nguyên dương, s d ng c u trúc vòng l p while-do tính t ng t t c các s nguyên dương l nh hơn s nh p t bàn phím. Hi n k t qu tìm ư c ra màn hình. 8. Nh p t bàn phím m t s nguyên dương. Hãy ki m tra xem s nguyên dương ó có ph i là s nguyên t hay không, n u không thì tìm t t c các ư c s c a s nguyên dương ó. Hi n k t qu tìm ư c ra màn hình. 9. S d ng c u trúc vòng l p for tính t ng t t c các s nguyên dương chia h t cho 7 và nh hơn m t s n cho trư c t bàn phím. Hi n k t qu ra màn hình. 10. Nh p vào t bàn phím vào 4 s t nhiên. Hãy ki m tra xem có t n t i hay không m t c p s (a, b) trong b n s trên mà a chia h t cho b. N u có, hi n ra màn hình t t c các c p s (a, b) tìm ư c. 11. Công th c tính dãy s Fibonacci như sau: f(0) = 0; f(1) = 1; f(n) = f(n-1) + f(n-2), v i n >1. 12. Nh p t bàn phím m t s nguyên không âm n, hãy tính giá tr f(n). Hi n k t qu tính ư c ra màn hình. 13. Nh p vào t bàn phím 3 s nguyên h (0 ≤ h ≤ 23), m (0 ≤ m ≤ 59), s (0 ≤ s ≤ 59) cho bi t gi , phút, giây c a th i i m hi n t i. Hãy tính xem còn bao nhiêu giây n a thì n th i i m 0 gi , 0 phút, 0 giây. Ví d : h = 23, m = 59, s = 58. K t qu : còn 2 giây n a thì n 0:0:0

60

Chương 4. Hàm
Các chương trình ví d mà ta g p t u n gi u ng n v i duy nh t m t hàm chính – hàm . Khi c n gi i quy t bài toán ph c t p hơn, hàm s dài hơn, và ph c t p hơn, d n n chương trình khó c, khó hi u, l p trình viên d m c l i, và l i khó tìm. gi i quy t các bài toán l n và ph c t p, ngư i ta thư ng s d ng chi n lư c chia tr . Nghĩa là, chia bài toán thành m t chu i các bài toán nh hơn, d hơn, và chúng có th ư c gi i m t cách ít nhi u c l p v i nhau, sau ó k t h p l i có m t l i gi i hoàn ch nh cho bài toán ban u. Trong l p trình, chia tr ư c th hi n b ng vi c chia chương trình thành các chương trình con. o n mã ch a trong thân m t chương trình con s ư c th c thi m i khi chương trình con ó ư c g i (hay kích ho t). Chương trình con chính là m t trong các cơ ch cho phép mô- un hóa chương trình. tr , vi c s d ng chương trình con còn mang l i Bên c nh chi n lư c chia cho l p trình viên kh năng tái s d ng mã, s d ng các chương trình con như là các kh i l p ghép xây d ng các chương trình m i. Chương trình con cũng giúp tránh ư c các o n mã gi ng nhau l p i l p l i trong m t chương trình. Ngư i ta khuyên r ng dài m i chương trình con không nên vư t quá m t trang màn hình l p trình viên có th ki m soát t t ho t ng c a chương trình con ó. Trong C++, t t c các chương trình con u ư c th hi n b i c u trúc hàm. Ngay c chương trình chính ( ) cũng là m t hàm. M t hàm ư c kích ho t khi nó ư c g i t bên trong m t hàm khác, ch ng h n hàm w ư c g i t c a chương trình trong Hình 3.12. Khi hàm ư c g i th c hi n trong hàm xong công vi c c a mình, nó tr k t qu v cho nơi g i nó ho c ơn gi n là tr quy n i u khi n v cho nơi g i nó. Có th so sánh hàm ư c g i như là m t ngư i th , còn hàm g i nó như là ngư i ch . Ngư i ch giao vi c cho ngư i th A, ngư i th A th c hi n công vi c và khi làm xong thì báo cáo k t qu l i cho ngư i ch . Ngư i th A trong khi làm nhi m v c a mình cũng có th yêu c u m t ngư i th khác (B) th c hi n m t nhi m v con trong ó. n ây quan h gi a ngư i th A và ngư i th B cũng tương t như quan h gi a ngư i ch và ngư i th B.

61

Chương này s nói v cách nh nghĩa các chương trình con (ho c các hàm) và các v n liên quan như bi n a phương, cách truy n d li u vào trong hàm.

4.1. Các hàm có s n
Các ngôn ng l p trình b c cao thư ng cung c p r t nhi u các hàm có s n cho ngư i dùng s d ng. Các hàm ó ư c chia thành các nhóm hay các thư vi n khác nhau. Khi mu n s d ng hàm có s n ó, ta ch c n ch ra cho chương trình bi t là hàm ó n m thư vi n nào (s d ng ) và sau ó có th s d ng hàm ó m t cách bình thư ng. Ví d như t i chương trình trong Hình 3.12, ta ã s d ng hàm w và khai báo include thư vi n cmath ch a nó. M t s thư vi n c a C++ hay ư c s d ng: • iostream: cung c p các hàm liên quan • cmath: cung c p các hàm liên quan n nh p và xu t d li u n toán h c.

• cstdlib: cung c p các hàm cho các m c ích chung như: qu n lý b nh ng, sinh s ng u nhiên, tìm ki m-s p x p… • cstring: cung c p các hàm x chu i… lý chu i kí t như: tính dài, sao chép

Có th tra c u chi ti t v các thư vi n này t i [4]. Ví d , B ng 4.1 li t kê danh sách m t s hàm toán h c thông d ng.
B ng 4.1: Các hàm toán h c trong thư vi n cmath.

Hàm ceil( x ) cos( x ) exp( x ) fabs( x ) floor( x ) fmod( x, y )

Miêu t s nguyên nh nh t không nh hơn x hàm lư ng giác cos x (x o b ng radian) ex giá tr tuy t ic ax

s nguyên l n nh t không l n hơn x ph n dư c a phép chia x/y (l y giá tr ki u th c)

62

log( x ) log10( x ) pow( x, y ) sin( x ) sqrt( x ) tan( x )

loga cơ s e c a x ( ln x ) loga cơ s 10 c a x ( log x ) xy hàm lư ng giác sin x (x o b ng radian) căn b c 2 c a x (x là giá tr không âm) hàm lư ng giác tan x (x o b ng radian)

4.2. C u trúc chung c a hàm
Ngoài vi c s d ng các hàm có s n trong thư vi n, l p trình viên còn t xây d ng các hàm c a riêng mình. Sau khi ư c nh nghĩa, m t hàm có th ư c s d ng nhi u l n. Hàm ư c nh nghĩa theo công th c: ki u_tr _v tên_hàm (tham_s _1, tham_s _2,…) thân_hàm trong ó: • ki u_tr _v là ki u giá tr mà hàm s tr v . ây có th là m t trong các ki u d li u có s n c a C++ ho c m t ki u d li u ngư i dùng t nh nghĩa. Trong C++, n u hàm không tr v giá tr nào, thì ki u_tr _v ư c thay th b ng t khóa . • tên_hàm là nh danh c a hàm, cách danh và gi ng cách t tên bi n. t tên hàm tuân th theo cách t nh

• tham_s _1, tham_s _2,…là danh sách các tham s u vào c a hàm. Tên y c a chúng là các tham s hình th c (formal parameter)4. ây là phương ti n truy n d li u vào trong hàm. • thân_hàm là nơi ch a chu i các l nh.

4

Còn ư c g i t t là "tham s ".

63

Hình 4.1 mô t cách khai báo, cài t và s d ng m t hàm tính di n tích hình ch nh t ( A ) trong C++. Hàm A nh n hai tham s u vào là L và , nó tính di n tích hình ch nh t (lưu t i bi n ) và tr l i k t qu (l nh ;).
< > ;

b A = ; ( L L , ; )

ươ () = 3; = ; = << " ; A ( " << , w ; );

w

}
Hình 4.1: Ví d v khai báo và s d ng hàm.

Lưu ý: Vi c khai báo và nh nghĩa (thân hàm) hàm có th tách ra thành hai ph n khác nhau. Ta s g p nh ng ví d các chương sau. Bi n ư c khai báo trong m t hàm ư c g i là bi n a phương c a hàm ó, nghĩa là nó ch có ph m vi là bên trong thân hàm ó. Gi s trong chương trình c a ta có hai hàm, m i hàm khai báo m t bi n có tên gi ng nhau, ví d . Ta s có hai bi n khác nhau tình c có tên gi ng nhau, và vi c s a i bi n trong hàm này s không có nh hư ng gì n bi n trong hàm kia. T c là, i v i máy tính, hai bi n này không có liên quan gì n nhau.

4.3. Cách s d ng hàm
s d ng m t hàm, ta g i tên hàm, theo sau là c p ngo c ơn ch a các giá tr truy n vào cho hàm (xem cách g i hàm A t trong hàm

64

Hình 4.1). Các giá tr truy n vào cho hàm ư c g i là các i s (argument)5. Như trong l i g i hàm A ( , w ) t i Hình 4.1, và w là các i s . M t hàm có th ư c g i nhi u l n v i các i s khác nhau. Khi chương trình th c thi m t l i g i hàm, giá tr c a các i s ư c sao chép vào các tham s hình th c tương ng, nghĩa là giá tr c a ư c chép vào L và giá tr c a w ư c chép vào , r i o n mã nh nghĩa hàm ư c th c thi. Cu i cùng, l nh tr v m t giá tr (là giá tr c a bi u th c n m ngay sau t khóa ) cho o n mã chương trình ã g i hàm này. ng th i, lu ng i u khi n c a chương trình cũng quay tr l i v i nơi g i hàm và các l nh n i ti p phía sau l i g i hàm s ư c th c thi.

4.4. Bi n toàn c c và bi n

a phương

Chương 2 ã gi i thi u các khái ni m cơ b n v bi n. Trong m c này, ta s bàn kĩ hơn v các lo i bi n, hi u l c và ph m vi c a bi n. Chúng ta ã bi t r ng bi n có các thu c tính như: tên, ki u, kích thư c, giá tr . Ngoài ra, m i bi n còn có các c i m khác, c th là: • th i gian s ng: bi n t n t i bao lâu trong b nh • ph m vi: bi n có th 4.4.1. Ph m vi c a bi n Ph m vi (scope) c a m t bi n là nh ng nơi chúng ta có th s d ng bi n ó. M t bi n có th có ph m vi toàn c c hay ph m vi a phương. Bi n toàn c c (global variable) là bi n ư c khai báo bên ngoài t t c các hàm (bi n A trong Hình 2.1). Bi n toàn c c có th ư c s d ng trong toàn b chương trình, ngay c bên trong các hàm, mi n là o n mã s d ng bi n n m sau dòng l nh khai báo bi n ó. Bi n a phương (local variable) là bi n ư c khai báo bên trong m t hàm ho c m t kh i l nh (trong C++, m t kh i l nh ư c gói trong c p ngo c {}). Bi n a phương ch có th s d ng bên trong kh i l nh mà nó ư c khai báo t i
5

ư c s d ng t i nh ng nơi nào trong chương trình

M t s tài li u dùng thu t ng "tham s th c s " hay "tham i" ng "tham s " g i chung cho c tham s hình th c l n i s .

ch

i s . M t s tài li u khác dùng thu t

65

ó. Kh i l nh này có th là thân c a m t hàm ho c m t kh i c u trúc i u khi n (xem Chương 3). Ch ng h n, t i chương trình trong Hình 4.2 có ba bi n x khác nhau v i các ph m vi khác nhau: bi n x ư c khai báo trong hàm có ph m vi là hàm ; bi n x ư c khai báo ngay t i dòng u tiên c a thân hàm có ph m vi là toàn b thân hàm do c p ngo c {} g n nh t chính là c p ngo c bao quanh thân hàm ; và bi n x ư c khai báo bên trong thân vòng c a hàm ch có ph m vi bên trong vòng . ây là các bi n hoàn toàn c l p. S a i i v i bi n này hoàn toàn không có nh hư ng gì i v i các bi n kia (th hi n các dòng output: con m x c a vòng thay i giá tr trong khi hai bi n x còn l i không có gì thay i).
< > ; ( () x = (); ( = 1; x = << "L << "L x <= 3; ; x ++) b " << x << " << x << ; ; ; b );

() x = ; << "L b " << x <<

x

;

ươ
L L L L L x x x x x 1 9

Hình 4.2: Ví d v ph m vi c a bi n.

66

4.4.2. Th i gian s ng c a bi n Trong trư ng h p m c nh v i l nh khai báo thông thư ng, m t bi n s ư c t o ra khi chương trình ch y n l nh khai báo bi n ó và t n t i cho n khi chương trình ra kh i ph m vi c a bi n ó. C th , các bi n toàn c c có ph m vi là toàn b chương trình, nên chúng ư c sinh ra và kh i t o úng m t l n và "s ng" cho n khi chương trình k t thúc. V i các bi n a phương ư c khai báo theo ki u thông thư ng, ph m vi c a chúng kéo t l nh khai báo chúng cho n h t kh i chương trình ch a l nh khai báo ó. Do ó, các bi n này ư c t o ra m i khi chương trình ch y n l nh khai báo bi n và b h y i khi chương trình ch y n h t kh i. Ngư i ta còn g i các bi n a phương này là bi n t ng (automatic variable). Trư ng h p ngo i l trong C++ là các bi n a phương ư c khai báo v i t khóa . Các bi n này tuy là bi n a phương nhưng "s ng" cho n khi chương trình k t thúc m c dù nó không th ư c truy nh p t i trong khi chương trình ang ch y ngoài ph m vi c a nó. Các bi n static này gi nguyên giá tr c a mình gi a các l n g i hàm. Ngư i ta g i các bi n a phương lo i này là bi n tĩnh (static variable). Chương trình trong Hình 4.3 là m t ví d minh h a s khác nhau gi a bi n tĩnh và bi n thông thư ng. Trong hàm V b có hai bi n a phương: x là bi n t ng và là bi n tĩnh. C hai u ư c khai báo v i giá tr kh i t o b ng 0, cùng ư c in ra màn hình trư c khi tăng thêm 1. V b ư c g i b n l n t trong hàm , m i l n l i in ra màn hình m t dòng thông báo giá tr c a x và . K t qu in ra màn hình cho th y x có giá tr b ng 0 trong t t c các l i g i hàm, trong khi bi n tĩnh y m i l n l i tăng thêm 1. L n nào bư c vào hàm V b , x cũng nh n giá tr kh i t o (0). Trong khi ó, ch ư c kh i t o b ng 0 úng m t l n, nó không b h y khi hàm k t thúc mà nó v n "s ng" và gi hi u ng c a phép tăng cu i hàm V b t l n g i hàm trư c cho n l n g i hàm sau.

67

<

> ; V b ; = " << << ; ()

x =

= ; << "x = " << x << ", x++; ++;

() V V V V ; b b b b (); (); (); ();

ươ
x x x x = = = = , , , , = = 1 = = 3
Hình 4.3: Ví d v bi n tĩnh.

4.5. Tham s ,

i s , và cơ ch truy n tham s cho hàm

Trong ph n này chúng ta s tìm hi u kĩ v các cơ ch truy n tham s cho hàm. Có hai cơ ch chính là truy n giá tr và truy n tham chi u v i i m khác nhau căn b n: m t bên ch cho phép hàm ư c g i thao tác trên b n sao d li u c a nơi g i hàm, bên kia cho phép hàm ư c g i truy nh p tr c ti p. 4.5.1. Truy n giá tr Trong cơ ch truy n giá tr hay truy n b ng giá tr (pass-by-value), tham s ư c truy n b ng giá tr , nghĩa là b n sao c a i s ư c chép vào tham s tương ng trong hàm ch b n thân i s thì không ư c truy n vào hàm. Các thay i i v i b n sao s không có nh hư ng gì i v i b n g c, cho nên, khi hàm th c hi n các s a i i v i m t tham s thì các s a i này không có nh 68

hư ng gì t i i s tương ng ư c dùng cho l i g i hàm. T t c các ví d trong chương này cho n ây u dùng cơ ch truy n giá tr . Xem thêm minh h a trong Hình 4.4. Vi c tham s hình th c b thay i giá tr t bên trong hàm không có nh hư ng gì i v i i s L (m t bi n c a hàm ) ư c dùng khi g i hàm này. Sau khi l i g i hàm ư c th c hi n xong, L v n gi nguyên giá tr là 9.
< > ; ) = ( ; += ; ; > ; ; --)

(

() L = << " << " ; = 9; ( " <<

L b <<

); 1 ; " << L

ươ
b 1 9

Hình 4.4: Ví d v truy n giá tr cho hàm.

Truy n giá tr ư c xem là l a ch n an toàn do nó m b o r ng hàm ư c g i s không gây hi u ng ph không mong mu n i v i d li u c a nơi g i hàm. S d ng cơ ch truy n giá tr là m t trong các khía c nh c a phong cách l p trình t t. Tuy nhiên, cơ ch này có m t như c i m: n u d li u ư c truy n vào hàm có kích thư c l n thì s t n phí v th i gian ch y và b nh . 4.5.2. Truy n tham chi u Khác v i truy n giá tr , cơ ch truy n tham chi u hay truy n b ng tham chi u (pass-by-reference) cho phép hàm ư c g i truy nh p tr c ti p t i d li u c a nơi g i hàm và s a d li u ó n u mu n. So v i truy n giá tr , cơ ch truy n 69

tham chi u giúp chương trình có hi u năng cao hơn do tránh ư c chi phí cho vi c sao chép d li u. Tuy nhiên, truy n tham chi u làm cho chương trình kém an toàn do nguy cơ hàm ư c g i có th làm r i lo n d li u c a hàm g i. M c này nói v m t cơ ch mà C++ cung c p truy n tham s b ng tham chi u. Ngoài ra, Chương 6 s nói n m t d ng truy n tham chi u khác c thù c a C/C++: con tr . Trư c tiên chúng ta tìm hi u v khái ni m tham chi u trong ngôn ng l p trình C++. Tham chi u (reference) c a m t bi n v b n ch t là m t bi t danh hay m t cái tên khác c a chính bi n ó. Các thao tác trên tham chi u c a m t bi n cũng có hi u qu gi ng h t như thao tác trên chính bi n ó và ngư c l i. Sau khi khai báo, tham chi u ư c s d ng trong chương trình như các bi n khác. Ví d dòng:
& b b k = b U B;

khai báo

có tên b U B. Lưu ý r ng trong khai báo có d u &. Ngoài ra, tham chi u ph i ư c kh i t o ngay khi khai báo, C++ không ch p nh n tình tr ng m t tham chi u không chi u i âu c .

k là m t tham chi u t i m t bi n ki u

b k Hình 4.5 minh h a cách khai báo và s d ng tham chi u. Bi n ư c khai báo (có d u & vào ng trư c tên bi n) là m t tham chi u t i bi n b U B (stick là m t tên g i khác c a USB stick). M i tính toán và tác ng trên bi n b k s tương t như trên bi n b U B và ngư c l i vì th c ch t hai bi n này là m t.

Hình 4.5: Ví d v khai báo và s d ng tham chi u.

70

Trong nhi u trư ng h p, chúng ta mu n vi c thay i giá tr c a m t tham s trong hàm s làm thay i giá tr c a i s tương ng. Ví d , khi ta vi t m t hàm nh p giá tr cho các bi n t bàn phím. làm như v y, ta có th s d ng cơ ch truy n tham chi u. T c là, tham s hình th c s là m t tham chi u t i i s tương ng. Trong cơ ch này, các s a i i v i tham s hình th c bên trong hàm ư c th c hi n trên chính i s dùng cho l i g i hàm. Hình 4.6 minh h a cơ ch truy n tham chi u v i hàm . Hàm này nh p hai s nguyên t bàn phím và lưu chúng vào hai tham s và k( ã ư c khai báo là tham chi u). Vi c lưu giá tr vào và k s làm thay i giá tr c a i s là các bi n tương ng c a hàm . Khác bi t duy nh t v cú pháp gi a truy n giá tr và truy n tham chi u là danh sách khai báo tham s hình th c. quy nh tham s nào s ư c truy n b ng tham chi u, c n có d u & t ngay sau tên ki u d li u t i khai báo tham s ó trong nh nghĩa hàm. Trong ví d hàm , có các d u & t t i khai báo c a các tham s và k.
( & , & k);

Lưu ý: Hàm không c n tr v giá tr gì nên nó ã ư c khai báo v i t khóa cho ki u giá tr tr v và không c n có l nh kèm giá tr trong thân hàm.

71

<

> ; ( & , & k) k k; ";

<< " >> >> ;

() 1, << " , << " << " ; k1; ( 1, k ; ( ,

k1); " << 1 << " k ); " << << " k " << ( k1 +

k " <<

k1 <<

;

k " << k );

k

<<

;

ươ
' 1 ' k 6 k 11
Hình 4.6: Ví d v truy n tham bi n cho hàm.

k k k

1 6

Như ã nói trên, vi c cho phép hàm ư c g i truy nh p tr c ti p t i d c a nơi g i hàm gây nguy cơ hàm ư c g i phá r i d li u c a nơi g i V y có cách nào gi m b t ho c ngăn ch n nguy cơ này? ó là h ng chi u. M t khi m t tham chi u ư c khai báo là h ng, trình biên d ch s b o r ng tham chi u ó s ch ư c dùng c ch không th s a i bi nó chi u t i. 4.5.3. Tham s m c nh

li u hàm. tham m n mà

Khi khai báo hàm, ta có th t s n m t giá tr m c nh cho các tham s . Các tham s này ph i ng cu i danh sách. t giá tr m c nh, ta ch c n vi t d u gán và giá tr m t nh cho tham s t i khai báo hàm. N u tham s ó không ư c truy n giá tr khi g i hàm, giá tr m c nh s ư c dùng. Ngư c 72

l i, n u m t giá tr ư c truy n vào tham s thì giá tr m c dùng giá tr ư c truy n vào.

nh s b b qua

Hình 4.7 minh h a v cách khai báo và s d ng tham s m c nh. Trong ó, tham s hình th c c a hàm có giá tr m c nh là 9. L n g i hàm th nh t cung c p i s cho c hai tham s ( w = 1 và = 5) và ta thu ư c k t qu là 15. L n g i hàm th hai ch cung c p i s có giá b ng 1 cho tham s w , còn tham s s nh n giá tr m c nh (9), ta thu ư c k t qu là 45.
< > ; w , =9)

(

( ;

= ; w <= += w ;

; ;

w

++)

() w L L = << " = << " ; ( w = 1; = ; ( w L " << L ); " << , << L ; );

<<

;

ươ
1

Hình 4.7: Ví d v tham s m c

nh.

V nguyên t c, trình biên d ch s duy t danh sách các i s truy n vào t trái qua ph i, và l n lư t g n các i s cho các tham s hình th c tương ng. Khi k t thúc danh sách i s , nh ng tham s hình th c chưa ư c truy n giá tr s 73

nh n giá tr m c nh. Lưu ý: s i s truy n vào ph i nhi u hơn ho c b ng s tham s hình th c không ư c g n giá tr m c nh.

4.6. Hàm trùng tên
Trong C++, hai hàm khác nhau có th có tên trùng nhau (function overloading) n u danh sách tham s (ch quan tâm n ki u d li u mà không quan tâm n tên c a tham s ) c a hai hàm là khác nhau. Ví d ,
( ( ( x); x); x,

);

là ba hàm khác nhau trong C++. M i khi c n d ch m t l i g i hàm có tên , trình biên d ch ki m tra ki u d li u c a i s và s lư ng các i s trong l i g i hàm ó xác nh xem hàm ư c g i là hàm nào trong ba hàm ã ư c nh nghĩa. Ví d trong Hình 4.8 minh h a vi c khai báo và s d ng các hàm trùng tên li t kê trên. C ba hàm ư c g i t trong hàm v i danh sách tham s khác nhau. K t qu ch y chương trình ch ng t trình biên d ch ã g i úng hàm cho các b i s khác nhau.

74

<

> ; ( x) " << x << ;

<< "

( << "

b b

x) " << x << ;

( << "

x,

) " << x << " " << << ;

() (1); (1 ); (1, ); ;

ươ 1 b 1
Hình 4.8: Ví d v hàm trùng tên.

1

Các hàm trùng tên ư c phân bi t b i ch kí c a hàm. Ch kí c a m t hàm bao g m tên c a hàm ó và danh sách ki u tham s theo th t khai báo. Theo quy t c ó, ba l nh khai báo hàm dư i ây có ch kí trùng nhau nên không ư c C++ ch p nh n làm các hàm trùng tên:
( ( ( x); x); );

Khi k t h p s d ng hàm trùng tên và tham s m c nh, c n lưu ý tránh trư ng h p m t hàm khi b qua các tham s m c nh l i có l i g i gi ng h t v i m t 75

hàm trùng tên v i nó. Ví d , khi ta có hai hàm trùng tên, m t hàm có danh sách tham s r ng, hàm kia cho phép t t c các tham s có th l y giá tr m c nh, ch ng h n () và ( =1, j= 1). Tình tr ng này s gây l i biên d ch do tình tr ng nh p nh ng không th xác nh m t l i g i hàm ng v i hàm nào. C++ còn cho phép s d ng cơ ch hàm trùng tên nh nghĩa các phiên b n khác c a các phép toán ã có s n dùng cho các ki u d li u không cơ b n. Ch ng h n l p trình viên có th nh nghĩa ki u d li u s ph c và vi t phép c ng (+) dành cho ki u d li u này. N i dung chi ti t v ch này n m ngoài ph m vi c a cu n sách này, ngư i c có th tìm hi u t i [2].

4.7. Hàm

quy

Trong các ví d t u cu n sách, ta ã làm quen v i vi c m t hàm g i m t hàm khác. quy là d ng g i hàm c bi t: hàm quy là hàm ch a l i g i t i chính nó, tr c ti p ho c gián ti p (qua m t hàm khác). D ng hàm này ư c dùng bi u di n các thu t toán quy – ưa m t bài toán v m t bài toán tương t nhưng có kích thư c nh hơn. ây là ch ph c t p, s ư c nói n m t cách y hơn trong các môn h c cao hơn c a ngành Khoa h c Máy tính. Ph n này ch gi i thi u v quy m c ơn gi n nh t. Ví d i n hình thư ng ư c dùng minh h a cho hàm quy là bài toán tính giai th a c a m t s . Giai th a c a n ư c tính theo công th c quy: n! = n * (n-1) * (n-2) * (n-3) ... * 1 tương ương v i: n! = n * (n-1)! Nghĩa là, gi s f(n) là giai th a b c n, f(n) ư c f(0) = 1 f(n) = n * f(n-1) Trong ó, dòng th nh t là trư ng h p cơ b n, dòng th hai là công th c quy. Hàm quy vi t b ng C++ v cơ b n là gi ng h t v i công th c quy trên. Hình 4.9 mô t hàm quy tính giá tr c a n! Hàm quy bao g m m t kh i l nh chia hai trư ng h p cơ b n và t ng quát. Trư ng h p cơ b n x y ra n u ≤ 1, khi ó hàm k t thúc tính toán và tr v giá tr 1 là 76 nh nghĩa như sau:

giai th a c a . Trư ng h p còn l i ( > 1), hàm g i ( - 1) r i tr v k t qu là tích c a và ( - 1) .

quy

tính giá tr c a

Trong hai ph n chính c a hàm quy, trư ng h p cơ b n nhìn qua có v ơn gi n nhưng th c ra l i có vai trò r t quan tr ng trong hàm quy. N u thi u ho c có nh m l n khi vi t trư ng h p này, ho c sơ su t trong bư c quy làm nó không th h i t v trư ng h p cơ b n thì chương trình có nguy cơ quy vô t n n khi c n ki t b nh dành cho chương trình. Hi n tư ng này tương t như vòng l p vô t n.
< > ; ( ( <= 1) 1; ( b b ( -1)); = 1 ( -1) )

() = << ; << " ; = " << ( );

}
Hình 4.9: Ví d v hàm quy tính n!.

M t i m c n nh chú ý trong chương trình tính giai th a là ki u tr v cho hàm tính giai th a. Giá tr c a giai th a tăng r t nhanh so v i : 10! ã t n giá tr 3628800; n u dùng ki u (có kích thư c 4 byte h u h t các b n cài t C++) thì giai th a c a 16 b t u vư t ra ngoài kho ng giá tr c a (hãy th b ng cách s a chương trình ví d trong Hình 4.9). Do ó, có th áp ng giá tr l n hơn c a , ki u d li u cho giá tr giai th a ph i có kích thư c l n. Tài li u C++ chu n quy nh ki u có kích thư c l n nh t trong các ki u nguyên và g m ít nh t 4 byte. Ki u (vi t ng n g n là ) ch g m các giá tr không âm nên có th lưu giá tr t 0 t i ít nh t 4294967295, ta nên ch n ki u d li u này cho ki u tr v c a hàm tính giai th a.

77

Bài t p
1. Vi t m t hàm nh n tham s u vào là 5 s nguyên, và tr v k t qu là trung bình c ng c a 5 s nguyên ó. Hi n k t qu tr v c a hàm ra màn hình. 2. Hãy tìm nh ng hàm trùng nhau trong danh sách các hàm sau: a) int foo (int x) b) int foo (float x) c) float foo (int y) d) float foo (int x, int y) e) float foo (int x, float y) f) int foo (int student, float teacher) 3. Khi nào thì nên truy n i s cho hàm theo ki u truy n giá tr , khi nào thì nên truy n theo ki m tham chi u? 4. Vi t m t chương trình có m t hàm v i 5 tham s d ng tham chi u nh p vào 5 s nguyên t bàn phím. Tìm và hi n ra màn hình t t c các c p s có t ng b ng 50. tính giá tr nh nh t c a 3 s . 5. Vi t chương trình v i m t hàm get_min Hàm trên ư c vi t d a vào hàm get_min tính giá tr nh nh t c a hai s . Lưu ý, hai hàm này trùng tên. 6. Nh p t bán phím hai s nguyên x, y. Hãy tính và hi n ra màn hình giá tr c a các hàm sau ây: a) căn b c hai c a x b) ex c) log (x) d) x! e) x!! 7. Tìm hi u hàm rand sinh ra các s ng u nhiên trong ngôn ng l p trình C++. Hãy vi t chương trình sinh ra 9 s nguyên ng u nhiên n m trong ph m 78

vi t 2 n 99. Hi n ra màn hình các c p s nguyên ư c sinh ra có t ng b ng 100. 8. Dãy s Fibonacci ư c tính như sau: a) f (0) = 0; f (1) = 1; f(n) = f (n-1) + f(n-2) v i n > 1. b) Hãy vi t chương trình v i hàm quy tính f(k), v i k là giá tr nh p t bàn phím. Hi n k t qu tính ư c ra màn hình. 9. Vi t chương trình có m t hàm quy tính t ng t t c các s nguyên dương chia h t cho 3 và nh hơn m t s nguyên cho trư c nh p t bàn phím. ưa k t qu tính ư c ra màn hình. 10. Vi t m t hàm nh n phép toán sau ây: u vào là hai s x, y và tr ra 4 giá tr là k t qu c a 4

a) Thương c a phép toán x chia cho y b) Tích c a phép toán x nhân c) Ph n nguyên c a x chia cho y d) Ph n dư c a x chia cho y 11. Cho m t dãy s g m 5 s nguyên có giá tr ôi m t khác nhau ư c nh p vào t bàn phím. Hãy vi t hàm f(k) tr ra giá tr c a ph n t l n th k trong dãy s trên. Giá tr k ư c nh p vào t bàn phím. Hi n k t qu tìm ư c ra màn hình. Ví d cho dãy s : 14, 5, 11, 2, 23 f(1) = 23; f(3) = 11; f(5) = 2. 12. Nh p vào t bàn phím 1 s nguyên x, vi t m t hàm tính t ng t t c các ch s c a s nguyên x. Hi n k t qu tìm ư c ra màn hình. Ví d : x = 25701, thì t ng các ch s c a x là: 2+5+7+0+1 = 15.

79

Chương 5. M ng
Các ki u d li u cơ b n như ã gi i thi u trong Chương 2 không bi u di n các lo i d li u mà các bài toán òi h i. M t ví d là khi chương trình c n lưu và x lý m t chu i các ph n t d li u cùng ki u, ch ng h n như danh sách sinh viên trong trư ng ho c danh sách i m thi c a m t sinh viên, có th s p x p, tìm ki m, và tính toán các con s th ng kê trên chu i d li u ó. a s các ngôn ng l p trình cung c p các ki u d li u có c u trúc ph c v các nhi m v này, trong ó, m ng là c u trúc d li u thông d ng nh t.

5.1. M ng m t chi u
M ng m t chi u là m t chu i h u h n các ph n t d li u thu c cùng m t ki u d li u, t t i các ô nh liên ti p trong b nh . M i ph n t trong m ng có m t ch s khác nhau. M ng cho phép nh v và truy nh p n t ng ph n t b ng cách s d ng ch s c a ph n t ó. Ví d , i m s cho 7 môn thi c a m t sinh viên có th ư c lưu tr trong m t m ng có kích thư c b ng 7 (nghĩa là có 7 ô nh ) thay vì khai báo 7 bi n khác nhau cho i m thi t ng môn. M ng có th ư c hình dung như sau:
30 0 85 1 76 2 90 3 72 4 80 5 88 6

trong ó, m i ô bi u di n m t ph n t c a m ng – trong trư ng h p này là m t giá tr thu c ki u . B y ph n t c a m ng ư c ánh s l n lư t t 0 n 6, ó còn g i là ch s c a các ph n t trong m ng. B y ph n t c a m ng có th ư c xem như 7 bi n ki u v i "tên" c a chúng là , 1 , , 3 , , , và 6 , trong ó ch s c a m i ph n t ư c t trong c p ngo c vuông. Khi truy nh p m t ph n t m ng, có th dùng ch s là m t giá tr nguyên ho c m t bi u th c có giá tr nguyên. Ví d , v i bi n có giá tr b ng 3, l nh sau gán giá tr 100 cho :
+ = 1 ;

còn l nh sau tính trung bình c ng c a vào bi n :

1 r i ghi k t qu

80

= (

+

1 )

;

5.1.1. Khai báo và kh i t o m ng Cũng như m t bi n bình thư ng, m ng ph i ư c khai báo trư c khi s d ng. Cú pháp khai báo m t m ng trong C++ có d ng: ki u_d _li u tên_m ng s _ph n_t
;

trong ó, ki u_d _li u là m t ki u d li u h p l (ch ng h n , b …), tên_m ng là m t nh danh h p l , và s _ph n_t (luôn ngo c vuông) quy nh s lư ng ph n t mà m ng c n ch a. Ví d , m ng trong ví d
;

, , t trong c p

trên ư c khai báo như sau:

Lưu ý: giá tr s ph n t t trong c p ngo c vuông ph i là m t h ng s , do các m ng khai báo ki u này thu c b nh tĩnh và ph i có kích thư c ư c xác nh trư c khi chương trình th c thi. M ng v i kích thư c ng s ư c nói n trong chương sau. Hình 5.1 minh h a vi c khai báo và s d ng m ng m t chi u. Chương trình trong hình yêu c u ngư i dùng nh p i m cho 7 môn h c, l n lư t c ng d n t ng i m r i tính i m trung bình. ý r ng chương trình s d ng m t h ng bi n (NU B _ U ) lưu tr kích thư c m ng, cũng là s môn h c, thay vì s d ng giá tr 7 trong toàn b o n mã. Giá tr ch xu t hi n úng m t l n khi khai báo h ng NU B _ U . V i cách s d ng h ng như v y, n u ta mu n thay i s môn h c mà chương trình x lý, ta ch c n s a duy nh t m t v trí trong chương trình là l nh khai báo h ng NU B _ U thay vì ph i làm m t công vi c t n th i gian và d gây l i là tìm và s a t t c các giá tr 7 có liên quan (trong các chương trình ph c t p hơn, không ph i giá tr 7 nào cũng liên quan n s môn h c).

81

<

> ; _ U = ;

NU B ()

NU B = ; ( << " >> = + << " ;

_

U

;

=

;

< NU B

_

U

;

++) << " ";

" << ; ; " << NU B _ U

;

ươ 3 8 6 3 9 8 88

1

6

The average score is 74.42857
Hình 5.1: Ví d v khai báo và s d ng m ng.

Lưu ý s khác nhau v ng nghĩa c a giá tr bên trong c p ngo c vuông: t i l nh khai báo m ng thì nó là kích thư c m ng, còn khi truy nh p ph n t c a m ng thì nó là ch s c a ph n t m ng. Ta có th khai báo m ng ch a b t c lo i d li u nào ngo i tr tham chi u. Ch ng h n ta có th khai báo m t m ng ki u ch a m t xâu ký t . Khi khai báo m t m ng, ta có th kh i t o giá tr cho các ph n t c a m ng theo cách sau, v i lưu ý r ng s giá tr n m trong danh sách kh i t o không ư c vư t quá kích thư c ư c khai báo c a m ng.

82

=

6 ,

, 89,

, 88, 3 , 9

;

Ta cũng có th b qua không khai báo kích thư c c a m ng C++ t xác nh thông qua dài c a dãy kh i t o. Ví d l nh sau ây cho hi u qu gi ng h t l nh trên:
= 6 , , 89, , 88, 3 , 9 ;

N u không ư c kh i t o, các ph n t c a m ng s có giá tr không xác nh cho n khi ta gán cho chúng m t giá tr nào ó. Vi c s d ng các giá tr không xác nh s d n n l i lô-gic. 5.1.2. ng d ng c a m ng

M ng có th ư c dùng lưu tr và tính toán nhi u d ng d li u. D th y nh t là dùng m ng lưu tr m t chu i giá tr , ch ng h n như dãy i m s c a các môn h c như ví d trong Hình 5.1. Ta có th dùng m ng bi u di n t p h p, ch ng h n m ng = 1, , 1 i di n cho t p h p [0, 2], trong ó ph n t có giá tr khác 0 mang ý nghĩa r ng giá tr có m t trong t p h p. Ngoài ra, ta có th dùng các ph n t m ng làm các con m. Chương trình ví d trong Hình 5.2 gi l p vi c tung xúc x c và th ng kê s l n ra các m t có giá tr t 1 n 6. Chương trình s d ng m ng ch a các con m, trong ó dùng m s l n tung xúc x c ư c m t có giá tr . Vòng th nh t trong chương trình th c hi n gi l p vi c tung xúc 6.000.000 l n, sau m i l n tung l i tăng con m tương ng. gi l p tung xúc x c, chương trình dùng hàm sinh s ng u nhiên () thu c thư vi n b, v n n m trong b thư vi n chu n c a ngôn ng C. Hàm này tr v m t giá tr nguyên ng u nhiên trong kho ng t 0 n AND_ AX (m t h ng s ư c nh nghĩa trong b, có giá tr ph thu c t ng b cài t khác nhau c a C++ nhưng ư c m b o là không nh hơn 32767). có ư c m t giá tr ng u nhiên trong m t kho ng giá tr , ta k t h p (), phép l y ng dư và các phép tính s h c khác. Ví d , () % 6 + 1) như trong chương trình cho k t qu là m t s công th c ( ng u nhiên trong o n t 1 n 6. Th c ra hàm rand() ch sinh ra các s gi () sinh ra khi ư c g i l p i l p ng u nhiên (pseudocode). Chu i s mà l i trông có v ng u nhiên nhưng m i l n ch y chương trình l i cho ra cùng m t chu i. chu i s mà () sinh ra m i l n m i khác, ta c n dùng kèm hàm () trư c khi g i () l n u trong chương trình. Hàm () l y m t tham s ki u int và l y giá tr này làm h t gi ng cho chu i ng u nhiên s ư c sinh. Các h t gi ng khác nhau s cho chu i khác nhau. Trong chương

83

trình ví d , ta dùng th i gian hi n t i làm h t gi ng (g i hàm b ng 0).
< < < < > > b> > ; () b b ( ( ) ); 1, ( F , ; = 1; <= 6 = 1 + () % F ++; F F = 6; + 1

() v i

is

=

; b

; b

F

++ ) ;

<< "F

" <<

;

( << ;

= 1; << "

<= " <<

b

F

; <<

++ ) ;

ươ F 1 3

6

1 9 999 8 999 61 9989 99993 1 13
Hình 5.2: S d ng m ng m.

84

5.1.3. Trách nhi m ki m soát tính h p l c a ch s m ng i v i m ng ư c khai báo v i kích thư c n, ch s c a các ph n t trong m ng ó là các s nguyên t 0 n n–1. Ngoài ra, các giá tr khác u không h p l . Vi c truy nh p m ng b ng các ch s không h p l , ch ng h n khi truy nh p n -1 hay , có th d n n các thay i không mong mu n i v i d li u vùng b nh bên ngoài m ng (có th thu c v các bi n khác), h u qu là chương trình ch y sai ho c g p s c d ng t ng t. Trong nhi u ngôn ng l p trình, vi c truy nh p m ng ư c ki m soát t ng tránh trư ng h p truy nh p v i ch s không h p l . Tuy nhiên, trong C++, vi c truy nh p n các ph n t c a m ng v i ch s nh hơn 0 ho c l n hơn –1 không h ph m l i cú pháp, vi c truy nh p ra ngoài m ng không gây l i khi d ch nhưng có th gây l i khi ch y. L p trình viên có trách nhi m ki m soát các giá tr ch s m ng tránh trư ng h p này. 5.1.4. M ng làm tham s cho hàm Có th dùng m ng làm tham s cho hàm. Hình 5.3 là k t qu c a vi c s a chương trình trong Hình 5.1, ưa hai nhi m v nh p d li u cho m ng và tính i m trung bình vào hai hàm và truy n m ng vào trong hai hàm ó. ý r ng tuy các tham s m ng không ư c khai báo v i kí t "&" trong ph n khai báo và nh nghĩa hàm, nhưng th c ch t chúng là các tham chi u (thay vì giá tr ). Nói cách khác, khi chương trình th c thi, các hàm không t o các b n sao riêng c a các m ng ư c truy n làm tham s (vi c t o b n sao này có th có chi phí r t cao v b nh .) V y làm th nào khi ta c n quy nh r ng m t hàm không ư c s a i m t tham s m ng nào ó? (ví d không nên cho hàm quy n s a m ng .) Gi i pháp mà C++ cung c p là t khóa . Ta s a ph n khai báo tham s c a hàm t
( , );

thành
( , );

K t qu là trình biên d ch s không ch p nh n các dòng l nh s a giá tr c a tham s m ng bên trong hàm . Nên s d ng t khóa cho t t c các tham s mà hàm không có nhu c u thay i.

85

<

> ; _ ( U = , = ; < ; ) ; ++) " << ; << " ";

NU B

( << " >>

( = ( = + ; ; = ;

,

)

< ;

;

++)

() NU B ( _ U _ ; U ( " << ); , NU B _ U ; );

, NU B =

<< " ;

Hình 5.3: Ví d v m ng làm tham s c a hàm.

5.2. M ng nhi u chi u
C u trúc m ng có th có nhi u hơn m t chi u. M ng nhi u chi u có th ư c miêu t là "m ng c a các m ng". Ch ng h n, có th hình dung m ng hai chi u là m t b ng hai chi u g m các dòng và các c t, m i ô lưu m t giá tr thu c cùng m t ki u. Ví d , m ng A dư i ây là m t m ng kích thư c 3x4 g m các ph n t ki u nguyên. A 1 là bi u th c truy nh p t i ph n t t i ô m u xám (dòng 2, c t 1).

86

1 A 1 1 8 9 3 6 11

3

1

1

M t ví d khác v m ng hai chi u: lưu m t bàn c ca-rô, ta có th dùng m t m ng hai chi u ch a các kí t . Trong ó, kí t '.' bi u di n m t ô tr ng trên bàn c , các kí t 'x' và 'o' l n lư t bi u di n các kí hi u trong trò chơi c ca rô. Khai báo m ng hai chi u như sau:
B A D_H H = ; B A D_ D H = 6; B A D_H H B A D_

b

D H ;

Ta dùng hai ch s hàng và c t
b 1 = 'x';

truy nh p t ng ph n t trong m ng, ví d :

o n chương trình sau có th
( ( << b << ; w = ,

ư c dùng

v bàn c ra màn hình.
++)

w < B A D_H H , w++) = , < B A D_ D H, w ;

Cũng như m ng m t chi u, m ng nhi u chi u cũng có th dùng làm tham s cho hàm. Lưu ý, khi khai báo m ng nhi u chi u như là tham s c a hàm, chúng ta ph i khai báo kích thư c t t c các chi u c a m ng, ngo i tr chi u u tiên có th b tr ng.
B ( b N_ D H );

là m t khai báo h p l , còn
B ( b );

là m t khai báo không h p l . i v i các m ng có s chi u nhi u hơn 2, cú pháp cũng tương t . Ví d

87

(

A

3

);

5.3. M ng và xâu kí t
Chúng ta ã dùng n các xâu kí t , ch ng h n " " trong Hình 5.3. Các ngôn ng l p trình u có c u trúc xâu kí t (string), trong ó quy nh cách tham chi u t i t ng ph n t trong xâu. Kèm theo ó là m t b các hàm và th t c th c hi n các phép toán trên d li u xâu, ch ng h n như xác nh dài xâu, so sánh n i dung xâu, ghép xâu. B thư vi n chu n C++ có thư vi n khá m nh v i ki u d li u dùng x lý và thao tác v i các xâu kí t . Tuy nhiên, v b n ch t, xâu kí t là chu i các kí t , nên ta có th bi u di n xâu kí t b ng m t m ng m t chi u g m các ph n t ki u . Nhi u ti n ích trong thư vi n chu n C++ s d ng xâu kí t ki u m ng, các chương trình C++ truy n th ng cũng như nhi u chương trình hi n i v n s d ng xâu kí t d ng m ng. Do ó, ta v n c n h c s d ng thành th o ki u d li u này. Ví d , m ng sau ây g m 20 ph n t ki u
;

.

V lý thuy t, m ng trên có th ch a m t chu i các ký t v i dài không quá 20. Nhưng ta còn có th lưu t i ó các xâu kí t có dài ng n hơn, ch ng h n " " hay "H ". Xâu " " mà ta ã g p cũng có c u trúc tương t , i m khác bi t ch là ây là m t h ng xâu kí t . H ng xâu kí t có th dùng làm giá tr kh i t o t i l nh khai báo m ng . Ví d :
= "H ";

Do m ng có th lưu xâu kí t có dài nh hơn kích thư c c a m ng, ta c n có cơ ch xác nh i m cu i hay dài c a xâu. C++ s d ng kí t (' ') ánh d u k t thúc c a xâu kí t . Ví d , m ng có th dùng lưu xâu " " hay "H " như trong Hình 5.4.

88

greeting

H
Hình 5.4: Xâu ký t lưu trong m ng.

Lưu ý: các kí t ' ' n m cu i xâu ánh d u k t thúc xâu; còn các ô màu xám kí hi u các ph n t m ng n m ngoài xâu (tuy v n n m trong m ng) và có giá tr không xác nh. Khi khai báo m ng lưu tr m t xâu kí t , ta c n chú ý khai báo kích thư c m ng l n ch a c kí t n m cu i xâu.
< > ; AX_NA () AX_NA << " >> ; << "H " << ; _L N H ; "; << " "; _L N H = 1 ;

ươ

H
Hình 5.5: Ví d v xâu kí t .

Hình 5.5 minh h a m t chương trình ví d nh p m t xâu kí t và ghi ra màn hình. Ta có th th y r ng m ng kí t (hay xâu) ư c s d ng như là m t cho phép c các xâu kí t bi n bình thư ng i v i các l nh vào ra d li u, không ch a kí t tr ng. N u mu n m b o xâu nh p vào s không dài quá kích thư c c a m ng name, ta có th dùng hàm w ch n s kí t s ư c c vào. Ví d l nh sau gi i h n s kí t ư c c vào không vư t quá 99 và dành v trí th 100 trong m ng cho kí t null ánh d u cu i xâu.

89

>>

w(1

) >>

;

N u ta mu n nh p c m t dòng, trong ó có c các kí t tr ng (tên y thư ng ch a d u tr ng phân cách gi a h , m, và tên), ta có th dùng l nh () cho công vi c này. Ví d , c vào m ng m t dòng text có dài t i a 100, k t thúc b ng kí t xu ng dòng, ta dùng l nh:
( , 1 , ' ' );

lưu xâu kí t input, tham s th hai là dài t i a c a input, và tham s th ba là kí t ánh d u cu i input (kí t này s không ư c ghi vào m ng ích). 5.3.1. Kh i t o giá tr cho xâu kí t Có hai cách kh i t o giá tr cho xâu kí t ngay t i l nh khai báo: 1. Kh i t o xâu theo cách kh i t o m ng:
= 'H', ' ', ' ', ' ', ' ', ' ' ;

() òi h i tham s th nh t là m ng

2. Dùng h ng giá tr

kh i t o xâu:
= "H ";

i v i cách th nh t, ta ph i t i n kí t cu i xâu. Còn cách th hai, các bi u di n giá tr xâu có d ng dùng c p d u nháy kép ư c t ng kèm thêm kí t . Lưu ý r ng chúng ta ang nói v công o n kh i t o giá tr cho xâu ch không nói v l nh gán giá tr cho c xâu. Cũng như các lo i m ng nói chung, i v i m ng (hay xâu ký t ), không ư c phép dùng m t l nh gán tr hàng lo t cho các ph n t trong m ng. Các l nh sau s gây l i khi d ch:
= 'H', ' ', ' ', ' ', ' ', ' = " "; ' ;

5.3.2. Thư vi n x lý xâu kí t c a C++ (v n là thư vi n c a C) cung c p m t lo t Thư vi n các hàm ti n ích cho vi c x lý xâu kí t , ch ng h n như tr v dài xâu, sao chép xâu, và so sánh xâu. Xem thêm chi ti t v thư vi n này trong Ph l c C.

90

5.4. Tìm ki m và s p x p d li u trong m ng
Tìm ki m d li u trong m ng là xác nh xem m t giá tr nào ó ( ư c g i là khóa) có m t trong m ng hay không, n u có thì nó n m v trí nào. S p x p m ng là s p t l i v trí c a các ph n t m ng theo m t trong hai th t : giá tr khóa tăng d n ho c gi m d n. Ví d , m t danh sách t có th ư c s p x p theo th t t i n, danh sách sinh viên ư c s p x p theo s sinh viên. M c này gi i thi u m t s thu t toán cơ b n cho vi c tìm ki m và s p x p d li u trong m ng. 5.4.1. Tìm ki m tuy n tính Thu t toán tìm ki m tuy n tính (linear search) duy t tu n t t ng ph n t trong m t m ng, so sánh khóa v i m i ph n t . Khi g p m t ph n t kh p v i khóa, thu t toán k t thúc và tr v ch s c a ph n t ó. N u duy t n h t m ng mà v n không tìm th y ph n t nào kh p v i khóa, thu t toán k t lu n là khóa c n tìm không có trong m ng. Ví d , v i m ng {3, 18, 2, 3, 10, 1}, n u ta th c hi n tìm ki m v i khóa b ng 10, thu t toán tìm ki m tuy n tính s duy t l n lư t t ph n t u tiên (3) cho t i khi g p ph n t th năm (10) và tr v k t qu là ch s m ng c a ph n t ó (v i m ng C++ ánh s t 0, k t qu c a thu t toán trong trư ng h p này s là 4).

91

<

> ; ( , <= ) ; , ++) ; k )

( ( -1;

=

; == k

() 1 ; << " >> = >= ) << << ; k ; ( << " << " , , " << "; ); ; "; = 1 , 3, = 6; , , , 1 ;

(

ươ k 3 k
Hình 5.6: Ví d v tìm ki m tuy n tính.

3 1

Chương trình trong Hình 5.6 minh h a thu t toán tìm ki m tuy n tính trong m ng. Trong ó, thu t toán tìm ki m ư c cài trong hàm tr v ch s c a ph n t m ng kh p v i khóa tìm ki m ho c tr v -1 n u không tìm th y. 5.4.2. Tìm ki m nh phân Thu t toán tìm ki m tuy n tính ư c gi i thi u m c trư c tuy ơn gi n nhưng có ph c t p O(n) nên cho hi u qu không cao i v i d li u l n. Tìm ki m

92

nh phân (binary search) là m t thu t toán tìm ki m ph c t p hơn nhưng cho hi u qu cao hơn. Tuy nhiên, nó còn òi h i m ng u vào ã ư c s p x p. Gi s m ng ã ư c s p x p tăng d n, thu t toán tìm ki m nh phân ho t ng như sau: l n l p u tiên, l y ph n t n m gi a m ng. N u ph n t ó kh p v i khóa thì thu t toán k t thúc. N u nó có giá tr l n hơn khóa thì ch c ch n n a sau c a m ng ch a toàn các ph n t l n hơn khóa, và do ó không c n tìm t i ph n này. Nghĩa là vùng tìm ki m nay ã ư c gi i h n ch còn là n a u c a m ng. Còn n u ph n t gi a có giá tr nh hơn khóa, v i l p lu n tương t như trên, ta có gi i h n c n tìm ki m thu h p l i ch còn là n a sau c a m ng. Như v y, t i m i l n l p, thu t toán so sánh khóa v i ph n t n m gi a ph n m ng c n tìm ki m ho c là th y ph n t ó kh p v i khóa ho c là lo i b m t n a m ng ra kh i ph m vi c n tìm ki m. Thu t toán k t thúc khi tìm th y m t ph n t có giá tr b ng khóa ho c khi ph m vi c n tìm ki m b gi m xu ng thành m t m ng con có kích thư c b ng 0. Ví d , cho m ng {1, 3, 4, 7, 10, 12, 15}. tìm ph n t có giá tr 10, u tiên thu t toán l y ph n t n m gi a m ng là 7 và so sánh v i 10. Vì 7 nh hơn 10, thu t toán b qua n a u c a m ng, ph m vi tìm ki m thu h p thành o n m ng {10, 12, 15}. T i l n l p ti p theo, thu t toán l i l y ph n t n m gi a là 12 và so sánh v i khóa 10. Vì 12 l n hơn 10 nên n a sau c a o n {10, 12, 15} b b qua, ph m vi tìm ki m ư c thu h p l i ch còn o n m ng g m m t ph n t {10}. L n l p th ba, ph n t n m gi a m ng (ph n t duy nh t còn l i trong o n c n tìm) có giá tr trùng v i khóa nên thu t toán k t lu n ã tìm th y ph n t có giá tr 10. Thu t toán ư c minh h a b ng chương trình trong Hình 5.7.

93

<

> ; ( = , > << ( ( , = ) << " " << = ( + ) == k ) > k ) = + 1; << ; = ; ; ; ; , k )

b

w

(

-1;

() 1 ; << " >> = b >= ) << << ; k ; ( << " << " , , " << "; ); ; "; = 1, 3, = ; , , 1 , 1 , 1 ;

(

}
Hình 5.7: Ví d v tìm ki m nh phân.

5.4.3. S p x p ch n S p x p ch n (selection sort) là m t trong nh ng thu t toán s p x p ơn gi n nh t, nhưng l i có hi u qu không cao i v i d li u có kích thư c l n (m ng có s ph n t l n). Ho t ng c a thu t toán này r t ơn gi n. l n l p th nh t, ta tìm ph n t nh nh t c a toàn m ng r i tráo v trí c a nó v i ph n t u tiên (gi thi t r ng ta ang c n s p x p m ng theo th t tăng d n). L n l p th 2, ta tìm ph n t nh th nhì trong toàn m ng, nghĩa là ph n t nh nh t c a o n m ng tính t ph n t th hai tr i, r i tráo v trí c a nó v i ph n t th 94

hai trong m ng. Thu t toán ti p t c cho n l n l p cu i cùng – khi ph n t l n nhì m ng ư c ch n ra và tráo v i ph n t có ch s sát cu i, d n n vi c ph n t l n nh t m ng n m t i v trí cu i m ng. T ng quát, k t qu c a l n l p th i là ph n t nh th i c a m ng ư c x p vào v trí th i trong m ng. Hình 5.8 minh h a thu t toán s p x p ch n.
< > ; ( ( = ; < , - 1; ) ++) , ( = ; j = + 1; j < ( j < w = = = ; ; ; ; j++) ) = j; -1

w

() 1 << " >> << " ( , ; "; ; "; = ( << " ( = << ; ; < << " "; ; < , "; ; ++) ; ++) >> ;

);

Hình 5.8: S p x p ch n.

95

Bài t p
1. Nh p vào t bàn phím m t danh sách các s X1, X2,…, X2n-1, X2n. Hãy vi t m t hàm tính giá tr c a bi u th c sau ây (hi n k t qu tìm ư c ra màn hình): ( X1 + X2n) * (X2 + X2n-1) *…* (Xn + Xn+1) 2. Nh p vào t bàn phím danh sách tên các b n sinh viên trong l p. Hãy tìm hi u và cài t thu t toán s p x p n i b t (bubble sort) s p x p danh sách tên theo th t tăng d n. Hi n danh sách sau khi ã s p x p ra màn hình. 3. Nh p vào t bàn phím m t danh sách các s nguyên. Hãy hi n ra màn hình t t c các b s (a, b, c) mà t ng c a chúng b ng 25. 4. M t qu i ư c chia thành m t lư i ô vuông có kích thư c m*n ô vuông. M i ô vuông ch a m t s nguyên i di n cho cao t i ô vuông ó. Hãy tìm và hi n ra màn hình: • Ô vuông có • Ô vuông có cao l n nh t cao nh nh t gi a cao hơn gi a th p hơn ghi

• T t c các hình vuông có kích thư c 3*3, mà ô vuông các ô vuông xung quanh • T t c các hình vuông có kích thư c 3*3, mà ô vuông các ô vuông xung quanh

5. Nh p vào t bàn phím m t xâu kí t . S d ng ki u d li u char[] ra màn hình các k t qu sau: • dài c a xâu kí t v a nh p

• Xâu kí t sau khi ã lo i b t t c các d u ‘?’, ‘!’ • Xâu kí t sau khi chèn vào gi a xâu t “C++”. • Xâu kí t sau khi ã xóa b 5 kí t n m gi a

6. Nh p vào t bàn phím m t danh sách tên các b n sinh viên trong l p, hãy m xem có bao nhiêu b n có tên v i ch cái b t u là ‘T’, ‘C’, ‘V’, ‘A’,

96

‘Q’. Tìm tên có s b n trùng nhau là nhi u nh t. Hi n k t qu tìm ư c ra màn hình. 7. Nh p vào t bàn phím m t xâu ký t là danh sách tên các sinh viên. Hai tên ng li n nhau ư c cách nhau b i ít nh t m t d u cách. Hãy tính xem có bao nhiêu sinh viên trong danh sách. Ví d : D li u vào Vinh tuan vinh blah blah K t qu tương ng 5

8. Nh p m t xâu ký t t bàn phím. Hãy chu n hoá xâu b ng cách lo i b các ký t không ph i ch cái, d u cách, d u ph y, d u ch m. Các t cách nhau b i úng m t d u cách và ch vi t hoa ch cái u tiên. Ví d : D li u vào tOi te1N !LA ng2uyen v3an aN;. K t qu tương ng Toi Ten La Nguyen Van An.

9. Nh p vào t bàn phím 1 dãy kí t g m các kí t 0..9. Hãy tính s lư ng kí t 0, s lư ng kí t 1,…, s lư ng kí t 9 trong xâu v a nh p vào. Hi n k t qu ra màn hình. 10. Nh p t bàn phím 2 s nguyên l n (s lư ng ch s l n hơn 100). Hãy vi t chương trình tính và hi n k t qu ra màn hình: • T ng c a hai s trên • Hi u c a hai s trên • Tích c a hai s trên 11. Nh p t bàn phím 1 dãy các ch s t 0 n 9. Hãy vi t chương trình ch các ch s thu ư c (hi n k t qu ra màn hình): • S nguyên có giá tr l n nh t • S nguyên có giá tr nh nh t Ví d : Dãy u vào: 1312013 o

• S nguyên có giá tr l n nh t: 3321110 97

• S nguyên có giá tr nh nh t: 0111233

98

Chương 6. Con tr và b nh
Con tr là m t công c mà m t s ngôn ng l p trình b c cao, c bi t là C và C++, cung c p cho phép chương trình qu n lý và tương tác tr c ti p v i b nh . Nó giúp chương trình linh ng và hi u qu . Tuy nhiên, s d ng con tr cũng d d n n sai sót và khó phát hi n ra l i.

6.1. B nh máy tính
hi u v con tr , trư c tiên ta s tìm hi u v b nh máy tính. Ta có th hình dung b nh máy tính là m t lo t các ô nh n i ti p nhau, m i ô nh có kích thư c nh nh t là m t byte. Các ô nh ơn này ư c ánh s liên t c, ô nh sau có s th t hơn s th t c a ô nh li n trư c là 1. T c là ô nh 1505 s ng sau ô nh 1504 và ng trư c ô nh 1506 (xem Hình 6.1). S th t c a ô nh có th ư c g i là a ch c a ô nh ó.
a ch b nh 1 3 1 1 1 6 1 1 8 1 9 1 1
Hình 6.1: Bi n

N i dung Tên bi n ô nh c 1 byte 'H' ' ' ' ' ' ' ' ' ' ' greeting

ee i

– xâu kí t "Hello"– trong b nh .

6.2. Bi n và

a ch c a bi n

Bi n trong m t chương trình là m t vùng b nh ư c dùng lưu d li u. Vi c truy nh p d li u t i các ô nh ó ư c th c hi n thông qua tên bi n. T c là, ta không ph i quan tâm n v trí v t lý c a ô b nh . Khi m t bi n ư c khai báo, ph n b nh c n thi t s ư c c p phát cho nó t i m t v trí c th trong b nh , v trí ó ư c g i là a ch b nh c a bi n ó. Ví d , trong Hình 6.1, bi n có a ch là 1504. Thông thư ng, h i u hành s quy t nh v trí c a bi n trong b nh khi chương trình ch y.

99

l y a ch c a m t bi n, trong C++ ta s d ng toán t tham chi u a ch (&). Khi t toán t tham chi u trư c tên c a m t bi n, ta có m t bi u th c có giá tr là a ch c a bi n ó trong b nh . Ví d :
<< << & = 9; ; ; k b b 9 a b ó 9

Trong th c t , trư c khi chương trình ch y, chúng ta không th bi t ư c c a bi n .

a ch

6.3. Bi n con tr
Bi n con tr là m t lo i bi n c bi t, ư c dùng lưu gi a ch c a các vùng nh . T c là, giá tr c a m t bi n con tr là a ch c a m t ô nh trong b nh . Hay nói m t cách hình tư ng, bi n con tr ch n m t ô nh trong b nh , nó ư c dùng gián ti p truy nh p n ô nh ó. Ví d , gi s ta có bi n ki u int n m t i a ch 0x2a52ec, bi n con tr A ang ch t i bi n . i u ó có nghĩa bi n A ang có giá tr 0x2a52ec và i u quan tr ng là có th dùng A gián ti p truy nh p t i bi n b ng cách dùng bi u th c ( A ), xem Hình 6.2.
ptrApples apples

Hình 6.2. Con tr ptrApples ch t i bi n apples, gián ti p truy nh p ô nh apples

Cũng như các lo i bi n khác, bi n con tr c n ư c khai báo trư c khi s d ng. V i các bi n và A nói trên, có th khai báo b ng l nh sau:
A , ;

trong ó, bi n A ư c khai báo thu c ki u (con tr t i m t giá tr int), còn bi n ư c khai báo thu c ki u . Lưu ý là d u * kí hi u ki u con tr ch áp d ng duy nh t cho bi n n m ngay sau nó ch không áp d ng cho t t c các bi n n m sau, m i bi n con tr trong l nh khai báo c n có m t d u * t trư c nó. Ví d , l nh sau khai báo hai bi n con tr :

100

A

,

P

;

Con tr c n ư c kh i t o b ng giá tr 0 (hay NULL) ho c m t a ch ngay t i l nh khai báo ho c b ng m t l nh gán. M t con tr có giá tr 0 hay NULL (m t h ng s tương ương v i 0 ư c nh nghĩa trong t p thư vi n ) không ch t i ô nh nào và ư c g i là con tr null. M t con tr chưa ư c kh i t o ch n m t vùng b nh không xác nh ho c chưa ư c kh i t o, vi c vô tình dùng con tr chưa ư c kh i t o truy nh p b nh là m t l i l p trình khó phát hi n, có th d n n d li u chương trình b s a làm chương trình ch y sai ho c gây s c làm s p chương trình. ây là m t trong nh ng c i m không an toàn c a ngôn ng C/C++. Do ó, l p trình viên nên chú ý kh i t o con tr ngay sau khi khai báo. truy nh p d li u t i ô nh mà bi n con tr ch n ta s d ng toán t *. Ví d , ta dùng bi u th c A truy nh p bi n mà A ang tr t i. Có th dùng bi u th c A bên trái cũng như bên ph i c a phép gán, nghĩa là c cũng như ghi giá tr vào ô nh .N u dùng phép toán truy nh p * cho con tr null, chương trình s g p l i run-time và d ng l p t c. Hình 6.4 minh h a v vi c khai báo và s d ng bi n con tr . Trong ví d , ta khai báo m t bi n con tr A dùng lưu gi a ch ô nh c a bi n . L nh
A = & ; A

s gán a ch c a bi n cho bi n con tr tương t như trong Hình 6.2 và Hình 6.3
a ch b nh x x x x 8 x2a52e x Hình 6.3: Bi n con tr p N i dung ô nh c 4 byte

và t o hi u ng

Tên bi n

x2a52e

ptrApples

x

9

apples

Apples có giá tr là

a ch c a bi n apples.

Lưu ý, các tác ng trên ô nh bi n con tr A ch n cũng chính là các tác ng ư c th c hi n trên bi n apples và ngư c l i. C th là l nh 101

++;

s tăng giá tr c a bi n do bi n con tr A Tương t , l nh
A += 1;

lên m t, ng nghĩa v i vi c tăng giá tr ch n lên 1.

ô nh

s tăng giá tr t i ô nh mà bi n con tr tăng giá tr c a bi n thêm 1.

A

thêm 1,

ng nghĩa v i vi c

Chương trình trong Hình 6.4 còn minh h a vi c in giá tr c a con tr ra màn hình. Có th dùng cout in giá tr c a con tr như i v i nhi u ki u d li u khác. Tuy nhiên, nh d ng c a giá tr in ra ph thu c vào t ng trình biên d ch, m t s h th ng in ra các giá tr con tr d ng h cơ s 16 (như trong hình), các h th ng khác s d ng nh d ng h th p phân.

102

<

> ;

(

, = 9; << " << "A A ; = & << " << "V ++; << " << "V A ; " << A " <<

)

<< " << &

; << ;

A

A " <<

<< A

; << ;

" << A += 1;

<< " <<

; A << ;

A << " << "V ;

" << A

<< " <<

; A << ;

ươ
9 A A V 1 V 11 V A 11
Hình 6.4: Khai báo và s d ng bi n con tr .

x x A A 9 1

M t trong nh ng ng d ng thư ng c a con tr là làm con ch y trên chu i các ô nh liên ti p, ch ng h n như m ng. Chương trình trong Hình 6.5 minh h a vi c ó. Trong chương trình là m t vòng l p có nhi m v duy t và in ra toàn b các ph n t c a m ng . Con ch y trong vòng l p là con tr v i giá tr ban u là a ch c a ph n t u tiên m ng . T i m i l n l p, ph n t m ng 103

hi n ư c tr t i ư c c b ng bi u th c r i in ra màn hình, sau ó ư c tăng thêm 1 ( ++) v i hi u qu là nó s tr t i ph n t ti p theo trong m ng. Vòng l p d ng khi b t u tr vư t ra xa hơn v trí ph n t cu i m ng ( i u ki n l p là <= & 6 ).

Hình 6.5: Dùng con tr làm con ch y duy t m ng.

Hình 6.5 còn minh h a các phép toán c ng và tr con tr v i m t s nguyên và các phép so sánh con tr . Có th dùng các phép so sánh b ng/khác và l n hơn/nh hơn cho con tr . Các phép toán này so sánh các a ch lưu trong các con tr . M t phép so sánh thư ng g p là so sánh m t con tr v i 0 ki m tra xem ó có ph i là con tr null hay không. Các phép so sánh l n hơn/nh hơn i v i các con tr là vô nghĩa tr khi chúng ang tr t i các ph n t c a cùng m t m ng. Trong trư ng h p ó, k t qu c a phép so sánh cho th y con tr này tr t i ph n t m ng có ch s cao hơn con tr kia. Trong Hình 6.5, con tr ptr ư c so sánh v i a ch c a ph n t cu i cùng xem nó ã ch y n v trí ó hay chưa. Các phép toán c ng tr i v i con tr không có nghĩa c ng hay tr chính s nguyên ó vào giá tr lưu trong bi n con tr . Th c t , giá tr ư c c ng vào hay tr i là s nguyên ó nhân v i kích thư c c a ki u d li u mà con tr tr t i. Ví d , gi s con tr ki u ang tr t i ph n t m ng và ki u d li u có kích thư c 4 byte, l nh += 3; s gán cho giá tr 4020 (nghĩa là 4008 + 3 * 4) làm nó tr t i . Xem minh h a t i Hình 6.6.

104

Hình 6.6. Phép c ng 3 vào con tr ptr.

6.4. M ng và con tr
Trong C++, m ng và con tr có quan h ch t ch v i nhau và g n như có th dùng thay th cho nhau. M t cái tên m ng có th ư c coi như m t h ng con tr , có th dùng bi n con tr trong b t c cú pháp nào c a m ng. Gi s , khi khai báo m t m ng
;

ta ã khai báo m t vùng nh liên ti p g m 7 ô, m i ô ch a m t s nguyên. Trong C++, m ng ư c cài t b ng con tr . C th là, tên m ng ( ) có th ư c coi là m t h ng con tr ki u tr t i ô nh u tiên trong m ng ( ). truy c p n ph n t có ch s trong m ng ho c ( + ). Ví d , và ph n t u tiên trong m ng. , ta có th s d ng u có ý nghĩa là

thao tác v i m ng ư c minh h a trong Hình 6.7. Cách dùng ki u con tr Trong ó vòng l p l n lư t in ra các ph n t trong m ng, v i bi u th c ( + ) ư c dùng truy nh p ph n t th trong m ng.

105

<

> ;

(

, =

) 1, ,3, , ,6, = ; + ; ++)

( << ; (

< ; ) << " ";

}
Hình 6.7: S d ng tên m ng như con tr .

Ngư c l i, n u ta có là m t con tr ki u int, l nh sau gán giá tr c a cho làm nó tr t i v trí u tiên trong m ng .
= ;

L nh trên tương ương v i
= & ;

Sau ó ta có th dùng bi n con tr là m t tên m ng.

thao tác m ng

như th

Hình 6.8 minh h a vi c ó, ây ch là s a i nh t chương trình trong Hình 6.7 th c hi n cùng m t nhi m v nhưng l i dùng v i cú pháp m ng thay vì dùng tên m ng v i cú pháp con tr .

106

<

> ;

(

, = =

) 1, ,3, , ,6, ; ; < ;

( << ;

=

; <<

++) ;

}
Hình 6.8: S d ng con tr như tên m ng.

6.5. B nh

ng

Trong t t c các chương trình ví d trư c, ta m i ch dùng b nh trong ph m vi các bi n ư c khai báo trong mã ngu n v i kích thư c ư c xác nh trư c khi chương trình ch y. V i C++, t t c các bi n ư c khai báo trong chương trình u n m trong b nh tĩnh và có kích thư c xác nh trư c. N u chúng ta c n n lư ng b nh mà kích thư c ch có th bi t ư c khi chương trình ch y thì sao? Ch ng h n khi chương trình c a ta c n làm vi c v i m t m ng mà kích thư c c a nó không xác nh ư c khi chương trình chưa ch y, và ta cũng không th ư c lư ng dài t i a mà c n c d li u vào xác nh dài c n thi t. Gi i pháp là s d ng b nh ng. Không như các bi n thông thư ng ch c n khai báo, các bi n n m trong vùng b nh ng c n ư c c p phát khi mu n s d ng và gi i phóng m t cách tư ng minh khi không còn ư c dùng n. Trong C++, con tr cùng v i các toán t w và phát và gi i phóng d li u n m trong b nh ng. 6.5.1. C p phát b nh Khi m t bi n con tr
A

là công c

xin c p

ng

ư c khai báo, ví d
;

giá tr c a bi n con tr A chưa ư c xác nh, nghĩa là nó chưa tr vào m t vùng nh xác nh trư c nào. Chúng ta cũng có th xin c p phát m t vùng 107

nh ng, và vùng nh này ư c qu n lý (tr t i) b i bi n con tr b ng cách s d ng toán t c p phát b nh ng w như sau:
A = w ;

A

Lênh này s c p phát m t vùng nh cho m t giá tr ki u int, a ch vùng nh A . Quá trình c p phát b nh này ư c th c này ư c ghi vào bi n hi n trong quá trình ch y chương trình và ư c g i là c p phát b nh ng. Sau l nh c p phát trên, ta có th ti n hành lưu gi , c p nh t giá tr vùng nh này thông qua a ch c a nó (hi n lưu t i bi n A ). N u l nh c p phát không thành công (ch ng h n vì không còn b nh ), A s nh n giá tr 0. L p trình viên c n chú ý phòng nh ng tình hu ng này. 6.5.2. Gi i phóng b nh ng

Do lư ng b nh ng là có h n, d li u t trong b nh ng nên ư c gi i phóng khi dùng xong dành b nh cho các yêu c u c p phát ti p theo. Vi c gi i phóng vùng nh ư c th c hi n b ng toán t . Ví d , l nh sau gi i phóng ô nh ki u mà con tr A hi n ang tr t i.
A ;

Sau khi ư c gi i phóng, vùng nh phát b nh ng khác.

ó có th

ư c tái s d ng cho m t l n c p ng.

Hình 6.9 minh h a v vi c c p phát, s d ng, và gi i phóng b nh

108

<

> ;

( A Apples A << " A << " dele e p ; =

, ; ew i ; A += ; A Apples

)

p

" << " <<

A A

<< <<

; ;

}
Hình 6.9: C p phát, s d ng và gi i phóng b nh ng.

Lưu ý: n u vì sơ xu t c a ngư i l p trình hay vì lý do nào ó mà t i m t th i i m nào ó chương trình không còn lưu ho c có cách nào tính ra a ch c a m t vùng nh ư c c p phát ng, thì vùng b nh này ư c xem là b "m t". Nghĩa là chương trình không có cách gì truy nh p hay gi i phóng vùng b nh này n a, sau khi chương trình k t thúc nó m i ư c h i u hành thu h i. Ví d , o n chương trình sau làm th t thoát ph n b nh ư c c p phát do l nh w th nh t, do con tr duy nh t gi a ch c a ô nh ó ã b gán giá tr m i, ta không còn có th l y l i ư c a ch c a vùng nh ó s d ng ho c gi i phóng.
1 = = 1 = w w ; ; ;

6.6. M ng

ng và con tr
ư c cho kích li u

Trong các chương trình ví d t trư c n gi , kích thư c c a m ng ph i xác nh trư c khi khai báo. T c là, kích thư c c a m ng là m t h ng s trư c. Trong nhi u trư ng h p, chúng ta khó có th xác nh trư c ư c thư c c a m ng ngay t khi l p trình, mà kích thư c này ph thu c vào d u vào cũng như quá trình ch y chương trình.

109

kh c ph c tình tr ng trên, C++ cho phép chúng ta s d ng con tr t o m ng có kích thư c ng n m trong b nh ng. Nh ng m ng ư c t o theo cách ó ư c g i là m ng ng, b i kích thư c m ng và vi c c p phát b nh cho m ng ư c xác nh và ti n hành trong quá trình ch y chương trình. Vi c khai báo m ng ng ư c ti n hành thành hai bư c: 1. Khai báo con tr m ng: Trư c tiên, khai báo m t bi n con tr : data_type array_name; trong ó data_type là ki u d li u c a m ng, array_name là tên m ng. 2. Xin c p phát b nh : Sau khi khai báo, chúng ta xin c p phát b nh cho bi n con tr b ng toán t new [] theo c u trúc sau: array_name = new data_type [size]; h th ng s c p cho chương trình m t vùng nh liên ti p có th ch a ư c size ph n t có ki u data_type. a ch c a ph n t u tiên ư c ch n b i bi n array_name. Lưu ý, size có th là m t h ng s , ho c là m t bi n. Sau khi ã c p phát b nh thành công, ta có th i x v i bi n con tr array_name như m t m ng thông thư ng v i size ph n t . T c là, truy c p n ph n t th i trong m ng, ta có th s d ng array_name[i] ho c *(array_name + i). Gi i phóng b nh : Khi chúng ta không s d ng n m ng ng n a, chúng ta ph i ti n hành gi i phóng b nh ã xin c p phát b ng cách s d ng toán t delete [] như sau:
delete [] array_name;

Lưu ý khi gi i phóng b nh
delete array_name;

ng cho m t m ng, n u ta s d ng l nh

thì ch có ô nh array_name[0] ư c gi i phóng, còn các ô nh ti p theo c a m ng không ư c gi i phóng. Hình 6.10 minh h a vi c s d ng m ng ng tính t ng i m c a m t danh sách sinh viên nh p vào t bàn phím. S lư ng sinh viên không ư c xác nh trư c mà ư c ngư i dùng nh p vào t bàn phím.

110

n l de n nt n e

t e e td; * e ; t e n e ; [])

n( nt nt n t n e n nte e

e

e

;

( nt t n

nt = 0; nt nte t e e [ nt];

n

e e

e ;

nt++) nt

;

nt t t l ( nt t t l t

= 0; nt = 0; += t l

nt e [

n e nt]; t t l

e ;

nt++)

endl;

et

n 0;

}
Hình 6.10: M ng ng và con tr .

6.7. Truy n tham s là con tr
Như ã ư c gi i thi u trong M c 4.5, C++ có hai phương pháp truy n d li u vào trong hàm: truy n b ng giá tr và truy n b ng tham chi u. Trong phương pháp truy n b ng tham chi u, M c 4.5 ã nói v cách dùng i s là tham chi u. Trong m c này, chúng tôi s gi i thi u ki u truy n b ng tham chi u còn l i: dùng i s là con tr . Còn nh r ng các i s là bi n tham chi u cho phép hàm ư c g i s a giá tr d li u c a hàm g i. Các i s tham chi u còn cho phép chương trình truy n lư ng d li u l n vào hàm mà không ph i ch u chi phí cho vi c sao chép d li u như khi truy n b ng giá tr . Cũng như v y, các i s là con tr có th ư c s

111

d ng s a i các bi n c a hàm g i ho c trong khi tránh ư c vi c sao chép d li u.

truy n các

i tư ng d li u l n

Trong C++, con tr ư c dùng kèm v i toán t * th c hi n cơ ch truy n b ng tham chi u. Khi g i m t hàm, các i s c n s a giá tr ư c truy n vào trong hàm b ng a ch c a chúng (s d ng toán t a ch &).
n l de n d n w e t e e td; nt * )

( nt *

nt t = * ; * = * ; * = t ;

nt

n( nt nt t n t w t ( ;

*

[])

nte t e n ; e ); te e w

e

nd

;

n

= = = =

endl;

w

n

endl;

et

n 0;

ươ nte t e n e e e w n te w n nd = = = =

Hình 6.11: Tham s c a hàm là con tr .

Chương trình trong Hình 6.11 minh h a cách s d ng con tr truy n d li u vào hàm qua tham chi u. Hàm w có nhi m v tráo i giá tr c a hai bi n. Nó nh n các tham s và là con tr t i các bi n c n i giá tr , r i thông qua và truy nh p gián ti p t i các bi n ó s a giá tr . Còn t i hàm n, khi 112

mu n i giá tr c a hai bi n a và b, khi g i hàm w .

a ch c a hai bi n này ư c truy n vào và và

Trong Hình 6.12, bi n con tr e ư c truy n vào hàm et l l te . D n n tham s hình th c c a hàm et l l te chính là con tr t i m ng e trong hàm n.
n l de n d n et ( nt t n e t e e td; e nt n n e e e e ) e ; nt++) nt

( nt *

nt = 0; nt nte t e e [ nt];

;

nt

l

l te

(

n t

nt *

e

nt n

e

e )

nt t t l = 0; ( nt nt = 0; t t l += et n t t l ;

nt e [

n e nt];

e ;

nt++)

nt

n( nt nt n t n nt * e nte n e e ; e = new

* e ; t e n e ; nt[n e = t l e ; n l

[])

e

e

;

e e l te

e ]; e ); ( t t l

et ( nt t t l t delete et n 0;

e

n e endl;

e );

Hình 6.12: Tham s c a hàm là con tr .

113

Trong nh ng trư ng h p ta mu n dùng con tr hàm nhưng l i không mu n cho hàm s a i d n t thi t l p quy n c a hàm i v i l l te Hình 6.12, trong ó, t khóa th c e
nt l l te ( n t nt *

truy n lư ng l n d li li u, ta có th dùng t tham s . Xem ví d n t phía trư c tham s
e nt n e

u vào khóa hàm hình

e )

quy nh r ng hàm l l te ph i coi d li u nt mà và không ư c phép s a i. V cách s d ng t khóa 1. không quy
l t * t ;

e tr t i là h ng

n t khi khai báo m t bi n con tr , ta có 4 l a ch n:

nh con tr li u ư c tr
n t t ;

hay d

li u

ư c tr thì

t i là h ng ư c s a i.

2. quy
n t

nh d
l

t i là h ng, con tr

t *

3. quy nh d li u tr t i không ph i là h ng, nhưng bi n con tr thì là h ng
l t * n t t ;

4. quy
n t

nh c
l t *

con tr
n t

l n d
t ;

li u nó tr

t i

u là h ng.

S d ng n t cho nh ng hoàn c nh thích h p là m t ph n c a phong cách l p trình t t. Nó giúp gi m quy n h n c a hàm xu ng t i m c v a , ch ng h n m t hàm ch có nhi m v c d li u và tính toán thì không nên có quy n s a d li u, t ó gi m nguy cơ c a hi u ng ph không mong mu n. ây chính là m t trong các cách thi hành nguyên t c quy n ưu tiên t i thi u (the principle of least privilege), ch c p cho hàm quy n truy nh p d li u v a th c hi n nhi m v c a mình. M t i m quan tr ng khác c n lưu ý là tình tr ng con tr có giá tr null ho c không xác nh do chưa gán b ng a ch c a bi n nào. N u con tr t có giá tr null ho c không xác nh thì vi c truy nh p * t s d n n l i run-time ho c l i lô-gic cho chương trình. Ta c n chú ý kh i t o giá tr c a các bi n con tr và ki m tra giá tr trư c khi truy nh p. Ngoài ra, còn có m t l i khuyên là nên s d ng bi n tham chi u thay cho con tr b t c khi nào có th tránh trư ng h p con tr null ho c có giá tr không xác nh.

114

Bài t p
1. Trình bày s khác bi t, ưu i m, như c i m gi a bi n tĩnh và bi n ng. 2. Vi t m t chương trình v i hai bi n con tr x, y. S d ng hai bi n x,y lưu hai s th c ư c nh p t bàn phím. Tính t ng c a x, và y và hi n k t qu ra màn hình. 3. Tính giá tr c a
nt le ; nt * t = nt * t 2 = le += 2; * t --; * t 2 += ; le , * t le ; t ;

,* t

2 c a o n mã sau:

4. Xác

nh k t qu c a o n mã sau:

nt * 1 = new nt; nt * 2; * 1 = ; 2 = 1; t * 1 = t * 2 = * 2 = 10; t * 1 = t * 2 = 1 = new nt; * 1 = 20; t * 1 = t * 2 =

* 1 * 2 * 1 * 2

endl; endl; endl; endl;

* 1 * 2

endl; endl;

5. Hãy nêu các tình hu ng có th x y ra

i v i o n chương trình sau:

115

nt * 1 = new nt * 2; * 1 = ; 2 = 1; t * 2; delete 1; t * 2; * 2 = 10;

nt;

6. Hãy nêu các tình hu ng có th x y ra
nt * 1 = new nt * 2 = new * 1 = ; 2 = 1; t * 2; nt; nt[10];

i v i o n chương trình sau:

7. Hãy nêu các tình hu ng có th x y ra
nt * = new nt[10]; ( nt = 0; = 10; nt [ ]; [ ] = ; ++)

i v i o n chương trình sau:

8. Nh p t bàn phím vào m t danh sách các s nguyên. Hãy s d ng c u trúc m ng ng lưu gi dãy s nguyên này và tìm s lư ng s nguyên chia h t cho s nguyên u tiên trong dãy. Hi n k t qu ra màn hình. 9. Phân tích s khác bi t, như c i m, ưu i m c a vi c s d ng m ng ng và m ng tĩnh. Nh ng lưu ý khi khai báo, xin c p phát và gi i phóng b nh i v i m ng ng. 10. S d ng c u trúc m ng ng lưu gi m t danh sách tên các sinh viên nh p vào t bàn phím. Hãy s p x p danh sách tên sinh viên tăng d n theo dài c a tên. Hi n ra màn hình danh sách sau khi ã s p x p. 11. M t bàn c có kích thư c m*n ô vuông. Tr ng thái trên m i ô vuông ư c bi u di n b i m t kí t in hoa t ‘A’ n ‘Z’. S d ng m ng ng hai chi u lưu gi tr ng thái c a bàn c nh p t bàn phím. Tìm và hi n ra màn hình: • Các hàng th a mãn i u ki n t t c các ô cùng m t tr ng thái 116

• Các c t th a mãn i u ki n t t c các ô cùng m t tr ng thái • Các ư ng chéo th a mãn i u ki n t t c các ô cùng m t tr ng thái

117

Chương 7. Các ki u d li u tr u tư ng
Các ki u d li u có s n c a m t ngôn ng l p trình, c bi t là các ki u d li u cơ b n, ôi khi không bi u di n d li u c a bài toán c n gi i quy t. Thông thư ng, ta c n g p m t vài thành ph n d li u có liên quan v i nhau l i bi u di n m t ph n t d li u ph c h p m i. Ch ng h n: • D li u c n thi t mô t m t ngày (D te) g m 3 thành ph n: ngày, tháng, năm. Ví d , d li u v ngày Qu c khánh c a Vi t Nam g m 3 thành ph n: 2 (ngày), 9 (tháng), 1945 (năm). • D li u c n thi t thu c ki u nt, mô t St dent bao g m ba thành ph n: t dentN t d thu c ki u D te, n e thu c ki u [ 0].
e

Ki u d li u tr u tư ng là ki u d li u ph c h p ư c c u t o t các thành ph n d li u thu c các ki u d li u khác nhau (có th là ki u có s n ho c ki u d li u mà chúng ta t nh nghĩa). ây là cơ ch cho phép chúng ta t nh nghĩa các ki u d li u m i, ch ng h n như D te và St dent như miêu t trên. i v i m i m t ki u d li u tr u tư ng, ta c n nh nghĩa m t lo t các thao tác x lý d li u cho nó. Ví d , v i ki u d li u D te có th c n n các thao tác x lý d li u như in ra màn hình, và các phép tính i v i d li u ngày tháng như: tính ngày hôm qua, tính ngày mai, tính kho ng cách gi a hai ngày, … Các ngôn ng l p trình b c cao có th chia thành hai lo i: ngôn ng l p trình hư ng th t c, và ngôn ng l p trình hư ng i tư ng. Ki u d li u tr u tư ng hai lo i ngôn ng này có s khác bi t như sau: • i v i các ngôn ng l p trình hư ng th t c, các ki u d li u có c u trúc ch d ng l i vi c óng gói các thành ph n d li u có liên quan l i v i nhau. Ph n x lý d li u ư c t t i các hàm và th t c c l p.

• Các ngôn ng l p trình hư ng i tư ng i xa hơn m t bư c: cho phép óng gói c các hàm x lý d li u vào trong ki u d li u, coi chúng như là m t ph n không th tách r i c a ki u d li u. Trong các ngôn ng này, ki u d li u tr u tư ng ư c g i là các l p i tư ng (class).

7.1.

nh nghĩa ki u d li u tr u tư ng b ng c u trúc struct

Các ngôn ng l p trình b c cao s d ng các c u trúc khá tương t nhau mô t d li u tr u tư ng. M t trong các c u trúc mà C++ cung c p cho công vi c này 118

là c u trúc t t. Ví d , ki u d li u tr u tư ng như sau trong C++:
t t nt nt nt e ; n te; e nd; n te, e

e có th

ư c

nh nghĩa

;

Trong ó, , c u trúc e.

nd là các trư ng hay các thành viên d li u c a

Chú ý r ng các trư ng thu c cùng m t c u trúc ph i có tên khác nhau tuy r ng có th trùng tên v i các trư ng c a m t c u trúc khác. Ngoài ra, ph n nh nghĩa m t c u trúc ph i ư c k t thúc b ng m t d u ch m ph y. Sau khi ã nh nghĩa ki u d li u e, ta có th s d ng nó y như các ki u d li u khác. Ta có th khai báo bi n, m ng, con tr , tham chi u ki u e, ví d :
e d nne e; e nt ent[10]; e *t ePt = d nne e t eRe = d nne

e; e; t c a C++ không tương

Lưu ý: m c dù cùng dùng t khóa t t, nhưng t ương v i t t c a ngôn ng l p trình C.

Trong C++, bi n thu c ki u d li u c u trúc cũng ư c i x như các ki u d li u thông thư ng. Ta có th th c hi n phép gán giá tr c a bi n e này cho bi n e khác, ví d :
nt ent[1] = d nne e;

K t qu là giá tr c a các thành viên d li u c a d nne e ư c sao chép vào các thành viên d li u tương ng c a nt ent[1]. Lưu ý r ng phép gán m c nh c a C++ là phép gán nông, nghĩa là ch có giá tr c a các thành viên ư c sao chép. Do ó n u m t trong các thành viên d li u là con tr t i m t vùng nh thì ch có giá tr c a con tr ư c sao chép ch n i dung c a vùng nh thì không. truy c p các thành viên d li u c a c u trúc, ta có hai toán t d u ch m (.) và mũi tên (- ). Toán t mũi tên (- ) dùng truy nh p các thành viên qua m t

119

con tr n i tư ng. Toán t d u ch m (.) ư c dùng trong các trư ng h p còn l i. Ví d , in thành viên c a bi n d nne e ra màn hình:
t d nne e. ;

ho c
t t eRe . ;

ho c thông qua bi n con tr t ePt như sau
t t ePt ; e, còn t eRe là m t

Trong ó t ePt ang ch a a ch c a bi n d nne tham chi u c a bi n d nne e.

Lưu ý r ng bi u th c (*t ePt ) cho ta chính bi n d nne th c (*t ePt ). , d nne e. , và t ePt v i nhau. Ngoài ra, c p ngo c trong bi u th c (*t ePt ). toán t * không ư c ưu tiên b ng toán t - .

e, do ó ba bi u

tương ương là c n thi t do

khai báo c u trúc d Hình 7.1 minh h a cách khai báo và s d ng t t li u e. Cũng như các ki u d li u khác, ki u d li u có c u trúc cũng có th ư c truy n vào trong các hàm dư i dư i d ng tham s (xem Hình 7.2). Trong ví d ó, ph n mã chương trình có nhi m v in m t giá tr ki u e ra màn hình ư c chuy n thành hàm nt v i tham s là m t tham chi u t i bi n e c n in. Trong ví d này, tham s c a hàm nt ư c quy nh là h ng tham chi u (t khóa n t) hàm này không có quy n s a d li u n m trong bi n ki u e ư c truy n vào. Khi s d ng cơ ch truy n b ng giá tr , ch ng h n nt( e), m t b n sao c a i s ki u Time s ư c truy n vào hàm tương t như i v i tham s thu c các ki u d li u khác. Tuy nhiên, tránh vi c ph i t n chi phí tính toán và b nh cho vi c sao chép các c u trúc mà không ph i c p quy n s a m t cách không c n thi t, ngư i ta thư ng dùng tham s là h ng tham chi u như t i hàm nt( n t e t) trong Hình 7.2 thay vì dùng ki u truy n giá tr . M t l a ch n khác là dùng tham s là con tr , ch ng h n
d nt( e * t e)

Và n u không mu n cho print quy n s a d li u c a bi n Time ư c truy n cho nó, ta quy nh tham s là con tr t i h ng ki u Time, nghĩa là:

120

d

nt (

n t

e *

t

e)

ý r ng c u trúc e trong Hình 7.2 ch bao g m d li u. Ph n chương trình x lý d li u c a e ư c t bên ngoài c u trúc d li u e, t i các hàm có ch c năng thao tác d li u e. ây chính là c i m c a phong cách l p trình hư ng th t c: d li u ư c khai báo m t nơi và x lý d li u m t nơi. C th , trong ví d c a ta, các hàm nt, et e và n tuy n m ngoài và c l pv i e nhưng l i có toàn quy n thao tác d li u n m trong các bi n ki u e, ch ng h n như gán cho m t bi n Time giá tr không h p l 3:100:-1. ây là gi i h n c a các ngôn ng l p trình th t c. Các ngôn ng l p trình hư ng i tư ng i xa hơn và cung c p cơ ch t b o v cho các ki u d li u. Ta có th s a c u trúc e trong Hình 7.2 s d ng cơ ch ó, m c ti p theo s nói v v n này.

121

de ne n l de n n e

t

t t e e

e

nd te t

t.

td;

t

; nt

e t t e de n t n t e nt ; 0-2 (2 nt n te; 0nt e nd; 0end t t e n() e d nne d nne d nne d nne dn dn dn t e dn t;

l

t)

le et et et

new t

e

e e e e

e. = 1 ; e. n te = 0; e. e nd = 0; t. = 0; t. n te = 0; t. e nd = 0; D nne d nne d nne d nne t dn dn dn

e e n te e e e nd e e

d nne d nne d nne dn t dn t dn t

et et et

e e n te e e e nd e e

w ll e eld t e. e. n te e. e nd endl; w ll e t. t. n te t. e nd w t ed t

t

endl;

et

n 0;

ươ
D nne t w ll w ll e e eld w t t 1 ed 0 0 t 0 0 0

Hình 7.1: Ví d v khai báo và s d ng c u trúc d li u struct.

122

de ne n l de n l de n n e

t

t t e n e

e

nd te t

t.

td;

t

;

e t t e de n t n t e nt ; 0-2 (2 nt n te; 0nt e nd; 0end t t e nt t e t t e nt ( n t e t t. een t) t.

l

t)

d

n te

t. e

nd;

d

et et t.

e ( =

n te nd e e t nt ; t.

nd nt

e t n te

t nt

e e e

nd) nd;

n te =

n te; t. e

nd =

nt

n() e d nne et et e(d nne e( dn e dn e 1 0 0 e t; 0 0); 0); eld t ; le t e t e e

t

t D nne w ll nt(d nne e); t endl; t t w ll nt( dn t); et n 0;

e

w t

ed

t

;

Hình 7.2: Ví d v dùng d li u c u trúc làm tham s cho hàm.

123

7.2.

nh nghĩa ki u d li u tr u tư ng b ng c u trúc

a

Như ã nói trên, ta có th óng gói các hàm x lý d li u vào bên trong ki u d li u tr u tư ng. Ví d , các hàm nt và et e trong Hình 7.2 chính là m t ti n ích cho ki u d li u e và nên ư c óng gói vào bên trong ki u d li u này. C u trúc class cho phép ta th c hi n vi c óng gói ó. Khi th c hi n công vi c này, ta b t u bư c t l p trình hư ng th t c sang l p trình hư ng i tư ng. Hình 7.3 minh h a cách khai báo và cài t l p i tư ng e s d ng c u trúc l . M t bi n khi khai báo thu c l p e thì bi n ó ư c g i là m t i tư ng e. So v i t t e trong Hình 7.2, l e khác hai i m: (1) bao g m c các hàm et e và nt; (2) có thêm nhãn quy n truy nh p public. Các hàm et e và nt c a l p i tư ng e trong Hình 7.3 ho t ng gi ng như các hàm tương ng trong Hình 7.2, ch khác ch ta không c n truy n tham s là m t i tư ng e cho các hàm này (chi ti t s ư c gi i thích trong m c sau). V m t ho t ng, cài t c a l e trong Hình 7.3 hoàn toàn tương ương v i t t e trong Hình 7.2. C th , hàm n hay m t hàm nào khác v n có th t o các i tư ng e v i d li u không h p l . Nói cách khác, so v i t t e trong Hình 7.2, l e trong Hình 7.3 m i ch ti n m t bư c là óng gói d li u v i ph n x lý. C i ti n trong Hình 7.4 là bư c ti p theo, th c hi n ư c nhi m v ki m soát d li u. Trong cài t này, các thành viên d li u ư c gi i h n là ch ư c truy nh p t bên trong l e, còn hàm et e m b o d li u ư c gán cho các thành viên d li u ph i có giá tr h p l . Chi ti t s ư c gi i thích trong các m c sau. Lưu ý r ng ta hoàn toàn có th dùng t khóa t t thay vì l trong t t c các trư ng h p, nhưng theo thông l , t t thư ng ư c dùng cho các l p i tư ng ch có d li u còn l dùng cho các l p g m c d li u và hàm, nên ta chuy n sang dùng c u trúc l k t ví d này.

124

de ne l e n l de t e n n e e td; l l l d nt () t et e e de n t

nd te t

t.

n

n te nt ) e nd =

e

nd;

d

e ( nt nt = ; n te = ;

;

; nt

nt ; nt n te; nt e nd; end l n() e d nne et et e(d nne e( dn

0-2 00e

(2 -

l

t)

e

dn

t; 0 0); 0); eld t ;

le

t e t

e

e

e 1 t 0 0 e

t D nne w ll nt(d nne e); t endl; t t w ll nt( dn t); et n 0;

e

w t

ed

t

;

Hình 7.3: óng gói các hàm x lý d li u vào trong class Time.

125

de ne l e n l de t e n n e e td; l l l d t l et e ( nt nt () e e de n t

nd te t

t.

n

n te nt nt );

e

nd;

te nt ; 0-2 nt n te; 0nt e nd; 0l l d ( nt et n ( = 0 ( = 0 ; l end e ( et l et e e ( nt

(2 -

l

t)

nt

nt 2 ) 0)

) ( = 0 0);

nt

nt

)

l d( )) = ; n te = ; n t e;

et n l e; e nd = ;

nt

n() e d nne et et e(d nne e( dn e dn e 1 0 0 e t; 0 0); 0); eld t ; le t e t e e

t

t D nne w ll nt(d nne e); t endl; t t w ll nt( dn t); et n 0;

e

w t

ed

t

;

Hình 7.4: B sung cho class Time kh năng t ki m soát tính h p l c a d li u.

126

7.2.1. Quy n truy nh p Khi khai báo m t l p i tư ng, chúng ta mong mu n phân quy n truy nh p và s d ng d li u cũng như các hàm c a l p ó. T c là, m t s d li u hay hàm ư c truy nh p và s d ng r ng rãi b i t t c các hàm thu c hay không thu c l p i tư ng ó. Bên c nh ó, chúng ta cũng mong mu n m t s d li u hay hàm ư c b o v kh i vi c b truy nh p và s d ng t bên ngoài. T c là, ch các hàm thu c l p ó ư c phép truy nh p và s d ng, các hàm bên ngoài không thu c l p i tư ng ó thì không ư c phép truy nh p và s d ng. Các ngôn ng l p trình hư ng quy n như v y. i tư ng cung c p cho chúng ta cơ ch phân

Nhãn quy n truy nh p (member access specifier) quy nh quy n truy nh p n các thành viên c a l p. Trong s ó có hai lo i thư ng ư c s d ng là: • public: D li u hay hàm thu c lo i công c ng ( ư c khai báo dư i nhãn l ) có th ư c truy nh p và s d ng r ng rãi b i t t c các hàm thu c hay không thu c l p i tư ng ó. Trong Hình 7.4, hàm nt c a l p i tư ng Time là hàm public, và ta có th g i nó thông qua các bi n dn t ( dn t. nt) hay d nne e (d nne e. nt). • private: D li u hay hàm thu c lo i riêng tư ( ư c khai báo dư i nhãn te) ch ư c truy nh p và s d ng b i các hàm thành viên thu c l p ó. Các hàm bên ngoài không thu c l p i tư ng ó thì không ư c phép truy nh p và s d ng. Trong Hình 7.4, các bi n , n te, e nd, và hàm l d thu c di n te và ch có các hàm thành viên nt và et e là có th truy nh p tr c ti p, ch ng h n c/ghi giá tr c a . Trong khi, ó t i hàm n, nghĩa là ngoài l p e, ta không th truy nh p vào các bi n , n te, e nd hay g i hàm l d. Các l nh sau ây không h p l và s gây l i khi biên d ch:
d nne d nne e. e. = 1 ; l d(10 );

Lo i nhãn te này thư ng ư c dùng cho các hàm ti n ích ch c n dùng n bên trong ph m vi l p b i các hàm thành viên khác. Bên c nh hai nhãn ph bi n trên, ta còn các lo i nhãn phân quy n khác như te ted, end (ta s không nói n trong ph m vi khóa h c này).

127

N u không dùng các t khóa trên quy nh quy n truy nh p m t các tư ng minh, thì quy n truy nh p m c nh c a các thành viên c a l là te, còn c a t t là l . Các lo i quy n truy nh p ngoài m c nh ph i ư c quy nh m t cách tư ng minh. Tuy các thành viên private c a m t l p không th ư c truy nh p tr c ti p t ngoài nhưng chúng có th ư c truy nh p gián ti p thông qua các hàm mà l p e, dành riêng cho công vi c này. Ch ng h n v i các i tư ng thu c l p hàm nt cho phép c và hàm et e cho phép ghi d li u private. Ngoài ra, et e còn có m t ch c năng quan tr ng là ki m tra tính h p l c a d li u m i trư c khi gán tr cho các thành viên d li u (nó g i hàm l d). N u c n thi t, ta có th b sung các hàm etH , etH , et n te, et n te, etSe nd, etSe nd truy c p n các thành viên d li u private. Cùng v i et e, chúng ư c g i là các hàm truy c p (accessor) c a l p e, chúng ki m soát d li u ư c ghi vào i tư ng và qu n lý nh d ng c a k t qu c d li u c a i tư ng. 7.2.2. Toán t ph m vi và nh nghĩa các hàm thành viên

Vi c khai báo và nh nghĩa m t hàm có th th c hi n ng th i bên trong m t l p i tư ng (ch ng h n hàm nt trong Hình 7.4). Nhưng ta cũng có th tách ph n khai báo và nh nghĩa m t hàm ra hai nơi khác nhau: ph n khai báo n m bên trong khai báo l p, ph n nh nghĩa n m bên ngoài khai báo l p (ch ng h n hàm et e trong Hình 7.4). N u t nh nghĩa hàm bên ngoài này, ta ph i dùng toán t ph m vi ( ) ch rõ r ng ta ang nh nghĩa m t hàm thành viên c a l p e ch không ph i m t hàm thông thư ng. Toán t ph m vi ch rõ l p i tư ng mà m t thành viên thu c v , cho phép hàm thành viên ó có ư c tính ch t ph m vi như th nh nghĩa c a nó n m bên trong kh i nh nghĩa c a l p i tư ng ch c a nó. Ví d , ph n thân hàm et e ư c xem là n m bên trong ph m vi c a l p Time, do ó, t ây v n có th truy nh p tr c ti p các bi n thành viên lo i private thu c l p e. Lưu ý, cũng như các thành viên d li u, do ã n m bên trong ph m vi c a l p nên các hàm thành viên c a các l p khác nhau có th trùng tên. ý các l i g i hàm et e t hai i tư ng khác nhau d nne e và dn t trong Hình 7.3 hay Hình 7.4, l i g i hàm t i tư ng nào thì hàm ho t ng trên các thành viên d li u c a i tư ng ó. Tuy nhiên, ta không ph i truy n i tư ng vào hàm như trong Hình 7.2 – khi hàm nt là hàm 128

thông thư ng ch không ph i hàm thành viên. Lí do là vì khi g i hàm thành viên t m t i tư ng, i tư ng ó ư c t ng truy n vào hàm như là m t tham s n. 7.2.3. Hàm kh i t o và hàm h y Hình 7.5 là phiên b n m r ng c a cài t l p e trong Hình 7.4 (các ph n ... trong Hình 7.5 có n i dung gi ng như o n tương ng trong Hình 7.4). Ngoài thành viên d li u n te, trong Hình 7.5 còn có thêm các hàm c bi t là e() e( nt nt nt ) và ~ e(). Các hàm có tên e ư c g i là hàm kh i t o (constructor), còn ~ e ư c g i là hàm h y (destructor). Hàm kh i t o là hàm thành viên c bi t có ch c năng kh i t o các thành viên d li u c a i tư ng. Nó ư c g i m t cách t ng khi i tư ng ư c t o, ví d khi m t bi n thu c l p i tư ng, ch ng h n hàm kh i t o e() ư c g i khi l nh khai báo dn t e ư c th c thi. Hàm kh i t o ph i trùng tên v i tên l p, không có giá tr tr v , và không có ki u giá tr tr v . M t l p có th có vài hàm kh i t o ho t ng theo nguyên t c hàm trùng tên. Khi m t i tư ng ư c t o, trình biên d ch s ch n g i hàm nào có danh sách tham s kh p v i các i s ư c cho t i l nh khai báo i tư ng. Trong Hình 7.5, i tư ng d nne e ư c khai báo v i 3 i s , cho nên hàm kh i t o e ( nt nt nt ) s ư c t ng g i khi ch y l nh khao báo bi n d nne e. Trong khi ó, bi n dn t ư c khai báo không có i s , nên hàm kh i t o e() không yêu c u tham s s ư c t ng g i khi ch y l nh khao báo bi n dn t. Hàm h y, ví d ~ e(), th c hi n ch c năng ngư c l i v i hàm kh i t o. Nó ư cg it ng khi m t i tư ng b h y khi th i gian s ng c a nó ã k t thúc ho c khi nó là m t i tư ng ư c c p phát b nh ng và ang ư c gi i phóng kh i b nh b ng l nh delete. Hàm h y ph i trùng tên v i tên l p nhưng có thêm d u ngã (~) t trư c. Hàm h y không ư c có k t qu tr v . i v i m t i tư ng có thành viên d li u là b nh ng ư c c p phát trong th i gian s ng c a i tư ng, hàm h y là nơi thích h p vi t các l nh gi i phóng ph n b nh ư c c p phát ó, mà o n l nh này s ư c th c hi n t i th i i m mà i tư ng b h y. Trong Hình 7.5, hàm h y ~ e ch a m t l nh gi i phóng b nh ng mà thành viên d li u n te tr t i. Công vi c này s ư c th c hi n i v i t ng i tư ng dn t và d nne e khi chương trình ch y h t th i gian s ng c a chúng.

129

C hai lo i hàm h y và hàm t o u không b t bu c. N u không ư c nh nghĩa, trình biên d ch s t t o các hàm t o và h y m c nh có n i dung r ng.

130

n l de n l de n n e l l e () e

t n t e e td;

de lt n t t = n te = e nd = 0; n te = 0; nt n t * n) ); [ t len(n) + 1]; n); de t nt n te ( ) t ... e nd; ) ;

e ( nt nt et e( n te = new t (n te ~ e () l d

delete [] n te; nt

et e ( nt nt () t (n te = 0)

t

n te

te nt nt nt

; 0-2 n te; 0e nd; 0* n te; l l d ( nt

(2 -

l

t)

nt

nt

)

...

; nt n() e d nne e dn t d nne t dn et e (1 t; 0 0 t d te );

D nne w ll e eld t ; e. nt(); endl t w ll e w t t. nt(); n 0;

ed

t

;

Hình 7.5: Hàm t o và hàm h y.

131

7.3. L i ích c a l p trình hư ng

i tư ng

T i Hình 7.4, các nhãn quy n truy nh p l và te quy nh r ng các thành viên d li u ( , n te, e nd) ch ư c phép truy nh p t bên trong l p e (hàm n n m ngoài ph m vi này), còn các hàm et e và nt có th ư c g i t b t c âu trong chương trình. Trong khi ó, t i Hình 7.2 các thành viên d li u ó có th ư c truy nh p t b t c âu (ch ng h n hàm n) do có quy n truy nh p m c nh là public. i u ó có nghĩa là d li u c a t t e có th b c và s a i tùy ý t i b t c o n chương trình nào, trong khi ó, t bên ngoài l e, d li u ch có th ư c c b ng cách g i hàm nt và ư c ghi b ng cách g i hàm thành viên et e – nơi giá tr m i ư c ki m tra tính h p l (g i hàm l d) trư c khi c p nh t. K t qu c a các khác bi t trên là: làm vi c v i d li u ki u d li u e trong Hình 7.2, các o n chương trình bên ngoài ph i bi t chi ti t c u t o c a e. Còn i v i ki u e trong Hình 7.4, các o n mã khác kh c n bi t cách s d ng các hàm nt và et e là - ây chính là giao di n (interface) c a e. Các o n chương trình bên ngoài c u trúc e Hình 7.2 có toàn quy n thao túng d li u c a các i tư ng e, còn c u trúc e Hình 7.4 có th t m b o ư c tính h p l d li u c a mình b ng vi c cho phép truy nh p có ki m soát qua các hàm thành viên c a chính nó. S khác bi t này không có nhi u ý nghĩa i v i m t chương trình nh ch do m t ngư i vi t, tuy nhiên, nó mang l i ích l i quan tr ng trong quá trình phát tri n các ph n m m l n hơn v i nhi u mô un và v i s tham gia c a nhi u l p trình viên, trong ó có vi c tăng tính mô un và gi m l i l p trình. Tóm l i, m i l p i tư ng là khuôn m u hay mô hình cho vi c t o các i tư ng thu c m t ki u nh t nh. L p i tư ng nh nghĩa hai lo i thành viên và m i i tư ng thu c l p ó u có: • Các thành viên d li u mô t các thu c tính c a n te, và e nd c a c u trúc e. i tư ng. Ví d là ,

• Các hàm thành viên, hay hàm, mô t hành vi c a i tư ng (các hành ng mà i tư ng có th th c hi n). Ví d là các hàm nt, et ec ac u trúc e. 132

L p trình hư ng i tư ng cho phép ơn gi n hóa vi c l p trình. Các mô un chương trình có th k t n i v i nhau mà ch c n bi t giao di n c a nhau. Các chi ti t cài t ư c che d u bên trong các mô- un và bên ngoài không c n bi t n. L p trình hư ng i tư ng còn giúp tăng tính tái s d ng và kh năng tích h p các mô un ph n m m, th hi n hai i m: các thành viên c a m t l p có th là i tư ng thu c l p khác, và các l p m i ư c t o t l p cũ b ng quan h th a k (ch này n m ngoài ph m vi khóa h c này).

7.4. Biên d ch riêng r
C++ cho phép chia chương trình thành nhi u ph n lưu t i các t p khác nhau, Các t p này có th ư c biên d ch riêng r , r i liên k t (link) v i nhau trư c khi ch y chương trình. Cách phân chia thông d ng nh t là t nh nghĩa c a m t l p cùng v i nh nghĩa các hàm thành viên c a nó vào các t p riêng ch không t cùng chương trình s d ng class ó. V i cách này, ta có th xây d ng m t thư vi n các l p i tư ng sao cho nhi u chương trình có th dùng chung m t l p. Ta có th biên d ch l p ó úng m t l n và dùng nó trong nhi u chương trình khác nhau, tương t như ta v n dùng các thư vi n quen thu c t e và t n . V i m i l p, ta còn có th vi t nh nghĩa c a nó t i hai t p tách giao di n c a l p (kh i nh nghĩa l p gói trong c p ngo c {}) kh i chi ti t cài t c a l p ( nh nghĩa các hàm thành viên). Khi ó, n u ta thay i cài t c a m t l p mà v n gi nguyên giao di n c a l p ó thì ta ch ph i d ch l i t p ch a cài t c a l p ó. Các t p khác, trong ó có các t p ch a các chương trình s d ng l p ó, không c n ph i s a i gì và không c n biên d ch l i. Hình 7.6, Hình 7.7 và Hình 7.8 là k t qu c a vi c tách chương trình trong Hình 7.5 thành ba t p riêng r . Thông l cho vi c tách t p như sau: • T p header ch a nh nghĩa l p và các nguyên m u hàm thành viên, nghĩa là ph n n m trong c p ngo c {}, ư c t tên có ph n m r ng là .h (t p time.h trong Hình 7.7). T p này ph i ư c include trong t t c các t p s d ng l p Time (các t p time.cpp và main.cpp). • T p mã ngu n ch a nh nghĩa c a các hàm thành viên c a l p, thư ng trùng tên v i tên t p header tương ng (ví d time.cpp) và có ph n m r ng là .cpp hay .cc. 133

Các t p này ư c biên d ch riêng r và liên k t v i t p chương trình chính (main.cpp) trư c khi ch y chương trình. ý mã ngu n c a t p time.h, ta th y ph n n i dung t p ư c gói trong b nh hư ng ti n x lý dư i ây tránh vi c n i dung t p ư c include nhi u l n trong m t chương trình.
nde __ I de ne __ I … end _H__ _H__

o n ti n x lý ó có nghĩa: n u nhãn __ I _H__ chưa ư c nh nghĩa thì nh nghĩa __ I _H__, và o n mã sau ó cho n trư c end m i ư c trình biên d ch xét n. Còn n u như __ I _H__ ã ư c nh nghĩa khi trình biên d ch duy t n dòng nde __ I _H__, thì trình biên d ch s b qua ph n mã ti p theo cho n h t end . Dòng de ne __ I _H__ n m trong t p time.h có tác d ng ánh d u tr ng thái r ng time.h ã ư c include vào chương trình. Cái tên __ I _H__ là ư c t theo thông l tương ng v i tên t p time.h.

Hình 7.6: T p main.cpp ch a chương trình chính.

134

nde de ne l l

I I e

_H _H

e ()

de lt n t t = n te = e nd = 0; n te = 0; nt nt delete [] n te; nt n t * n); de t t nt ) ;

~

e ( nt e () l d

et e ( nt nt ();

te nt nt nt

; n te; e nd; * n te;

0-2 00-

(2 -

l

t)

l ; end

l d ( nt

nt

nt

);

Hình 7.7: T p time.h ch a

nh nghĩa c a l p Time.

135

n l de n l de n l de n e n

t n t e t e. e e td; nt nt n t * n)

e ( nt et e( n te = new t (n te

); [ t len(n) + 1]; n);

l

e ( et

et

e ( nt

nt

nt

)

l d( )) = ; n te = ; n t e;

et n l e; e nd = ;

d

e t (n te

nt() n te ( e nd; ) ;

= 0)

t

n te

l et

e n ( (

l d ( nt = 0 = 0

nt 2 ) 0)

nt

)

(

= 0

0);

Hình 7.8: T p time.cpp ch a cài

t l p Time.

136

Bài t p
1. Tìm hi u và trình bày v l p trình hư ng i tư ng, các ngôn ng l p trình hư ng i tư ng mà b n bi t. S khác bi t, ưu i m, như c i m c a l p trình hư ng i tư ng so v i l p trình hư ng th t c. 2. Trình bày các s gi ng nhau và khác bi t gi a c u trúc d li u struct, và c u trúc d li u class. Cho hai ví d v s d ng c u trúc d li u struct và c u trúc d li u class cho cùng m t ki u d li u. 3. Trình bày s khác bi t gi a d li u và phương th c thu c lo i private và thu c lo i public. Khi nào thì nên khai báo bi n và phương th c thu c lo i private. Cho hai ví d minh h a v cách s d ng d li u và phương th c thu c private và thu c public. 4. Vi t m t c u trúc d li u struct ch a thông tin v ba c nh c a m t tam giác: • Nh p thông tin các c nh c a tam giác t bàn phím • Vi t hàm ki m tra xem ba c nh ó có th a mãn là ba c nh c a tam giác hay không. Hi n k t qu ra màn hình. • Vi t hàm tính di n tích tam giác. Hi n k t qu ra màn hình. 5. Vi t m t class ch a thông tin v ba c nh c a m t tam giác và các phương th c: • Nh p thông tin các c nh c a tam giác t bàn phím. • Ki m tra xem là tam giác thư ng, tam giác cân, tam giác là tam giác. Hi n k t qu ra màn hình. u, hay không

6. Nh p t bàn phím thông tin v m t ngày (m t ngày g m ba thành ph n là ngày, tháng, năm), s d ng c u trúc struct và c u trúc class tính toán và hi n ra màn hình: • Ngày hôm trư c. • Ngày hôm sau. • Còn bao nhiêu ngày n a thì n ngày 1/1/2020.

7. Vi t m t class Student bao g m 3 thông tin cơ b n là name, age, university. L p Student bao g m: 137

• M t hàm kh i t o gán thông tin cho sinh viên: name = “NO NAME”; age = -1; university = “No information”; • Hàm h y v i m c ích hi n ra dòng ch : “Good bye” + name. • Hàm assign nh n và gán thông tin name, age, university cho m t sinh viên. • Hàm print hi n thông tin c a m t sinh viên ra màn hình. 8. Vi t m t class lưu tr thông tin v m t sinh viên (tên tu i, ngày tháng năm sinh, quê quán, l p h c, l c h c t 0,0 n 10,0) và các phương th c tính toán: • Sinh viên ó bao nhiêu tu i tính n ngày hôm nay.

• Phân lo i h c l c c a sinh viên ó (kém, trung bình, gi i, xu t s c). • Quê quán thu c có thu c ba thành thành ph l n (Hà N i, H Chí Minh, à N ng) hay không. 9. Nh p vào t bàn phím m t danh sách sinh viên. Hãy tính và hi n ra màn hình: • Thông tin v t t c các b n tên là Vinh • Thông tin v t t c các b n quê Hà N i

• Cho bi t t ng s b n có h c l c kém (<4), h c l c trung bình (≥4 và <8), h c l c gi i (≥8). 10. S d ng c u trúc d li u class và m ng ng lưu gi danh sách sinh viên m t l p h c. M i sinh viên bao g m các thông tin (tên tu i, ngày tháng năm sinh, quê quán, l p h c, l c h c t 0,0 n 10,0). Vi t chương trình th c hi n các công vi c sau ây: • Nh p thông tin các sinh viên t bàn phím • Hãy ki m tra xem có hai b n sinh viên nào trùng nhau t t c các thông tin. • Hi n k t qu tìm ư c ra màn hình. 138

11. Tìm hi u v tính th a k (inheritance) trong trong l p trình hư ng Hãy vi t m t chương trình g m 2 l p sau:

i tư ng.

12. L p people g m 2 thu c tính (name, age) và phương th c talk ( u vào là m t xâu kí t , hi n xâu kí t ra màn hình). 13. L p student g m 4 thu c tính (name, age, university, major) và hai phương th c talk, study (hi n ra màn hình thông tin v university và major).

139

Chương 8. Vào ra d li u
T t c các chương trình mà ta ã g p trong cu n sách này u l y d li u vào t bàn phím và in ra màn hình. N u ch dùng bàn phím và màn hình là các thi t b vào ra d li u thì chương trình c a ta khó có th x lý ư c kh i lư ng l n d li u, và k t qu ch y chương trình s b m t ngay khi ta óng c a s màn hình c i thi n tình tr ng này, ta có th lưu d li u t i các output ho c t t máy. thi t b lưu tr th c p mà thông d ng nh t thư ng là ĩa c ng. Khi ó d li u t o b i m t chương trình có th ư c lưu l i sau này ư c s d ng b i chính nó ho c các chương trình khác. D li u lưu tr như v y ư c óng gói t i các thi t b lưu tr thành các c u trúc d li u g i là t p (file). Chương này s gi i thi u v cách vi t các chương trình l y d li u vào (t bàn phím ho c t m t t p) và ghi d li u ra (ra màn hình ho c m t t p).

8.1. Khái ni m dòng d li u
Trong m t s ngôn ng l p trình như C++ và Java, d li u vào ra t t p, cũng như t bàn phím và màn hình, u ư c v n hành thông qua các dòng d li u (stream). Ta có th coi dòng d li u là m t kênh ho c m ch d n mà d li u ư c truy n qua ó chuy n t nơi g i n nơi nh n. D li u ư c truy n t chương trình ra ngoài theo m t dòng ra (output stream). ó có th là dòng ra chu n n i và ưa d li u ra màn hình, ho c dòng ra n i v i m t t p và y d li u ra t p ó. Chương trình nh n d li u vào qua m t dòng vào (input stream). Dòng vào có th là dòng vào chu n n i và ưa d li u vào t màn hình, ho c dòng vào n i v i m t t p và nh n d li u vào t t p ó. D li u vào và ra có th là các kí t , s , ho c các byte ch a các ch s nh phân. Trong C++, các dòng vào ra ư c cài t b ng các i tư ng c a các l p dòng t mà ta v n dùng ghi ra màn hình chính là dòng ra vào ra c bi t. Ví d , chu n, còn n là dòng vào chu n n i v i bàn phím. C hai u là các i tư ng dòng d li u (khái ni m " i tư ng" này có liên quan n tính năng hư ng i tư ng c a C++, khi nói v các dòng vào/ra c a C++, ta s ph i c p nhi u n tính năng này).

140

8.2. T p văn b n và t p nh phân
V b n ch t, t t c d li u trong các t p u ư c lưu tr dư i d ng m t chu i các bit nh phân 0 và 1. Tuy nhiên, trong m t s hoàn c nh, ta không coi n i dung c a m t t p là m t chu i 0 và 1 mà coi t p ó là m t chu i các kí t . M t s t p ư c xem như là các chu i kí t và ư c x lý b ng các dòng và hàm cho phép chương trình và h so n th o văn b n c a b n nhìn các chu i nh phân như là các chu i kí t . Chúng ư c g i là các t p văn b n (text file). Nh ng t p không ph i t p văn b n là t p nh phân (binary file). M i lo i t p ư c x lý b i các dòng và hàm riêng. Chương trình C++ c a b n ư c lưu tr trong t p văn b n. Các t p nh và nh c là các t p nh phân. Do t p văn b n là chu i kí t , chúng thư ng trông gi ng nhau t i các máy khác nhau, nên ta có th chép chúng t máy này sang máy khác mà không g p ho c g p ph i r t ít r c r i. N i dung c a các t p nh phân thư ng l y cơ s là các giá tr s , nên vi c sao chép chúng gi a các máy có th g p r c r i do các máy khác nhau có th dùng các quy cách lưu tr s không gi ng nhau. C u trúc c a m t s d ng t p nh phân ã ư c chu n hóa chúng có th ư c s d ng th ng nh t t i các platform khác nhau. Nhi u d ng t p nh và âm thanh thu c di n này. M i kí t trong m t t p văn b n ư c bi u di n b ng 1 ho c 2 byte, tùy theo ó là kí t ASCII hay Unicode. Khi m t chương trình vi t m t giá tr vào m t t p văn b n, các kí t ư c ghi ra t p gi ng h t như khi chúng ư c ghi ra màn hình b ng cách s d ng t. Ví d , hành ng vi t s 1 vào m t t p s d n n k t qu là 1 kí t ư c ghi vào t p, còn v i s 1039582 là 7 kí t ư c ghi vào t p. Các t p nh phân lưu t t c các giá tr thu c m t ki u d li u cơ b n theo cùng m t cách, gi ng như cách d li u ư c lưu trong b nh máy tính. Ví d , m i giá tr nt b t kì, 1 hay 1039582 u chi m m t chu i 4 byte.

8.3. Vào ra t p
C++ cung c p các l p sau • • •
t e t e t e

th c hi n nh p và xu t d li u

i v i t p:

: l p dành cho các dòng ghi d li u ra t p : l p dành cho các dòng : l p dành cho các dòng v a c d li u t t p c v a ghi d li u ra t p.

141

i tư ng thu c các l p này do quan h th a k nên cách s d ng chúng khá gi ng v i n và t – các i tư ng thu c l p t e và t e – mà chúng ta ã dùng. Khác bi t ch là ch ta ph i n i các dòng ó v i các t p.

Hình 8.1: Các thao tác cơ b n v i t p văn b n.

Chương trình trong Hình 8.1 t o m t t p có tên hello.txt và ghi vào ó m t câu "Hell " theo cách mà ta thư ng làm i v i t, ch khác ch thay t b ng i tư ng dòng le ã ư c n i v i m t t p. Sau ây là các bư c thao tác v i t p. 8.3.1. M t p Vi c u tiên là n i i tư ng dòng v i i di t p. K t qu là i tư ng dòng s i v i i tư ng ó s ư c th c hi n t p t m t i tư ng dòng, ta dùng hàm
en ( leN e de);

m t t p, hay nói cách khác là m m t n cho t p, b t kì ho t ng c và ghi i v i t p mà nó i di n. m m t en c a nó:

Trong ó, leN e là m t xâu kí t thu c lo i n t * v i k t thúc là kí t n ll (h ng xâu kí t cũng thu c d ng này), là tên c a t p c n m , và de là tham s không b t bu c và là m t t h p c a các c sau:

142

n t n te

m m m

c ghi d ng t p nh phân

t ví trí b t u c/ghi t i cu i t p. N u c này không ư c t giá tr gì, v trí kh i u s là u t p. m ghi ti p vào cu i t p. C này ch m t p ch ghi. ư c dùng cho dòng

t

n

n ut p ư cm ghi ã có t trư c, n i dung cũ s b xóa ghi n i dung m i.

Các c trên có th ư c k t h p v i nhau b ng toán t bit OR (|). Ví d , n u ta mu n m t p people.dat theo d ng nh phân ghi b sung d li u vào cu i t p, ta dùng l i g i hàm sau:
t e le. le; en ( e le.d t t |

|

n

);

Trong trư ng h p l i g i hàm en không cung c p tham s de, ch ng h n Hình 8.1, ch m c nh cho dòng lo i t e là t, cho dòng lo i t e là n, và cho dòng lo i t e là n | t. Cách th hai n i m t dòng v i m t t p là khai báo tên t p và ki u m t p ngay khi khai báo dòng, hàm en s ư c g i v i các i s tương ng. Ví d :
t e le ( ell .t t t | | n );

ki m tra xem m t t p có ư c m thành công hay không, ta dùng hàm thành viên _ en(), hàm này không yêu c u i s và tr v m t giá tr ki u l b ng t e n u thành công và b ng l e n u x y ra trư ng h p ngư c l i
( le. _ en()) * le n w en nd e d *

8.3.2.

óng t p

Khi ta hoàn thành các công vi c c d li u và ghi k t qu , ta c n óng t p tài nguyên c a nó tr v tr ng thái s n sàng ư c s d ng. Hàm thành viên này 143

không có tham s , công vi c c a nó là x các vùng b nh có liên quan và óng t p:
le. l e();

Sau khi t p ư c óng, ta l i có th dùng dòng le v a óng l i có th ư c m b i các ti n trình khác. Hàm l e cũng ư c g i t ang n i v i m t t p. 8.3.3. X lý t p văn b n ng khi m t

m t p khác, còn t p

i tư ng dòng b h y trong khi nó

Ch dòng t p văn b n ư c thi t l p n u ta không dùng c n khi m t p. Các thao tác xu t và nh p d li u i v i t p văn b n ư c th c hi n tương t như cách ta làm v i t và n.
n l de n l de n nt n e t e t e e td;

n () t e ( e le. le ( _ en()) e .t t );

e e e e

le le le. l

1 Int d t 2 t e t e(); nn t

n t

P te

n S

n ; en e n ;

el e et

t n 0;

en

le ;

ươ 1 Int d t 2 t e t n t P te n S

en e

Hình 8.2: Ghi d li u ra t p văn b n.

144

n l de n l de n l de n nt n e

t e t e t n e td;

n () t e ( le. w le ( _ en()) le.e e .t t );

le (

())

t n l ne; etl ne ( le l ne); t l ne endl; le. l el e et t n 0; e(); nn t en le ;

ươ 1 Int d t 2 t e t n t P te
Hình 8.3:

n S

en e
c d li u t t p văn b n.

Chương trình ví d trong Hình 8.2 ghi hai dòng văn b n vào m t t p. Chương trình trong Hình 8.3 c n i dung t p ó và ghi ra màn hình. ý r ng trong chương trình th hai, ta dùng m t vòng l p c cho n cu i t p. Trong ó, le.e () là hàm tr v giá tr t e khi ch m n cu i t p, giá tr t e mà le.e () tr v ã ư c dùng làm i u ki n k t thúc vòng l p c t p. Ki m tra tr ng thái c a dòng Bên c nh hàm e () có nhi m v ki m tra cu i t p, còn có các hàm thành viên khác dùng ki m tra tr ng thái c a dòng:

145

d()

tr v t e n u m t thao tác c ho c ghi b th t b i. Ví d khi ta c vi t vào m t t p không ư c m ghi ho c khi thi t b lưu tr không còn ch tr ng ghi. tr v t e trong nh ng trư ng h p d() tr v t e và khi có l i nh d ng, ch ng h n như khi ta ang nh c m t s nguyên nhưng l i g p ph i d li u là các ch cái. tr v t e n u ch m n cu i t p

l()

e

() d()

tr v l e n u x y tình hu ng mà m t trong các hàm trên n u ư c g i thì s tr v t e.

t l i c tr ng thái mà m t hàm thành viên nào ó ã ánh d u trư c ó, ta dùng hàm thành viên le . Con tr get và put c a dòng i tư ng dòng vào ra có ít nh t m t con tr n i b . Con tr n i b c a t e hay t e ư c g i là con tr get hay con tr c. Nó ch t i v trí mà thao tác c ti p theo s ư c th c hi n t i ó. Con tr n i b c a t e hay t e ư c g i là con tr put hay con tr ghi. Nó ch t i v trí mà thao tác ghi ti p theo s ư c th c hi n t i ó. Cu i cùng, t e có c con tr get và con tr put. nh v v trí hi n t i c a các con tr get và put, ta có các hàm thành viên tell và tell . Các hàm này tr v m t giá tr thu c ki u _t e, là ki u d li u s nguyên bi u di n v trí hi n t i (tính t u t p) c a con tr get c a dòng (n u g i hàm tell ) ho c con tr put c a dòng (n u g i hàm tell ).
d

M i

tr
d d

t l i v trí c a các con tr get và put, ta có các hàm ee ( et e t n) và ee ( et d e t n) có công d ng di chuy n các con get và put t i v trí et. Trong ó, et ư c tính t u t p n u e t n là e (giá tr m c nh c a d e t n), t cu i t p n u e t n là end, và t v trí hi n t i n u direction là . tính kích thư c c a

Hình 8.4 minh h a cách s d ng các con tr get và put m t t p văn b n.

146

n l de n l de n nt n e

t e t e e td;

n () t e le ( e .t t );

l n e n = le.tell (); le. ee (0 end); l n end = le.tell (); le. l e(); t et n 0; e e (end e n) te . n ;

ươ
e e te .
Hình 8.4: Dùng con tr dòng xác nh kích thư c t p.

8.3.4. X lý t p nh phân c và ghi d li u v i t p nh phân, ta không th dùng các toán t <<, >> và các hàm như etl ne do d li u có nh d ng khác và các kí t tr ng không ư c dùng tách gi a các ph n t d li u. Thay vào ó, ta dùng hai hàm thành viên ư c thi t k riêng cho vi c c và ghi d li u nh phân m t cách tu n t là w te và e d. Cách dùng như sau: size); n t_ t e . e d(memory_block size); Trong ó memory_block thu c lo i "con tr t i char" (char*), nó i di n cho a ch c a m t m ng byte lưu tr các ph n t d li u c ư c ho c các ph n t c n ư c ghi ra dòng. Tham s size là m t giá tr nguyên xác nh s kí t c n c ho c ghi vào m ng ó. Các chương trình trong Hình 8.5, Hình 8.6 và Hình 8.7 minh h a vi c ghi d li u ki u ngư i dùng t nh nghĩa t t p nh phân. c và
t t_ t e .w te(memory_block

147

nde S de ne S n l de n n e de t ne

D N _H D N _H t e e td; _N _ N H 20

t St dent n e [ l t e;

_N

_

N

H + 1];

St dent () n e[0] = 0 ; St dent ( n t * l t); d ntln() t n e t ; St dent St dent ( n t * n l

e = 0;

e

endl;

t

)

nt len t = t len(n); (len t _N _ N t n (n e n len t ); n e[len t ] = 0 ; e = ;

H) len t t e end

=

_N t e t

_ n

N

H;

end
Hình 8.5: Ki u b n ghi ơn gi n Student.

148

n l de n l de n l de n l de n nt n e

t e t e t n t dent. e td;

n () t e ( le. le ( _ en()) 10); ); ); *)( *)( *)( nne) l ) ) e (St dent)); e (St dent)); e (St dent)); e .d t n | t);

St dent St dent St dent le.w le.w le.w

nne( nne l ( l ( te(( te(( te(( e();

le. l el e et t n 0;

nn t

en

le ;

Hình 8.6: Ghi d li u ra t p nh phân.

149

n l de n l de n l de n l de n nt n e

t e t e t n t dent. e td;

n () t e ( w le ( e .d t _ en()) le.e () ) n );

le. le (

St dent t dent; le. e d(( *)( t dent) e ( t dent)); ( le. d()) t dent. ntln(); le. l el e et t n 0;
Hình 8.7: c d li u t t p nh phân.

e(); nn t en le ;

150

Bài t p
1. Nh p vào t bàn phím m t danh sách sinh viên. M i sinh viên g m có các thông tin sau ây: tên tu i, ngày tháng năm sinh, nơi sinh, quê quán, l p, h c l c (t 0 n 9). Hãy ghi thông tin v danh sách sinh viên ó ra t p văn b n student.txt 2. Sau khi th c hi n bài 1, hãy vi t chương trình nh p danh sách sinh viên t t p văn b n student.txt r i hi n th ra màn hình: • Thông tin v t t c các b n tên là Vinh ra t p văn b n vinh.txt • Thông tin t t c các b n quê Hà N i ra t p văn b n hanoi.txt

• T ng s b n có h c l c kém (<4), h c l c trung bình (≥4 và <8), h c l c gi i (≥8) ra t p văn b n hocluc.txt. 3. Sau khi th c hi n bài 2, hãy vi t chương trình cho bi t kích thư c c a t p văn b n student.txt, vinh.txt, hanoi.txt, hocluc.txt. K t qu ghi ra t p văn b n all.txt. 4. Vi t chương trình ki m tra xem t p văn b n student.txt có t n t i hay không? N u t n t i thì hi n ra màn hình các thông tin sau: • S lư ng sinh viên trong t p • S lư ng dòng trong t p • Ghi vào cu i t p văn b n dòng ch “CHECKED” • N u không t n t i, thì hi n ra màn hình dòng ch “NOT EXISTED”. 5. T p văn b n numbers.txt g m nhi u dòng, m i dòng ch a m t danh sách các s nguyên ho c th c. Hai s ng li n nhau cách nhau ít nh t m t d u cách. Hãy vi t chương trình t ng h p các thông tin sau và ghi vào t p văn b n info.txt nh ng thông tin sau: • S lư ng s trong t p • S lư ng các s nguyên • S lư ng các s th c Lưu ý: Test chương trình v i c trư ng h p t p văn b n number.txt ch a m t hay nhi u dòng tr ng cu i t p. 151

6. Trình bày s khác nhau, ưu i m, như c i m gi a t p văn b n và t p văn b n nh phân. Khi nào thì nên dùng t p văn b n nh phân. 7. Cho file văn b n numbers.txt ch a các s nguyên ho c th c. Hãy vi t m t chương trình c các s t file numbers.txt và ghi ra file nh phân numbers.bin các s nguyên n m trong file numbers.txt. 8. Sau khi th c hi n bài 7, hãy vi t m t chương trình c và tính t ng c a t t c các s nguyên file nh phân numbers.bin. Hi n ra màn hình k t qu thu ư c. 9. Sau khi th c hi n bài 7, hãy vi t m t chương trình c các s nguyên file nh phân numbers.bin. Ghi các s n m v trí ch n (s u tiên trong file ư c tính v trí s 0) trong file nh phân numbers.bin vào cu i file numbers.txt. 10. Cho hai file văn b n num1.txt và num2.txt, m i file ch a 1 dãy s ã ư c s p không gi m. S lư ng s trong m i file không quá 109. Hãy vi t chương trình c và ghi ra file văn b n num12.txt các s trong hai file num1.txt và num2.txt th a mãn i u ki n các s trong file num12.txt cũng ư c s p x p không gi m. 11. File văn b n document.txt ch a m t văn b n ti ng anh. Các câu trong văn b n ư c phân cách nhau b i d u ‘.’ ho c ‘!’. Hãy ghi ra file văn b n sentences.txt n i dung c a văn b n document.txt, m i câu ư c vi t trên m t dòng. Ví d : document.txt
t e H we e d t e en e.

sentences.txt
t H we e t d e e en e.

12. File văn b n document.txt ch a m t văn b n có l n c các câu ti ng anh và các câu ti ng Vi t. Các câu trong văn b n ư c phân cách nhau b i d u ‘.’ ho c ‘! ’. Hãy ghi ra file văn b n english.txt (viet.txt) các c u ti ng Anh (Vi t) trong văn b n document.txt.

152

Ph l c A. Phong cách l p trình
Ph n này gi i thi u nh ng i m cơ b n mà l p trình viên nên làm theo chương trình d c, d hi u, và t ư c hi u qu cao. V cơ b n, chương trình c n vi t tư ng minh, ơn gi n, d hi u. Không nên s d ng các c u trúc l nh ph c t p d d n n nh m l n và khó tìm l i. A.1. Chú thích Trư c và trong khi l p trình c n ph i ghi chú thích cho các o n mã trong chương trình. Vi c chú thích giúp chúng ta hi u m t cách rõ ràng và tư ng minh hơn v công vi c chúng ta c n làm. Quan tr ng hơn, chúng s giúp chúng ta d dàng hi u khi chúng ta quay l i ki m tra ho c ti p t c làm vi c v i chương trình. c bi t quan tr ng là giúp chúng ta có th chia s và cùng phát tri n chương trình theo nhóm trong m t th i gian dài. C th là, i v i m i hàm, c bi t là các hàm quan tr ng, chúng ta c n xác nh và ghi chú thích v nh ng v n cơ b n sau: • M c ích c a hàm là gì? • Bi n u vào c a hàm (tham bi n) là gì? u vào n u có?

• Các i u ki n r ng bu c c a các bi n • K t qu tr v c a hàm là gì? • Các r ng bu c c a k t qu tr ra n u có.

• Vi c chú thích s giúp chúng hi u rõ ràng v yêu c u c a hàm. Ví d :

153

t e n t n l l te t e n t tw nte e n e t t n nte e n e etS ( nt nt ) nt et = n ; + ;

tw lle t

d t n 10

A.2. Chia nh chương trình Trong l p trình, ngư i ta thư ng s d ng chi n lư c chia tr , t c là chương trình ư c chia nh ra thành các chương trình con. Vi c chia nh ra thành các chương trình con làm tăng tính mô un c a chương trình và mang l i cho l p trình viên kh năng tái s d ng mã. Ngư i ta khuyên r ng dài m i chương trình con không nên vư t quá m t trang màn hình l p trình viên có th ki m soát t t ho t ng c a chương trình con ó. A.3. Bi n toàn c c Xu hư ng chung là nên h n ch s d ng bi n toàn c c. Khi nhi u hàm cũng s d ng m t bi n toàn c c, vi c thay i giá tr bi n toàn c c c a m t hàm nào ó có th d n n nh ng thay i không mong mu n các hàm khác. Bi n toàn c c s làm cho các hàm trong chương trình không c l p v i nhau. A.4. Cách t tên bi n

Tên bi n nên d c, và g i nh n công d ng c a bi n hay ki u d li u mà bi n s lưu tr . i v i nh ng bi n g m nhi u t , thì các t nên vi t li n nhau và ch cái u tiên c a các t phía sau nên ư c vi t hoa. Ví d
n e St dent n nt

Các bi n h ng nên vi t hoa. N u bi n h ng g m nhi u t , thì các t nên chia cách b ng d u g ch chân. Ví d

154

PI

N

R_I

R

ION

A.5. Cách

t tên hàm

Tên hàm nên d c, và g i nh n m c ích c a hàm. Tên hàm nên b t u b ng m t ng t . i v i nh ng hàm g m nhi u t , thì các t nên vi t li n nhau và ch cái u tiên c a các t phía sau nên ư c vi t hoa. Ví d
etS et n l l teS e

A.6. Bi u th c Các bi u th c c n vi t ơn gi n, g n g n và d hi u. Các bi u th c dài có th tách nh ra s d ng các bi n trung gian. Nên s d ng các c p d u ngo c trách s nh p nh ng và nh m l n v th t th c hi n các phép toán trong bi u th c. Ví d :
= * + * * – d e

Có th vi t thành
= = * ; * ( + 1) – (d e);

Lưu ý: Bi u th c i u ki n cũng nên tuân th theo nguyên t c trên. A.7. Vòng l p Không nên s d ng nhi u các l nh nh y như e , hay nt n e thoát ra kh i vòng l p. V i m i vòng l p, nên xác nh rõ ràng i u ki n vòng l p k t thúc. A.8. Kh i chương trình Các o n chương trình c n ư c trình bày theo thành t ng kh i (s d ng các d u cách). Vi c trình bày theo kh i s giúp chúng ta d dàng hi u ư c c u trúc và th t th c hi n các l nh. Ví d :

155

w

le ( d ne) d S et d ne = n e (); ();

A.9. L p M i l p (class) nên tách ra thành hai t p riêng bi t. T p header (.h) ch a khai báo v l p, còn t p ngu n (.cpp) ch a nh nghĩa v các phương th c c a l p. Vi c tách này s d dàng cho chúng ta trong vi c theo dõi, tìm hi u và phát tri n chương trình. Ví d :
t e. t e.

156

Ph l c B. D ch chương trình C++ b ng GNU C++
B.1. D ch và liên k t Quá trình t o t p th c thi ư c t các t p mã ngu n có hai bư c. Bư c 1: biên d ch các t p mã ngu n thành các t p mã object. Các t p có m r ng .cpp ho c .cc ư c d ch thành các t p có m r ng .o. Bư c 2: liên k t các t p mã object thành m t t p th c thi ư c. Các t p có m r ng .o ư c liên k t v i nhau thành m t t p th c thi ư c ( uôi .exe trong môi trư ng DOS/Windows). N u chương trình ch g m m t t p mã ngu n, ví d count.cpp, ta ch c n ch y l nh g++ -o count.exe count.cpp K t qu là m t t p th c thi ư c có tên count.exe. Ho c ta ch dùng l nh g++ count.cpp K t qu là m t t p th c thi ư c có tên m c Unix/Linux). nh (a.out trong môi trư ng

N u chương trình bao g m nhi u t p mã ngu n, ch ng h n time_test.cpp (ch a hàm main), time.cpp, time.h, ta d ch t ng t p có uôi cpp ho c cc b ng l nh sau g++ -c file.cpp Sau ó liên k t l i b ng l nh g++ time_test.o time.o -o time_test.exe B.2. Ti n ích make c a GNU Ta có biên d ch b ng cách m i l n l i gõ t ng l nh như hư ng d n trên. Tuy nhiên, v i nh ng chương trình l n bao g m nhi u t p mã ngu n, dùng n nhi u thư vi n, vi c gõ t ng l nh b ng tay m i khi c n d ch chương trình không ph i là cách làm hi u qu . Ti n ích e trong b công c GNU cho phép t ng hóa quy trình d ch và liên k t chương trình. e là m t h th ng ư c thi t k xây d ng các chương trình t các cây mã ngu n l n. T ct c a l p trình viên v cây mã ngu n, ti n ích make s g i trình biên d ch và liên k t 157

m t cách hi u qu nh t xây d ng chương trình th c thi ư c. M c này là m t hư ng d n t i gi n cho vi c s d ng ti n ích e. dùng ti n ích e cho m t chương trình, l p trình viên ph i t o m t t p có tên e le n m trong cùng thư m c v i các t p mã ngu n. T p này ch a các l nh hư ng d n make làm gì và làm th nào xây d ng ư c chương trình.
e le g m các b

c t , m i b qu n lý vi c c p nh t m t t p.

M ib ct c am tt p e le g m 3 ph n: ích (target), các quan h ph thu c (dependency), và các ch th (instruction). Công th c như sau:
et le De enden le1 De enden le2 ... De enden len

trong ó, et le là t p c n c p nh t và m i De enden le là m t t p mà et le ph thu c vào nó. Dòng th hai c a b c t là m t l nh d ch et le, l nh này ph i có m t kí t TAB ng trư c và k t thúc b ng kí t xu ng dòng. Ví d , b ct u tiên trong e le c a chúng ta như sau:
t e_te t.e e t e. t e_te t. ++ t e. t e_te t. - t e_te t.e e

trong ó dòng u ch ra r ng time_test.exe ph thu c hai t p time.o và time_test.o, dòng th hai là l nh dùng g++ d ch ra t p time_test.exe. Ti p theo, time.o không có s n ngay khi biên d ch l n b c t cho t p này:
t e. t e. ++ - t t e. e.

u, cho nên ta ph i vi t

Tương t là b
t e_te t. ++ -

c t cho time_test.o
t e. t e. t e_te t.

Do ó, Makefile s có d ng:
t e_te t t e. t e_te t. ++ t e. t e_te t. e. t e. ++ - t t e. e. t e_te t

t

t

e_te t. ++ -

t e. t e. t e_te t.

Và khi ta gõ t d u nh c dòng l nh 158

e

chương trình

es

c

e

le và th c hi n các công vi c sau:

1. th y r ng time_test.exe ph thu c vào time.o, và: a) Ki m tra time.o, th y nó ph thu c time.cc và time.h; b) Xác nh xem time.o ã l i th i chưa (cũ hơn b n m i nh t c a các t p time.cc và time.h) c) n u ã l i th i thì ch y l nh ++ - t e. t o t e.

2. th y r ng time_test.exe cũng ph thu c vào time_test.o, và a) Ki m tra time_test.o, th y nó ph thu c time_test.cc và time.h; b) Xác nh xem time_test.o ã l i th i chưa (chưa ư c d ch t b n m i nh t c a các t p time_test.cc và time.h)
)n u

ã l i th i thì ch y l nh time_test.o

++ -

t

e_te t.

t o

3. th y r ng t t c các t p mà time_test.exe ph thu c nên nó ch y l nh ++ t e. t e_te t. chương trình time_test.exe.

u ã ư c c p nh t, t e_te t t o

159

Ph l c C. X lý xâu b ng thư vi n cstring
C.1. M t s hàm x lý xâu thông d ng
a ( a , a )

Sao chép xâu s vào m ng char d. Tr v
a ( a , a ,

a ch c a xâu d.
z _ )

Chép t i a n kí t t xâu s vào m ng char d. Tr v
a a ( a , a )

a ch m ng d. è lên kí t null

Chép xâu s vào cu i xâu d. Kí t u tiên c a xâu s s cu i xâu d. Tr v a ch c a xâu d.
a a ( a , a , z _ )

Chép t i a n kí t c a xâu s vào cu i xâu d. Kí t è lên kí t null cu i xâu d. Tr v a ch c a xâu d.
( a 1, a 2 )

u tiên c a xâu s s

So sánh xâu s1 và xâu s2. Tr v m t giá tr b ng 0 n u s1 b ng s2, nh hơn 0 (thư ng là -1) n u s1 nh hơn s2, ho c l n hơn 0 (thư ng là 1) n u s1 l n hơn s2 theo th t t i n.
( a 1, a 2, z _ )

Tương t hàm strcmp() nhưng ch so sánh n kí t n kí t u tiên c a xâu s2.
a k( a 1, a 2 )

u tiên c a xâu s1 v i

M t chu i các l i g i hàm strtok có tác d ng tác xâu s1 thành các m nh ("token"), ch ng h n các t trong m t dòng văn b n. Xâu kí t ư c tách d a theo các kí t ch a trong xâu s2. Ví d , n u ta c n tách xâu "Hello, how are you?" thành các t , v i ' ', '?', ',' là các kí t ngăn cách gi a các t , k t qu s là các token "Hello", "how", "are", "you". Tuy nhiên, m i l n g i hàm strtok ch tách ư c m t token và tr v a ch c a token ó. Khi không còn tìm th y token nào, hàm s tr v giá tr NULL. L n g i u tiên trong quá trình phân tách xâu s1 s c n tham s u tiên là s1, các l n g i sau s ti p t c tách s1 n u tham s u tiên là NULL.
z _ ( a )

Tr v

dài c a xâu s – là s kí t 160

ng trư c kí t null.

C.2. Khuy n cáo v vi c s d ng thư vi n cstring M t s hàm trong thư vi n cstring n u s d ng không c n th n có th d n n vi c truy nh p ra ngoài không gian ã ư c khai báo c a m ng ho c tình tr ng xâu kí t không ư c k t thúc úng cách b ng kí t null. i v i nh ng hàm này, l p trình viên ph i s d ng m t cách c n tr ng m b o không gây ra l i d li u. M c này ưa ra m t s khuy n cáo v vi c s d ng các hàm này. Các hàm t và t n sao chép toàn b xâu kí t là tham s th hai vào m ng char ích mà không quan tâm không gian khai báo c a m ng ích có ch ch a hay không. L p trình viên ph i t m b o r ng m ng ích có ch cho xâu ngu n cũng như kí t null k t thúc xâu ó. M t l i khuyên là nên dùng t n thay cho t , vì t n cho phép ki m soát ư c s lư ng kí t s ư c chép vào m ng ích. Tương t , các hàm t t và t n t chép xâu kí t là tham s th hai vào cu i xâu kí t là tham s th nh t mà cũng không quan tâm không gian khai báo c a m ng ích có ch ch a c hai xâu hay không. L p trình viên ph i t m b o r ng m ng ích có ch cho c hai xâu cũng như kí t null k t thúc xâu th hai. t n t cũng ư c khuyên dùng hơn vì nó cho phép ki m soát s lư ng kí t s ư c chép vào m ng ích. Khi s d ng t n , n u s kí t c n chép (tham s th ba) không l n hơn dài c a xâu ngu n (tham s th hai), thì kí t null s không ư c chép vào m ng ích. t n cũng không t chèn thêm m t kí t null vào cu i o n v a chép. Trong trư ng h p này, n u l p trình viên không t g n kí t null ánh d u k t thúc xâu k t qu , xâu này có th tr thành xâu có dài không xác nh v i nguy cơ d n n l i nghiêm tr ng khi ch y chương trình. Tình tr ng tương t cũng x y ra i v i hàm t n t.

161

Tài li u tham kh o
[1]. Bjarne Stroustrup, The C++ Programming Language, 3rd edition, Addison-Wesley, 1997. [2]. [3]. [4]. Deitel & Deitel, C++ How to Program, 5th edition, Prentice Hall, 2005. ISO/IEC JTC1/SC22/WG21. Stable release, ISO/IEC 14882:2003 (2003) Juan Soulie, C++ Language Tutorial, http://www.cplusplus.com.

162