ươ

Bài 1 : C u Trúc C a M t Ch

ng Trình C++

ữ ố ữ ậ ằ ộ m t trong nh ng cách t t nh t đ  b t đ u h c m t ngôn ng  l p trình là b ng ẽ ộ ươ ươ ủ Có l ộ m t ch ậ ng trình. V y đây là ch ấ ể ắ ầ ọ ầ ng trình đ u tiên c a chúng ta :

Hello World!

// my first program in C++ #include int main () { cout << "Hello World!"; return 0; }

// my first program in C++

ườ ọ ữ ế ầ ng trình trên đây là ch ng trình đ u tiên mà h u h t nh ng ng i h c ngh  l p ế ầ t đ u tiên và k t qu  c a nó là vi ể ế ằ ữ ế ả ng trình đ n gi n nh t có th  vi ươ ươ ả ủ ơ ọ ữ ừ ề ậ t câu "Hello, World" lên màn hình. Đây là  ư ấ t b ng C++ nh ng nó đã bao  ng trình C++ có. Hãy cùng xem xét t ng dòng ươ Ch ế ầ trình vi ươ ộ m t trong nh ng ch ầ ơ ả ồ g m nh ng ph n c  b n mà m i ch m t :ộ

ằ ấ ả ấ ấ ổ ạ ộ ắ ầ ưở ươ ế ng nào đ n ho t đ ng c a ch ể ả c các l p trình viên dùng đ  gi ể ượ ươ ườ ả ợ ậ ng trình. Trong tr ng h p này, dòng chú thích là m t gi ươ ượ c coi là chút  Đây là dòng chú thích. T t c  các dòng b t đ u b ng hai d u s  (//) đ ủ ộ ả ng trình.  thích mà chúng không có b t kì m t  nh h ẩ i thích hay bình ph m bên trong mã  Chúng có th  đ ắ ộ ồ ủ i thích ng n  ngu n c a ch ữ ọ g n nh ng gì mà ch ng trình chúng ta làm.

ằ ượ ị ớ c dùng cho preprocessor (ai d ch h  tôi t ượ ự ư c dùng đ  báo hi u cho trình ị ả đây câu l nh ừ  này v i).  ệ t c n ph i ơ ả ộ ả ư ệ iostream. Đây là m t th  vi n vào ra c  b n trong C++ và nó ph i ộ ể ệ ế ầ #include báo cho trình d ch bi ư ệ ươ ẽ ượ ổ ể c dùng trong ch ể ử ng trình. Đây là cách c  đi n đ  s

#include ấ ắ ầ Các câu b t đ u b ng d u (#) đ ả ữ Chúng không ph i là nh ng dòng mã th c hi n nh ng đ ệ ị Ở d ch.  "include" th  vi n  ượ đ ụ d ng th  vi n

c "include" vì nó s  đ ư ệ iostream

ớ ươ ứ ể ng  ng v i ph n b t đ u khai báo hàm t ắ ầ ự ộ ầ ắ ầ ở ữ ủ ị ượ ệ ồ ủ ự ụ ủ gi a c a mã ngu n) mà n i dung c a nó luôn đ ấ main. Hàm main là đi m mà t ng trình C++ b t đ u th c hi n. Nó không ph  thu c vào v  trí c a hàm  ệ c th c hi n  ươ ọ ng ộ ng trình b t đ u. Thêm vào đó, do nguyên nhân nói trên, m i ch ả ồ ạ

int main () Dòng này t ươ ả c  các ch ố ở ầ này (  đ u, cu i hay  ươ ầ đ u tiên khi ch ề trình C++ đ u ph i t n t

ắ ầ ộ i m t hàm main.

ặ ơ ộ ặ ấ ả ở ộ

ặ ơ ộ ặ ể ặ Theo sau main  là m t c p ngo c đ n b i vì nó là m t hàm. Trong C++, t t c  các hàm ố mà sau đó là m t c p ngo c đ n () thì có nghĩa là nó có th  có ho c không có tham s

ắ ứ ế ầ ộ ộ ụ ủ ặ ủ ọ (không b t bu c). N i dung c a hàm main ti p ngay sau ph n khai báo chính th c  ư ượ đ c bao trong các ngo c nh n ( { } ) nh  trong ví d  c a chúng ta

ệ ấ ủ ệ ộ ng trình.

ẩ cout là m t dòng (stream)  ữ ươ ư ệ iostream và nh ng gì mà dòng ử

cout << "Hello World"; Dòng l nh này làm vi c quan tr ng nh t c a ch output chu n trong C++ đ ỗ ệ l nh này làm là g i chu i kí t

ọ ượ ị c đ nh nghĩa trong th  vi n  ự "Hello World" ra màn hình.

ế ằ ấ ẩ ượ ể ế này đ ộ ủ ạ ằ ộ ệ ữ ấ ỗ ệ ậ ắ ổ ế ữ ỗ ự c dùng đ  k t  ộ   ng trình C++ c a b n (m t ấ ấ ấ i ph  bi n nh t c a nh ng l p trình viên C++ là quên m t d u ch m Chú ý r ng dòng này k t thúc b ng d u ch m ph y ( ; ). Kí t ả ươ thúc m t l nh và b t bu c ph i có sau m i l nh trong ch ấ ủ trong nh ng l ph y).ẩ

ế ả ề ợ

return k t thúc hàm main và tr  v  mã đi sau nó, trong tr ộ ườ ươ ủ ng h p này là 0. Đây  i nào trong quá trình ng c a m t ch ườ ộ ỗ ng trình không có m t l ộ ụ ế ộ ế ệ ổ ế ấ ư ạ ẽ ấ ươ ộ

return 0; L nh ệ là m t k t thúc bình th ự th c hi n. Nh  b n s  th y trong các ví d  ti p theo, đây là m t cách ph  bi n nh t  ể ế đ  k t thúc m t ch

ng trình C++.

int main () { cout << " Hello World "; return 0; }

ễ ọ ơ ượ ấ ữ ể ở ng trình đ c c u trúc thành nh ng dòng khác nhau đ  nó tr  nên d  đ c h n  ậ ả ắ ụ ế ả ộ ươ Ch ư nh ng hoàn toàn không ph i b t bu c ph i làm v y. Ví d , thay vì vi t

int main () { cout << " Hello World "; return 0; }

ể ế ta có th  vi t

ộ ế ư ả cũng cho m t k t qu  chính xác nh  nhau.

ượ ệ ằ ẩ ươ   ng ấ c phân cách b ng d u ch m ph y ( ;). Vi c chia ch ể ấ ễ ọ ơ ệ ỉ Trong C++, các dòng l nh đ ằ trình thành các dòng ch  nh m đ  cho nó d  đ c h n mà thôi.

Các chú thích.

// Chú thích theo dòng /* Chú thích theo khối */

ượ ậ ả ầ ủ    trong các ph n c a ử ụ c các l p trình viên s  d ng đ  ghi chú hay mô t ể ươ Các chú thích đ ch ể ng trình. Trong C++ có hai cách đ  chú thích

ấ ổ ế ồ ể ẽ Chú thích theo dòng b t đ u t ằ ắ ầ b t đ u b ng  các chú thích cho ch ố    ố ắ ầ ừ ặ  c p d u x  (//) cho đ n cu i dòng. Chú thích theo kh i ế ề ằ   */ và có th  bao g m nhi u dòng. Chúng ta s  thêm /* và k t thúc b ng  ươ ng trình :

Hello World! I'm a C++ program

/* my second program in C++ with more comments */ #include int main () { cout << "Hello World! "; // says Hello World! cout << "I'm a C++ program"; // says I'm a C++ program return 0; }

ế ấ ươ t các chú thích trong ch ệ ng trình mà không s  d ng các d u //, /* hay */,  ỗ ẽ ể ư ị i. ử ụ ế ạ N u b n vi ẽ ị trình d ch s  coi chúng nh  là các l nh C++ và s  hi n th  các l

ươ

Bài 1 : C u Trúc C a M t Ch

ng Trình C++

ữ ố ữ ậ ằ ộ m t trong nh ng cách t t nh t đ  b t đ u h c m t ngôn ng  l p trình là b ng ẽ ộ ươ ươ ủ Có l ộ m t ch ậ ng trình. V y đây là ch ọ ấ ể ắ ầ ầ ng trình đ u tiên c a chúng ta :

Hello World!

// my first program in C++ #include int main () { cout << "Hello World!"; return 0; }

// my first program in C++

ườ ọ ữ ế ầ ng trình trên đây là ch ng trình đ u tiên mà h u h t nh ng ng i h c ngh  l p ế ầ t đ u tiên và k t qu  c a nó là vi ể ế ằ ữ ế ả ng trình đ n gi n nh t có th  vi ươ ươ ả ủ ơ ọ ữ ừ ề ậ t câu "Hello, World" lên màn hình. Đây là  ư ấ t b ng C++ nh ng nó đã bao  ng trình C++ có. Hãy cùng xem xét t ng dòng ươ Ch ế ầ trình vi ộ ươ m t trong nh ng ch ầ ơ ả ồ g m nh ng ph n c  b n mà m i ch m t :ộ

ằ ấ ổ ạ ộ ắ ầ ưở ấ ả ấ ươ ế ng nào đ n ho t đ ng c a ch ể ả ể ượ ậ ượ c coi là chút  Đây là dòng chú thích. T t c  các dòng b t đ u b ng hai d u s  (//) đ ủ ộ ả ng trình.  thích mà chúng không có b t kì m t  nh h ẩ i thích hay bình ph m bên trong mã  Chúng có th  đ c các l p trình viên dùng đ  gi

ươ ườ ợ ộ ả ắ ng trình. Trong tr ng h p này, dòng chú thích là m t gi i thích ng n ươ ồ ủ ngu n c a ch ữ ọ g n nh ng gì mà ch ng trình chúng ta làm.

ằ ượ ị ớ c dùng cho preprocessor (ai d ch h  tôi t ượ ự ư c dùng đ  báo hi u cho trình ị ả đây câu l nh ừ  này v i).  ệ t c n ph i ộ ơ ả ả ư ệ iostream. Đây là m t th  vi n vào ra c  b n trong C++ và nó ph i ộ ể ệ ế ầ #include báo cho trình d ch bi ư ệ ươ ẽ ượ ổ ể c dùng trong ch ể ử ng trình. Đây là cách c  đi n đ  s

#include ấ ắ ầ Các câu b t đ u b ng d u (#) đ ả ữ Chúng không ph i là nh ng dòng mã th c hi n nh ng đ ệ ị Ở d ch.  "include" th  vi n  ượ đ ụ d ng th  vi n

c "include" vì nó s  đ ư ệ iostream

ớ ươ ứ ể ng  ng v i ph n b t đ u khai báo hàm t ắ ầ ự ộ ầ ắ ầ ở ữ ủ ị ượ ệ ồ ủ ự ụ ủ gi a c a mã ngu n) mà n i dung c a nó luôn đ ấ main. Hàm main là đi m mà t ng trình C++ b t đ u th c hi n. Nó không ph  thu c vào v  trí c a hàm  ệ c th c hi n  ươ ọ ng ộ ng trình b t đ u. Thêm vào đó, do nguyên nhân nói trên, m i ch ả ồ ạ

int main () Dòng này t ươ ả c  các ch ố ở ầ này (  đ u, cu i hay  ươ ầ đ u tiên khi ch ề trình C++ đ u ph i t n t

ắ ầ ộ i m t hàm main.

ộ ặ ặ ơ ấ ả ở ộ

ể ặ ộ ặ ộ ứ ế ắ ầ ộ ặ ơ ủ ọ ụ ủ ặ Theo sau main  là m t c p ngo c đ n b i vì nó là m t hàm. Trong C++, t t c  các hàm ố mà sau đó là m t c p ngo c đ n () thì có nghĩa là nó có th  có ho c không có tham s   (không b t bu c). N i dung c a hàm main ti p ngay sau ph n khai báo chính th c  ư ượ đ c bao trong các ngo c nh n ( { } ) nh  trong ví d  c a chúng ta

ệ ấ ủ ệ ộ ng trình.

ẩ cout là m t dòng (stream)  ữ ươ ư ệ iostream và nh ng gì mà dòng ử

cout << "Hello World"; Dòng l nh này làm vi c quan tr ng nh t c a ch output chu n trong C++ đ ỗ ệ l nh này làm là g i chu i kí t

ọ ượ ị c đ nh nghĩa trong th  vi n  ự "Hello World" ra màn hình.

ế ằ ấ ẩ ượ ể ế này đ ộ ủ ạ ằ ộ ệ ữ ấ ỗ ệ ậ ắ ổ ế ữ ỗ ự c dùng đ  k t  ộ   ng trình C++ c a b n (m t ấ ấ ấ i ph  bi n nh t c a nh ng l p trình viên C++ là quên m t d u ch m Chú ý r ng dòng này k t thúc b ng d u ch m ph y ( ; ). Kí t ả ươ thúc m t l nh và b t bu c ph i có sau m i l nh trong ch ấ ủ trong nh ng l ph y).ẩ

ế ả ề ợ

return k t thúc hàm main và tr  v  mã đi sau nó, trong tr ộ ườ ươ ủ ng h p này là 0. Đây  i nào trong quá trình ng c a m t ch ườ ộ ỗ ng trình không có m t l ộ ụ ế ộ ế ệ ổ ế ấ ư ạ ẽ ấ ươ ộ

return 0; L nh ệ là m t k t thúc bình th ự th c hi n. Nh  b n s  th y trong các ví d  ti p theo, đây là m t cách ph  bi n nh t  ể ế đ  k t thúc m t ch

ng trình C++.

int main () { cout << " Hello World "; return 0;

ễ ọ ơ ượ ấ ữ ể ở ng trình đ c c u trúc thành nh ng dòng khác nhau đ  nó tr  nên d  đ c h n  ậ ả ắ ụ ế ả ộ ươ Ch ư nh ng hoàn toàn không ph i b t bu c ph i làm v y. Ví d , thay vì vi t

}

int main () { cout << " Hello World "; return 0; }

ể ế ta có th  vi t

ộ ế ư ả cũng cho m t k t qu  chính xác nh  nhau.

ượ ệ ẩ ằ ươ   ng ấ c phân cách b ng d u ch m ph y ( ;). Vi c chia ch ể ấ ễ ọ ơ ệ ỉ Trong C++, các dòng l nh đ ằ trình thành các dòng ch  nh m đ  cho nó d  đ c h n mà thôi.

Các chú thích.

// Chú thích theo dòng /* Chú thích theo khối */

ượ ậ ả ầ ủ    trong các ph n c a ử ụ c các l p trình viên s  d ng đ  ghi chú hay mô t ể ươ Các chú thích đ ch ể ng trình. Trong C++ có hai cách đ  chú thích

ấ ổ ế ồ ẽ ể

Chú thích theo dòng b t đ u t ằ ắ ầ b t đ u b ng  các chú thích cho ch ố    ố ắ ầ ừ ặ  c p d u x  (//) cho đ n cu i dòng. Chú thích theo kh i ế ề ằ   */ và có th  bao g m nhi u dòng. Chúng ta s  thêm /* và k t thúc b ng  ươ ng trình :

Hello World! I'm a C++ program

/* my second program in C++ with more comments */ #include int main () { cout << "Hello World! "; // says Hello World! cout << "I'm a C++ program"; // says I'm a C++ program return 0; }

ế ấ ươ t các chú thích trong ch ệ ng trình mà không s  d ng các d u //, /* hay */,  ỗ ẽ ể ư ị i. ử ụ ế ạ N u b n vi ẽ ị trình d ch s  coi chúng nh  là các l nh C++ và s  hi n th  các l

Bài 3 : Các Toán Tử

ế ế ự ồ ạ ủ ế t đ n s  t n t ể ằ ấ ừ ử , đó là các t ữ ư ầ i c a các bi n và các h ng. Trong C++, đ  khoá và các d u không có trong  ể i. Hi u bi ế ớ ầ ơ ả ủ ữ ấ ộ ọ ướ c chúng ta đã bi Qua bài tr ử ụ ớ thao tác v i chúng ta s  d ng các toán t ế ạ ả i có trên h u h t các bàn phím trên th  gi b ng ch  cái nh ng l là r t quan tr ng vì đây là m t trong nh ng thành ph n c  b n c a ngôn ng  C++. ế ề t v  chúng  ữ

ử Toán t gán (

=).

a = 5;

ử ế ể ộ ộ ị Toán t gán dùng đ  gán m t giá tr  nào đó cho m t bi n

ị ế ế

ế a. V  trái b t bu c ph i là m t bi n còn v  ph i  ả ả ể ắ ả ủ ế ế ộ ộ ứ ể ế ằ ấ ộ gán giá tr  nguyên 5 cho bi n  có th  là b t kì h ng, bi n hay k t qu  c a m t bi u th c.

a = b;

ả ạ ấ ượ ệ ừ ự gán luôn đ c th c hi n t trái sang ầ ả C n ph i nh n m nh r ng toán t ượ ph i và không bao gi ằ ờ ả  đ o ng ử c

ằ ứ ị

ự ẽ ế a b ng giá tr  đang ch a trong bi n  giá trị c a ủ b cho a và s  thay đ i c a ế b. Chú ý r ng ằ ổ ủ b sau đó s  không ị ủ gán giá tr  c a bi n  ỉ chúng ta ch  gán  ưở ả ế nh h ng đ n giá tr  c a ị ủ a.

a = 2 + (b = 5);

ộ ủ ượ ử ầ ộ ữ ậ gán trong C++ góp ph n giúp nó v ể ứ ế ệ ả M t thu c tính c a toán t t lên các ngôn ng  l p trình khác là vi c cho phép v  ph i có th  ch a các phép  gán khác. Ví d : ụ

b = 5; a = 2 + b;

ươ ớ ươ t ng đ ng v i

a = b = c = 5;

ợ ệ ể ậ ứ Vì v y bi u th c sau cũng h p l trong C++

ả ị gán giá tr  5 cho c  ba bi n ế a, b và c

Các toán t ử ố ọ +, -, *, /, % ) s  h c (

ử ố ọ ượ ỗ ợ ở ữ Năm toán t c h  tr  b i ngôn ng  là: s  h c đ

+ c ngộ trừ ­ * nhân chia /

ầ ư ấ % l y ph n d  (trong phép chia)

ệ ử ố ấ ề ầ ấ ượ ấ  đ i v i b n là phép l y ph n d , ký hi u  ầ ư ẽ ớ ị ụ ế a = 11 % 3;, bi n ế a s  mang giá tr  2 vì 11 ự ệ ư ứ ự ự c th c hi n trong   này cũng gi ng nh  chúng đ  th c hi n các toán t Th  t ệ ầ ư ẻ ơ ạ ố ớ ạ ọ toán h c. Đi u duy nh t có v  h i l ấ ằ b ng d u ph n trăm (%). Đây chính là phép toán l y ph n d  trong phép chia  ố hai s  nguyên v i nhau. Ví d , n u  = 3*3 +2.

ử Các toán t gán ph c h p ( ứ ợ +=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)

ủ ộ ặ ữ ộ ị ủ ử ế ộ ớ ổ ế ử ỉ  gán ph c h p cho phép ch nh s a giá tr  c a m t bi n v i ử ơ ả ữ ộ M t đ c tính c a ngôn ng  C++ làm cho nó n i ti ng là m t ngôn ng  súc tích  chính là các toán t m t trong nh ng toán t ữ ứ ợ  c  b n sau:

ươ ươ ớ value = value + ng đ ng v i

ươ ươ ng đ ng đ ớ a = a - 5; ng v i  ớ a = a / b; ng v i  ươ ươ ớ price = price * ng đ ng v i

value += increase; t increase; ươ a -= 5; t ươ a /= b; t price *= units + 1; t (units + 1);

ươ ự ấ ả ử và t ng t cho t t c  các toán t khác.

Tăng và gi m.ả

a++; a+=1; a=a+1;

ủ ụ ử ế ệ ệ ệ t ki m khi vi tăng (++) và ế ị ứ ươ ng t mã l nh là toán t ế ươ ươ ộ M t ví d  khác c a vi c ti ặ ả gi m (­­). Chúng tăng ho c gi m giá tr  ch a trong m t bi n đi 1. Chúng t ươ đ ả ậ ớ +=1 ho c ặ -=1. Vì v y, các dòng sau là t ộ ng đ ng v i ng:

ử ấ ủ này là nó có th  là ặ ể ặ ế ++a) ho c sau ( ế ứ ể ể ử ượ ử ụ ề ư ượ ử ụ t quan tr ng v  ý nghĩa: Trong tr ướ ( ả ọ ộ ề ố ++a) giá tr  đ c tăng tr ứ ườ ị ượ ể c s  d ng trong bi u th c; trong tr ợ ng h p ng ượ ử ụ ượ ự ị ị ể ti n tề ố ho c ặ h u tậ ố, có nghĩa là có  ộ M t tính ch t c a toán t ứ ấ ể ế ướ t tr th  vi a++) và m c dù trong hai bi u th c r t  c tên bi n ( ả ả ơ đ n gi n đó nó có cùng ý nghĩa nh ng trong các thao tác khác khi mà k t qu   ủ ệ c a vi c tăng hay gi m đ ộ ệ m t khác bi ư nh  là m t ti n t tr  đã tăng đ ế tr  trong bi n a đ ộ c s  d ng trong m t bi u th c thì chúng có th  có  ợ ườ ng h p toán t c s  d ng  ể c tính và giá  c khi bi u th c đ ượ ạ a++) giá  i ( t : đ ứ ượ c l ệ c tăng sau khi đã tính toán. Hãy chú ý s  khác bi

Ví d  1ụ Ví d  2ụ

B=3; A=++B; // A is 4, B is 4

B=3; A=B++; // A is 3, B is 4

ử Các toán t quan h  ( ệ ==, !=, >, <, >=, <= )

ể ể ể ể ử ụ ứ ớ ử ệ ị ủ ể ứ ế ệ ỉ ể ể ị ỳ ị true ho c ặ false, tu  theo bi u th c k t ả Đ  có th  so sánh hai bi u th c v i nhau chúng ta có th  s  d ng các toán t ẩ quan h . Theo chu n ANSI­C++ thì giá tr  c a thao tác quan h  ch  có th  là giá   ỉ tr  logic ­ chúng ch  có th  có giá tr   qu  là đúng hay sai.

ử ể ử ụ ệ ạ Sau đây là các toán t quan h  b n có th  s  d ng trong C++

< =

== B ngằ != Khác ơ ớ L n h n > ỏ ơ < Nh  h n ơ ớ > = L n h n ho c b ng ỏ ơ Nh  h n ho c  b ngằ

ặ ằ ặ

Ví d :ụ

ẽ ả ẽ ả ị false ị true

ấ ứ ể ể ử ụ ố

a=2, b=3 và c=6 ẽ ả ẽ ả

ị true. ị false

(7 == 5) s  tr  giá tr   (6 >= 6) s  tr  giá tr   ử ụ ấ t nhiên thay vì s  d ng các s , chúng ta có th  s  d ng b t c  bi u  t ứ th c nào. Cho  (a*b >= c) s  tr  giá tr   (b+4 < a*c) s  tr  giá tr

ằ ằ ấ ớ ộ ấ ử ả ộ ằ ế ở ể  gán ( gán giá tr  c a bi u th c bên ph i cho bi n  ể ệ ứ ằ ạ i (==) là m t toán t ứ ấ   ầ C n chú ý r ng = (m t d u b ng) lf hoàn toàn khác v i == (hai d u b ng). D u ị ủ ầ đ u tiên là m t toán t  bên  ấ ử ộ trái) và d u còn l  quan h  nh m so sánh xem hai bi u  ằ th c có b ng nhau hay không.

ề ị ẩ ị ử

ươ ứ ị Trong nhi u trình d ch có tr toán t ươ ứ t ệ ng  ng v i ả ề ng  ng v i ng là 1) thì t ướ ả ề  quan h  không tr  v  giá tr  logic  ớ false còn giá tr  khác 0 (th ữ ư c chu n ANSI­C++ cũng nh  trong ngôn ng  C, các  true ho c ặ false mà tr  v  giá tr   ị int v i ớ 0  ớ true. ườ

ử Các toán t logic (

!, &&, || ).

ử ớ ng đ phía bên

ử ! t ươ ệ ổ ượ c giá tr  c a đ i s  t ỉ ộ ố ố ở  logic NOT, nó ch  có m t đ i s   ị ủ ố ố ừ true sang ặ ươ ng v i toán t Toán t ấ ả ph i và vi c duy nh t mà nó làm là đ i ng ụ ượ ạ i. Ví d : c l false ho c ng

ứ ể ả ề false vì bi u th c bên ph i ả (5 == 5) có giá

!(5 == 5)

!false

tr  v   trịtrue. !(6 <= 4) tr  v   tr  v   !true tr  v ả ề true vì (6 <= 4)có giá tr  ị false. ả ề false. ả ề true.

ứ ể ấ ộ logic

&& và || đ

ử ả ế ấ ượ ử ụ c s  d ng khi tính toán hai bi u th c đ  l y ra m t  ả ươ ứ AND và OR. K t qu ể  logic ớ ng  ng v i các toán t ệ ủ ố ộ Toán t ử ế k t qu  duy nh t. Chúng t ố ố ụ ủ c a chúng ph  thu c vào m i quan h  c a hai đ i s :

Kết quả a && b

Kết quả a || b

ố ố ứ Đ i s  th  hai b ố ố ứ  Đ i s  th nh tấ a

true true true true

false true false true

true false false true

false false false false

Ví d : ụ

( (5 == 5) && (3 > 6) ) tr  v   ( (5 == 5) || (3 > 6)) tr  v

ả ề false ( true && false ). ả ề true ( true || false ).

ử ề ệ Toán t đi u ki n (

? ).

condition ? result1 : result2

ả ề ộ ứ ệ ộ ộ ỳ ị đi u ki n tính toán m t bi u th c và tr  v  m t giá tr  khác tu  thu c  ủ ử ề ứ ể ể ấ ư Toán t vào bi u th c đó là đúng hay sai. C u trúc c a nó nh  sau:

ế ị ả ề ẽ result1, n u không giá tr  tr  v ị ả ề N u ế condition là true thì giá tr  tr  v  s  là  là result2.

7==5 ? 4 : 3

5.

ớ ị ớ

a>b ? a : b

ả ề 3 vì 7 không b ng ằ tr  v   ả ề 4 vì 7 b ng ằ 5+2. 7==5+2 ? 4 : 3 tr  v   ơ 3. ả ề a, vì 5 l n h n  tr  v   5>3 ? a : b ơ a ho c ặ ả ề tr  v  giá tr  l n h n,  b.

ử Các toán t thao tác bit (

&, |, ^, ~, <<, >> ).

ử ế ể ễ ổ ộ thao tác bit thay đ i các bit bi u di n m t bi n, có nghĩa là thay đ i ủ ể ễ ị ổ Các toán t bi u di n nh  phân c a chúng

toán tử asm Mô tả

& AND Logical AND

| OR Logical OR

^ XOR Logical exclusive OR

ả ượ ~ c bit NOT Đ o ng

ị << SHL D ch bit sang trái

ị >> ả SHR D ch bit sang ph i

ử ể ổ ể Các toán t chuy n đ i ki u

ổ ể ể ử ể ạ chuy n đ i ki u cho phép b n chuy n đ i d  li u t ơ ả ứ ầ ể ổ c bi u th c c n chuy n đ i tên ki u d  li u đ ki u này sang ừ ấ ượ c th a  ể ữ ệ ượ   c

int i; float f = 3.14; i = (int) f;

ổ ữ ệ ừ ể Các toán t ệ ể ể ki u khác. Có vài cách đ  làm vi c này trong C++, cách c  b n nh t đ ặ ướ ể ữ ế ừ k  t  ngôn ng  C là đ t tr ặ ơ (), ví d :ụ ặ ọ b c trong c p ngo c đ n

ạ Ở ử ổ ể ể ố ậ ộ ể ở ộ ố ể ữ ư ậ ộ ố ề ượ ị c d ch là ử ể ẻ ấ ắ đây, toán t Đo n mã trên chuy n s  th p phân 3.14 sang m t s  nguyên (3).  ử ụ chuy n đ i ki u là (int). M t cách khác đ  làm đi u này trong C++ là s  d ng  các constructors (  m t s  sách thu t ng  này đ th y nó có v  không xuôi tai l m) thay vì dùng các toán t ấ ử nh ng tôi    c u t ặ ướ  : đ t tr ứ   c bi u th c

i = int ( f );

ữ ể ặ ổ ớ ể  tên ki u m i và bao b c ộ ặ ứ  gi a m t c p ngo c ể ọ bi u th c ể ầ c n chuy n đ i ki u đ n. ơ

ả ề ổ ợ ệ ể ể ể ướ ư ổ  chuy n đ i ki u m i đ c tr ng cho l p trình h trong C++. Thêm vào đó ANSI­C++  ố ậ ớ ặ ng đ i ể C  hai cách chuy n đ i ki u đ u h p l ử ữ còn có nh ng toán t ượ t ng.

sizeof()

a = sizeof (char);

ử ể ữ ệ ể ế ộ ộ ỡ ằ ố ủ ể ộ  này có m t tham s , đó có th  là m t ki u d  li u hay là m t bi n và  Toán t ố ượ ả ề tr  v  kích c  b ng byte c a ki u hay đ i t ng đó.

ị ỡ ị  ể char luôn có kích c  1 byte trên m i h  th ng. Giá tr ậ ố ọ ệ ố ướ ượ c tính tr c khi ẽ ả ề ủ sizeof là m t h ng s  vì v y nó luôn luôn đ ươ ự a s  mang giá tr  1 vì ki u  ộ ằ tr  v  c a  ch ệ   ng trình th c hi n.

ử Các toán t khác

ử ế ố ượ ướ ử ế ụ ể ộ ố ng đ i t ư  khác, nh  các toán t ẽ ượ ng. Chúng s  đ liên quan đ n con  c nói đ n c  th  trong các Trong C++ còn có m t s  các toán t ậ ỏ tr  hay l p trình h ầ ươ ứ ng  ng. ph n t

ứ ự ư

Th  t

ủ   u tiên c a các toán t

a = 5 + 7 % 2

ạ ớ h i toán h ng ế ượ ạ ụ ư ướ ứ Khi vi nào đ ề ạ ể ự ỏ ể t các bi u th c ph c t p v i nhi u toán h ng các b n có th  t ể ượ c tính sau. Ví d  nh  trong bi u th c sau:  c tính tr ứ ạ ứ ạ c, toán h ng nào đ

ể ể có th  có hai cách hi u sau:

ớ ế ớ ế ả 6, ho cặ a = 5 + (7 % 2) v i k t qu  là  ả 0 a = (5 + 7) % 2 v i k t qu  là

ứ ầ ể t ử ỉ ả ờ Câu tr  l ộ ậ l p m t th  t ế i đúng là bi u th c đ u tiên. Vì nguyên nhân nói trên, ngôn ng  C++ đã thi ấ ả ứ ự ư t c ữ ử ố ọ  s  h c mà t , không ch  riêng các toán t ữ   u tiên gi a các toán t

ứ ự ư ệ ượ ệ có th  xu t hi n trong C++. Th  t ủ   u tiên c a chúng đ c li t kê trong ử các toán t ả b ng sau theo th  t ấ ể ứ ự ừ  t ấ    ố  cao xu ng th p.

::

Associativity Toán tử Mô tả

() [ ] -> . sizeof

Th  ứ tự 1 scope Trái

++ --

~

2 Trái

!

tăng/gi mả ượ ả Đ o ng c bit

& *

(type)

NOT 3 Ph iả ử ỏ

+ -

Toán t ể con tr ổ ể Chuy n đ i ki u

* / %

ươ ặ D ng ho c âm

+ -

4 Toán t ử ố ọ  s  h c Trái

<< >>

5 ử ố ọ  s  h c Trái

< <= > >=

Toán t ị 6 D ch bit Trái

== !=

ử ệ 7 Toán t quan h Trái

& ^ |

ử ệ 8 Toán t quan h Trái

&& ||

ử 9 Toán t thao tác bit Trái

?:

ử 10 Toán t logic

ử ề 11 Toán t đi u ki n Trái ệ Ph iả

= += -= *= /= %= >>= <<= &= ^= |=

,

12 Toán t gánử Ph iả

ấ 13 ẩ D u ph y Trái

ợ u tiên thì ướ ứ ự ư  có cùng th  t ấ ị Associativity đ nh nghĩa trong tr ẽ ượ c tính tr cái nào s  đ ườ c, toán t ộ ng h p có m t vài toán t ả ấ ử ở ử  phía xa nh t bên ph i hay là xa nh t bên trái.

ế ứ ạ ứ ộ ạ ề ứ ự ư t m t bi u th c ph c t p mà l ặ ơ ạ ệ thì nên s  d ng các ngo c đ n. Các b n nên ắ ắ i không ch c l m v  th  t   u tiên  ề ự   th c hi n đi u này vì nó ể ử ụ ễ ọ ơ ố ạ ế N u b n mu n vi ử ủ c a các toán t ươ ẽ ng trình d  đ c h n. s  giúp ch

Bài 4 : Các C u Trúc Đi u Khi n

ươ ệ ỉ ng trình th ầ ự ố ế ể ề ạ ộ n i ti p nhau. Trong  i m t đo n mã nào đó. Đ  làm đi u này ạ ử ụ ề ồ ườ ộ ng không ch  bao g m các l nh tu n t M t ch ặ ạ ể ẽ quá trình ch y nó có th  r  nhánh hay l p l ể ấ chúng ta s  d ng các c u trúc đi u khi n.

ớ ề ẽ ệ ấ ế ớ t t ở ấ ượ

ệ ớ kh i l nh ư ể i thi u các c u trúc đi u khi n chúng ta cũng s  ph i bi ố ệ , đó là m t nhóm các l nh đ ộ ở ộ ượ ộ ệ ớ ạ ặ ố ớ Cùng v i vi c gi ệ khái ni m m i:  ph yẩ   (;) nh ng đ ộ ả i m t  ấ c ngăn cách b i d u ch m  ọ { và }. ộ ặ i h n b i m t c p ngo c nh n: c g p trong m t kh i gi

ấ ế ươ ề ể ẽ ử ố ệ ặ ộ ố ộ ỳ ộ ệ ặ ặ ọ ầ H u h t các c u trúc đi u khi n mà chúng ta s  xem xét trong ch ng này cho phép s ơ ụ d ng m t l nh đ n hay m t kh i l nh làm tham s , tu  thu c vào chúng ta có đ t nó  trong c p ngo c nh n hay không.

C u trúc đi u ki n:

ệ if  và else

ố ệ ượ ỉ ượ ự ộ c dùng khi m t l nh hay m t kh i l nh ch  đ ệ c th c hi n khi m t ộ ệ ạ ấ ề ộ ư ủ ả C u trúc này đ ệ đi u ki n nào đó tho  mãn. D ng c a nó nh  sau:

if (condition) statement

ề ệ

true,  ệ

ế ị ỏ ượ ứ ẽ ượ c tính toán. N u đi u ki n đó là  ế ự ự statement b  b  qua (không th c hi n) và  c th c hi n. N u không  ệ ế ệ ệ ế ụ ể ệ ự ươ ề ấ trong đó condition là bi u th c s  đ statement đ ch ng trình ti p t c th c hi n l nh ti p sau c u trúc đi u ki n.

if (x == 100) cout << "x is 100";

ụ ứ ạ ỉ ị Ví d , đo n mã sau đây s  vi ẽ ế x is 100 ch  khi bi n ế   x ch a giá tr  100: t

if (x == 100) { cout << "x is "; cout << x; }

ế ơ ườ ể ỉ ị ệ c th c hi n trong tr ử ụ ng h p  ộ ặ ọ { ượ ố ệ ộ kh i l nh ợ condition là  ự ặ ằ b ng cách s  d ng m t c p ngo c nh n ộ ệ ố N u chúng ta mu n có h n m t l nh đ true chúng ta có th  ch  đ nh m t  }:

ế ề ả c tho  mãn ẽ ả ượ ử ụ ể ỉ ừ ử ụ ư Chúng ta cũng có th  ch  đ nh đi u gì s  x y ra n u đi u ki n không đ ằ b ng cách s u d ng t ệ ượ ớ if nh  sau:  c s  d ng cùng v i ề else. Nó đ ị  khoá

if (condition) statement1 else statement2

if (x == 100) cout << "x is 100"; else cout << "x is not 100";

Ví d : ụ

if (x > 0) cout << "x is positive"; else if (x < 0) cout << "x is negative"; else cout << "x is 0";

ể ượ ụ ị ẽ ề c móc n i đ  ki m tra nhi u giá tr . Ví d  sau đây s ị ứ ấ ể ố ể ể ươ ằ if + else có th  đ C u trúc  ki m tra xem giá tr  ch a trong bi n ng, âm hay b ng không. ế x là d

Các c u trúc l p

ụ ặ ộ ố ầ ấ ị ặ ớ i m t thao tác v i m t s  l n nh t đ nh ho c trong ủ ề ộ ộ ặ ạ M c đích c a các vòng l p là l p l ả ệ khi m t đi u ki n nào đó còn tho  mãn.

Vòng l p ặ while .

ủ ư ạ D ng c a nó nh  sau:

while (expression) statement

ứ ủ ả ơ ỉ ệ ề ặ ạ statement khi đi u ki n i và ch c năng c a nó đ n gi n ch  là l p l ả expression còn tho  mãn.

ẽ ế ụ ươ ế ượ ử ụ Ví d , chúng ta s  vi ộ t m t ch ng trình đ m ng c s  d ng vào l p ặ while:

Enter the starting number > 8 8, 7, 6, 5, 4, 3, 2, 1, FIRE!

// custom countdown using while #include int main () { int n; cout << "Enter the starting number > "; cin >> n; while (n>0) { cout << n << ", "; --n; } cout << "FIRE!"; return 0; }

ạ c yêu c u nh p vào m t s  đ  đ m i s  d ng đ ườ ề ẽ ượ ượ ề ị ầ ậ ượ ườ ử ụ ươ ộ ố ể ế ng trình ch y ng Khi ch ậ ặ while b t đ u n u s  mà ng ắ ầ ế ố ượ i dùng nh p vào  c. Sau đó, khi vòng l p  ng ự ệ n>0 kh i l nh s  đ ệ ộ ố ầ ệ ố ệ ả c th c hi n m t s  l n  tho  mãn đi u ki n đi u ki n  ả ệ (n>0) còn đ ề ừ c tho  mãn. không xác đ nh ch ng nào đi u ki n

ầ ặ ả ả ế ớ ằ ặ ấ ở ươ ộ condition tr  thành sai n u không thì nó s  l p l ẽ ặ ạ ệ ặ ả ể  m t đi m nào đó,  ứ ng th c nào  i mãi mãi. condition tr  ở ể --n; đ  làm cho ộ ố ầ ặ ở ộ Chúng ta c n ph i nh  r ng vòng l p ph i k t thúc  ả ậ ộ vì v y bên trong vòng l p chúng ta ph i cung c p m t ph ế ể đó đ  bu c  ụ Trong ví d  trên vòng l p ph i có l nh  thành sai sau m t s  l n l p.

Vòng l p ặ do­while

ứ ạ D ng th c:

do statement while (condition);

ố ỉ ừ ề ề ứ ệ ượ sau khi statement đ ặ while ch  tr  có m t đi u là đi u ề   ộ c th c hi n, vì ẽ ượ ệ ả ướ ụ i đây s  vi ệ ự condition  ấ ẽ ế t ra b t kì c tính toán  ấ ươ c tho  mãn. Ví d , ch ạ ế ủ Ch c năng c a nó là hoàn toàn gi ng vòng l p  ặ ượ ể ki n đi u khi n vòng l p đ ộ ầ ự v y ậ statement s  đ c th c hi n ít nh t m t l n ngay c  khi  ờ ượ ả ng trình d không bao gi  đ ậ ố ậ ạ ố s  nào mà b n nh p vào cho đ n khi b n nh p s  0.

Enter number (0 to end): 12345 You entered: 12345 Enter number (0 to end): 160277 You entered: 160277 Enter number (0 to end): 0 You entered: 0

// number echoer #include int main () { unsigned long n; do { cout << "Enter number (0 to end): "; cin >> n; cout << "You entered: " << n << "\n"; } while (n != 0); return 0; }

ng đ ượ ụ ặ ề ườ ụ ể ế ặ ẽ ứ ể ế Vòng l p ặ do­while th ề ườ ệ ằ c dùng khi đi u ki n đ  k t thúc vòng l p n m  ặ ệ ậ ố ư i dùng nh p vào là đi u ki n  trong vòng l p, nh  trong ví d  trên, s  mà ng ậ ố ạ ể ế ki m tra đ  k t thúc vòng l p. N u b n không nh p s  0 trong ví d  trên thì  vòng l p s  không bao gi ặ ờ ấ  ch m d t.

Vòng l p ặ for .

ứ ạ D ng th c:

for (initialization; condition; increase) statement;

condition còn

ứ ừ ặ ạ statement ch ng nào ủ ư ư ị và ch c năng chính c a nó là l p l mang giá tr  đúng, nh  trong vòng l p i  ặ while. Nh ng thêm vào đó,

for cung c p ấ

ở ạ ậ ượ c thi ế ế t k ộ ố ầ ớ ộ ộ ị ệ ỗ ch  dành cho l nh kh i t o và l nh tăng. Vì v y vòng l p này đ ặ đ c bi ặ ệ ệ ặ ạ t l p l i m t hành đ ng v i m t s  l n xác đ nh.

ạ ộ ủ ư ứ Cách th c ho t đ ng c a nó nh  sau:

ệ ượ ự ệ ượ ể ể ộ ỉ ộ ầ . ệ ch  m t l n ế ụ ế ế

ự ặ ơ ộ

ệ ể ế ể ề ặ c th c hi n. Nói chung nó đ t m t giá khí ban  1, initialization đ ự ề ế ầ c th c hi n  đ u cho bi n đi u khi n. L nh này đ ặ ượ c ki m tra, n u nó là đúng vòng l p ti p t c còn n u  2, condition đ ế ượ ỏ ặ c b  qua. statement đ không vòng l p k t thúc và  ể ệ ộ ệ ượ c th c hi n. Nó có th  là m t l nh đ n ho c là m t  3, statement đ ọ ặ ộ ặ ượ ố ệ kh i l nh đ c bao trong m t c p ngo c nh n. ự ố increase đ 4, Cu i cùng,  c th c hi n đ  tăng bi n đi u khi n và  ở ạ ướ ặ i b vòng l p quay tr  l ượ c 2.

ụ ế ượ ử ụ ộ Sau đây là m t ví d  đ m ng c s  d ng vòng for.

10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!

// countdown using a for loop #include int main () { for (int n=10; n>0; n--) { cout << n << ", "; } cout << "FIRE!"; return 0; }

ể ượ ỏ ệ ắ ả ộ ầ ả ấ ở ạ ầ Ph n kh i t o và l nh tăng không b t bu c ph i có. Chúng có th  đ c b  qua ậ ẩ ẫ ư nh ng v n ph i có d u ch m ph y ngăn cách gi a các ph n. Vì v y, chúng ta  có th  vi ữ ấ ể ế for (;n<10;) ho c ặ for (;n<10;n++). t

ượ

đây cũng đ

c...

for ( n=0, i=100 ; n!=i ; n++, i­­ ) {   // cái gì  }

ể ấ ườ ụ ầ for, nh  là trong ph n kh i t o. Ví d ử ụ ẩ ng nào trong vòng  ộ ở ạ ề ệ ở ạ ặ ư ề ế ể ằ B ng cách s  d ng d u ph y, chúng ta có th  dùng nhi u l nh trong  ấ b t kì tr chúng ta có th  kh i t o m t lúc nhi u bi n trong vòng l p:

ẽ ự ư ệ ầ ổ ị

ế ặ Vòng l p này s  th c hi n 50 l n n u nh  n và i không b  thay đ i trong thân vòng l p: ặ

Các l nh r  nhánh và l nh nh y

L nh ệ break.

ể ệ ề ả ư ượ ả ặ ệ ể ượ c tho  mãn. L nh này có th  đ ộ ị ữ ệ ế ả ế ẽ ừ ướ ườ ượ ụ ể ộ    ể ế c dùng đ  k t thúc m t ế c khi nó c tr ỏ ử ụ break chúng ta có th  thoát kh i vòng l p ngay c  khi đi u ki n đ  nó S  d ng  ế k t thúc ch a đ ừ ặ vòng l p không xác đ nh hay bu c nó ph i k t thúc gi a ch ng thay vì k t thúc  ộ m t cách bình th ng. Ví d , chúng ta s  d ng vi c đ m ng ế k t thúc:

10, 9, 8, 7, 6, 5, 4, countdown aborted!

// break loop example #include int main () { int n; for (n=10; n>0; n--) { cout << n << ", "; if (n==3) { cout << "countdown aborted!"; break; } } return 0; }

L nh ệ continue.

ạ ủ ầ ỏ ng trình b  qua ph n còn l ẽ ỏ continue làm cho ch ế ầ ặ ặ i c a vòng l p và nh y  ế ươ ụ ượ ầ ố L nh ệ sang l n l p ti p theo. Ví d  chúng ta s  b  qua s  5 trong ph n đ m ng ả c:

10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE!

// break loop example #include int main () { for (int n=10; n>0; n--) { if (n==5) continue; cout << n << ", "; } cout << "FIRE!"; return 0; }

L nh ệ goto.

ệ ươ ể ề ả ạ ng trình.  ng trình C++. Tuy nhiên chúng ta  ượ ụ ệ ộ L nh này cho phép nh y vô đi u ki n t Nói chung b n nên tránh dùng nó trong ch ẫ v n có m t ví d  dùng l nh c: ệ ớ ấ i b t kì đi m nào trong ch ươ ể ế goto đ  đ m ng

10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!

// goto loop example #include int main () { int n=10; loop: ; cout << n << ", "; n--; if (n>0) goto loop; cout << "FIRE!"; return 0; }

Hàm exit.

ủ ế ươ ả ề ộ ạ ị là k t thúc ch ng trình và tr  v  m t mã xác đ nh. D ng ụ ứ ủ ư M c đích c a exit th c c a nó nh  sau

void exit (int exit code);

exit code đ ươ ch bình th

ặ ở ở ả ề ượ ể ượ c dùng b i m t s  h  đi u hành ho c có th  đ ươ ọ ng trình g i. Theo quy c, mã tr  v  0 có nghĩa là ch c dùng b i các ế ng trình k t thúc ườ ỗ ị ộ ố ệ ề ướ ng còn các giá tr  khác 0 có nghĩa là có l i.

ự C u trúc l a ch n:

ọ switch.

ủ ệ ụ ộ ữ ể ủ t m t chút. M c đích c a nó là ki m tra m t vài  ở ầ  đ u bài này khi ệ ng t switch h i đ c bi ứ ươ ộ ớ ệ ộ ự ớ  v i nh ng gì chúng ta làm  ứ ủ ị ằ ế ư ơ ặ Cú pháp c a l nh  giá tr  h ng cho m t bi u th c, t ộ liên k t m t vài l nh ể ạ if và else if v i nhau. D ng th c c a nó nh  sau:

switch (expression) { case constant1: block of instructions 1 break; case constant2: block of instructions 2 break; . . . default: default block of instructions }

ể ể ạ ộ ằ switch tính bi u th c và ki m tra xem nó có b ng

ấ ừ ố ủ ấ ự ả khoá ệ block of instructions 1 cho đ n ế ọ switch. break, sau đó nh y đ n ph n cu i c a c u trúc l a ch n ự ế ể ẽ ể ằ ế

khoá  ở ẽ ự ế ị ể ượ ấ ố ằ ỳ ể ỉ ị

constant2 hay không. N u ế ệ block of instructions 2 cho đ n khi tìm th y t ấ ừ break. ằ ạ   ị ỉ  trên (b n c ch  đ nh  ệ ệ ẽ ự ươ case tu  thích), ch ng trình s  th c hi n các l nh  ả ắ i vì ph n này không b t bu c ph i có.

ế ầ ộ ứ Nó ho t đ ng theo cách sau:  ế constant1 hay không, n u đúng thì nó th c hi n  ầ khi tìm th y t ứ ế Còn n u không, switch s  ki m tra xem bi u th c có b ng  đúng nó s  th c hi n  ứ Cu i cùng, n u giá tr  bi u th c không b ng b t kì h ng nào đ ệ có th  ch  đ nh bao nhiêu câu l nh  ồ ạ trong ph n ầ default: n u nó t n t

ạ ươ ươ Hai đo n mã sau là t ng đ ng:

if (x == 1) { cout << "x is 1"; } else if (x == 2) { cout << "x is 2"; } else { cout << "value of x unknown"; }

switch (x) { case 1: cout << "x is 1"; break; case 2: cout << "x is 2"; break; default: cout << "value of x unknown"; }

ươ ươ ụ ví d  switch if­else   t ng đ ng

ằ ệ trên r ng c u trúc c a l nh ấ ố ệ ở ở ố ệ cu i m i kh i l nh. Đi u này là c n thi ơ ặ switch h i đ c bi ế ế ả ệ

switch (x) { case 1: case 2: case 3: cout << "x is 1, 2 or 3"; break; default: cout << "x is not 1, 2 nor 3"; }

ợ ầ break đ u tiên.  ng h p là không c n ệ ặ ặ ạ ế ể ượ ặ ố ườ ề ộ ầ ng ự ồ ạ ủ ệ   ủ ệ i c a l nh t. Chú ý s  t n t Tôi đã nói  ự ầ ề ỗ t vì n u không thì sau khi th c hi n  break  ố ủ ệ ế ẽ ươ ng trình s  không nh y đ n cu i c a l nh switch mà  block of instructions 1 ch ế ẽ ự ấ ệ ế ố ệ s  th c hi n các kh i l nh ti p theo cho đ n khi nó tìm th y l nh  ỗ ườ ọ { } trong m i tr ề Đi u này khi n cho vi c đ t c p ngo c nh n  ố ệ ự ế ệ c dùng khi b n mu n th c hi n m t kh i l nh cho nhi u tr thi t và có th  đ ụ ợ h p khác nhau, ví d :

ệ ể ượ ứ ớ ể ể ộ c dùng đ  so sánh m t bi u th c v i các h ngằ . ậ ả

case

ế case (n*2):) hay các kho ng ( ỉ switch ch  có th  đ ể ặ ả ằ ợ ệ ằ Chú ý r ng l nh  Vì v y chúng ta không th  đ t các bi n ( (1..3):) vì chúng không ph i là các h ng h p l .

style="BORDER­RIGHT: medium none; PADDING­RIGHT: 0cm; BORDER­TOP:  medium none; PADDING­LEFT: 0cm; PADDING­BOTTOM: 0cm; BORDER­LEFT:  medium none; PADDING­TOP: 0cm; BORDER­BOTTOM: windowtext 3pt solid">

ế ạ ầ ể ả ả ằ ố ị

ế ợ   ề N u b n c n ki m tra các kho ng hay nhi u giá tr  không ph i là h ng s  hãy k t h p các l nh ệ if và else if

Bài 5 : Hàm (I)

ượ ự ộ ượ ọ ừ ộ ủ ể ươ c g i t m t đi m khác c a ch ng ệ c th c hi n khi nó đ ư ạ ố ệ Hàm là m t kh i l nh đ ứ ủ trình. D ng th c c a nó nh  sau:

type name ( argument1, argument2, ...) statement

ả ề ủ c tr  v  c a hàm ọ ủ ề ộ ỳ ể ữ ệ ư ồ

ượ ố ố ế ố ượ ọ ượ ở c g i. Các tham s  khác nhau đ c ngăn cách b i

ộ ệ ố ệ ủ ơ ộ trong đó: ể ữ ệ ượ type là ki u d  li u đ name là tên g i c a hàm. ầ ố c tu  theo nhu c u). M t tham  arguments là các tham s  (có nhi u bao nhiêu cũng đ ế ủ ố s  bao g m tên ki u d  li u sau đó là tên c a tham s  gi ng nh  khi khai báo bi n (ví  d  ụ int x) và đóng vai trò bên trong hàm nh  b t kì bi n nào khác. Chúng dùng đ   ể ư ấ ề ố truy n tham s  cho hàm khi nó đ ẩ . ấ các d u ph y ể statement là thân c a hàm. Nó có th  là m t l nh đ n hay m t kh i l nh.

ướ ề ụ ầ D i đây là ví d  đ u tiên v  hàm:

The result is 8

// function example #include int addition (int a, int b) { int r; r=a+b; return (r); } int main () { int z; z = addition (5,3); cout << "The result is " << z; return 0; }

ể ạ ớ ạ ở c đo n mã này, tr c h t hãy nh  l ề i nh ng đi u đã nói ể ể ượ ươ ắ ầ ệ ừ ướ ế ự ậ ng trình C++ luôn b t đ u th c hi n t hàm ữ ầ  bài đ u  ắ main. Vì v y chúng ta b t Đ  có th  hi u đ ộ tiên: m t ch ầ ừ đ u t  đây.

ắ ầ ằ ế ẽ ấ ự ươ ế ự ữ ấ ệ main b t đ u b ng vi c khai báo bi n z ki u  addition. N u đ  ý chúng ta s  th y s  t i g i t ể int. Ngay sau   gi a c u ng t ủ ờ ọ ủ ể ấ Chúng ta có th  th y hàm  ộ ờ ọ ớ i hàm  đó là m t l ớ trúc c a l ể i g i hàm v i khai báo c a hàm:

ố ọ ề ớ ượ

main chúng ta g i hàm  ố int a và int b đ

addition và  c khai báo cho

ậ Các tham s  có vai trò th t rõ ràng. Bên trong hàm  ươ ứ ị 5 và 3 t truy n hai giá tr :  ng  ng v i hai tham s   hàm addition.

ờ ể ể ượ ể ề c g i t ượ ọ ừ main, quy n đi u khi n đ ố 5 và 3) đ ề ượ c copy sang hai bi n c c b c chuy n sang cho hàm  ế ụ ộ int a và Vào th i đi m hàm đ ị ủ addition. Giá tr  c a c hai tham s  ( int b bên trong hàm.

ệ Dòng l nh sau:

return (r);

ể ề ọ i quy n đi u khi n cho hàm nào đã g i nó ( ị ề  cái đi m mà nó b  ng t b i l

main) và  ắ ở ờ ọ ế addition. Nh ng thêm ư

ả ạ addition, và tr  l ể ở ng trình  ớ ệ ị ượ ả ề ủ i g i đ n  ị ượ ế k t thúc hàm  ươ ế ụ ti p t c ch vào đó, giá tr  đ c dùng v i l nh

return (r) chính là giá tr  đ

c tr  v  c a hàm.\

ị ủ ượ ậ ế z c tính toán. Vì v y bi n ị ượ ị ả ề ở Giá tr  tr  v  b i m t hàm chính là giá tr  c a hàm khi nó đ ả ề ở addition (5, 3), đó là 8.   ẽ s  có có giá tr  đ ộ c tr  v  b i

ạ ộ ủ ạ Ph m vi ho t đ ng c a các bi n ế   [nh c l ắ ạ   i]

ạ ủ ớ ằ ạ ộ ấ ộ ỉ ạ ầ ộ ể ử ụ ự ế ế ố ệ ạ ể ử ụ ươ ụ ế ế ụ ộ ủ ng trình ví d  trên, b n không th  s  d ng tr c ti p các bi n  addition. Thêm vào đó ể ử ụ ự ế ế z tr c ti p bên trong hàm

addition vì nó làm bi n ế

B n c n nh  r ng ph m vi ho t đ ng c a các bi n khai báo trong m t hàm hay b t kì  ố ệ m t kh i l nh nào khác ch  là hàm đó hay kh i l nh đó và không th  s  d ng bên ngoài  ụ chúng. Ví d , trong ch a, b hay r trong hàm main vì chúng là các bi n c c b  c a hàm  ạ b n cũng không th  s  d ng bi n  ụ ộ ủ c c b  c a hàm

main.

ở ấ ể ạ b t kì đâu, ể ử ụ ạ ầ ụ ể ệ ấ ế Tuy nhiên b n có th  khai báo các bi n toàn c c đ  có th  s  d ng chúng  ể bên trong hay bên ngoài b t kì hàm nào. Đ  làm vi c này b n c n khai báo chúng bên

ố ệ ọ ươ ngoài m i hàm hay các kh i l nh, có nghĩa là ngay trong thân ch ng trình.

ề ộ ụ Đây là m t ví d  khác v  hàm:

The first result is 5 The second result is 5 The third result is 2 The fourth result is 6

// function example #include int subtraction (int a, int b) { int r; r=a-b; return (r); } int main () { int x=5, y=3, z; z = subtraction (7,2); cout << "The first result is " << z << '\n'; cout << "The second result is " << subtraction (7,2) << '\n'; cout << "The third result is " << subtraction (x,y) << '\n'; z= 4 + subtraction (x,y); cout << "The fourth result is " << z << '\n'; return 0; }

ủ ứ ạ ợ ng h p này chúng ta t o ra hàm  subtraction. Ch c năng c a hàm này là  ả ố ồ ả ề ế ườ ệ ủ Trong tr ấ l y hi u c a hai tham s  r i tr  v  k t qu .

ế ọ ế ươ ạ ẽ ấ ọ ầ ấ ể ạ

Tuy nhiên, n u phân tích hàm  ng trình đã vài l n g i đ n  main các b n s  th y ch ử ụ hàm subtraction. Tôi đã s  d ng vài cách g i khác nhau đ  các b n th y các cách  ể ượ ọ ộ khác nhau mà m t hàm có th  đ c g i.

ạ ầ ụ ể ộ ộ ờ ọ ế i g i đ n m t hàm có th  hoàn  ọ ệ ẽ ế ở ớ ằ ụ ị ủ ượ ầ ể Đ  có hi u c n k  ví d  này b n c n nh  r ng m t l toàn đ ể ặ c thay th  b i giá tr  c a nó. Ví d  trong l nh g i hàm đ u tiên :

z = subtraction (7,2); cout << "The first result is " << z;

ế ờ ọ ị ủ ằ ẽ N u chúng ta thay l i g i hàm b ng giá tr  c a nó (đó là

5), chúng ta s  có:

z = 5; cout << "The first result is " << z;

ươ ự ư ậ T ng t nh  v y

cout << "The second result is " << subtraction (7,2);

subtraction tr c ti p nh  là m t tham s  c a

ế ả ố ệ ườ ợ ư ự ế ư ộ ư ng h p này chúng ta  ố ủ cout. Chúng ta cũng có th  ể cũng cho k t qu  gi ng nh  hai dòng l nh trên nh ng trong tr ọ g i hàm  t: ế vi

cout << "The second result is " << 5;

ế vì 5 là k t qu  c a ả ủ subtraction (7,2).

ớ ệ Còn v i l nh

cout << "The third result is " << subtraction (x,y);

ấ ở đây là các tham s  c a ố ủ subtraction là các bi n thay vì các ớ ề ườ ị ượ ợ ề . Trong tr ng h p này giá tr  đ ế c truy n cho hàm ẻ ề Đi u m i m  duy nh t  ợ ệ ằ h ng. Đi u này là hoàn toàn h p l subtraction là giá trị c a ủ x and y.

ườ ứ ư ươ ự ế Tr ợ ng h p th  t cũng hoàn toàn t ng t . Thay vì vi t

z = 4 + subtraction (x,y);

ể ế chúng ta có th  vi t:

z = subtraction (x,y) + 4;

ế ằ ẩ ượ ặ ở c đ t ng đ ế ứ ứ ể ố ả ươ cũng hoàn toàn cho k t qu  t ầ cu i bi u th c ch  không c n thi ươ t ph i đ t ngay sau l ấ ấ ng. Chú ý r ng d u ch m ph y đ ờ ọ ả ặ i g i hàm.

ể Các hàm không ki u. Cách s  d ng

ử ụ void.

ộ ờ ủ ế ạ ớ N u b n còn nh  cú pháp c a m t l i khai báo hàm:

type name ( argument1, argument2 ...) statement

ể ằ ộ c hàm ể ữ ệ ẽ ượ ị ắ ầ ế ả ề ư ố ạ ẽ ấ ớ b n s  th y rõ ràng r ng nó b t đ u v i m t tên ki u, đó là ki u d  li u s  đ ả ề ở ệ tr  v  b i l nh

return. Nh ng n u chúng ta không mu n tr  v  giá tr  nào thì sao ?

ằ ưở ượ ỉ ể ể ố ạ ị ộ ộ ng t ả ơ ữ ậ ị ầ ữ ườ ậ ố ươ Hãy t ng r ng chúng ta mu n t o ra m t hàm ch  đ  hi n th  m t thông báo  ả ề ộ ầ lên màn hình. Nó không c n tr  v  m t giá tr  nào c , h n n a cũng không c n nh n  ể ữ ệ void trong ngôn ng  C. Hãy  ế tham s  nào h t. Vì v y ng i ta đã nghĩ ra ki u d  li u  ng trình sau:  xem xét ch

I'm a function!

// void function example #include

void dummyfunction (void) { cout << "I'm a function!"; } int main () { dummyfunction (); return 0; }

ầ ộ ậ ề ố ế ạ ầ

void trong ph n danh sách tham s  có nghĩa là hàm này không nh n m t tham  ể ả ử ụ void đ  làm đi u này. B n

t ph i s  d ng ả ử ụ ặ ơ ỉ ơ ừ T  khoá  ố s  nào. Tuy nhiên trong C++ không c n thi ặ ch  đ n gi n s  d ng c p ngo c đ n ( ) là xong.

ủ ố ộ ậ ờ ọ

dummyfunction

i g i hàm ở B i vì hàm c a chúng ta không có m t tham s  nào, vì v y l ẽ s  là :

dummyfunction ();

style="BORDER­RIGHT: medium none; PADDING­RIGHT: 0in; BORDER­TOP:  medium none; PADDING­LEFT: 0in; PADDING­BOTTOM: 0in; BORDER­LEFT:  medium none; PADDING­TOP: 0in; BORDER­BOTTOM: windowtext 3pt solid">

ấ ể ộ ờ ọ t đ  cho trình d ch hi u đó là m t l ứ i g i hàm ch ế ể ấ ầ ế ị ệ ả ấ ặ ơ Hai d u ngo c đ n là c n thi ộ không ph i là m t tên bi n hay b t kì d u hi u nào khác.

Bài 6 : Hàm (II)

ố ế

ố tham s  giá tr

Truy n tham s  theo

ị hay tham s  bi n.

ế ấ ả ề ố t c  các tham s  truy n cho hàm t, t ề ớ ề c truy n theo ế ề ế ấ ả t c  các hàm chúng ta đã bi ọ giá trị. Đi u này có nghĩa là khi chúng ta g i hàm v i các tham  giá tr  ị ch  không ph i b n thân các bi n.  ả ả ứ ư ả ử ọ Cho đ n nay, trong t ề ượ đ u đ ữ ố s , nh ng gì chúng ta truy n cho hàm là các  ụ Ví d , gi  s  chúng ta g i hàm

addition nh  sau:

int x=5, y=3, z; z = addition ( x , y );

ườ ọ ợ

addition thì các giá tr  ị 5 and 3 đ

c ượ ng h p này khi chúng ta g i hàm  ả ế ả Trong tr ề truy n cho hàm, không ph i là b n thân các bi n.

ạ ả ưở ề ng gì đâu ? Đi u đáng nói ư ậ ị ủ ạ ể ỏ ế ổ  đây là khi các b n thay đ i giá tr  c a các bi n ượ ẫ ổ ề ế a hay b bên trong hàm thì các bi n ế x  ủ giá trị c a chúng  ỉ c truy n cho hàm ch  có ề Đ n đây các b n có th  h i tôi: Nh  v y thì sao, có  nh h ở và y v n không thay đ i vì chúng đâu có đ ượ đ c truy n mà thôi.

ạ ầ ớ ộ ậ ợ ề ế ố ế ố ướ ạ ở ng h p b n c n thao tác v i m t bi n ngoài  ư ở i d ng tham s  bi n nh ộ  bên trong m t hàm. Vì v y  duplicate trong   trong hàm ụ ướ Hãy xét tr ạ ẽ b n s  ph i truy n tham s  d ví d  d ườ ả i đây:

x=2, y=6, z=14

// passing parameters by reference #include void duplicate (int& a, int& b, int& c) { a*=2; b*=2; c*=2; } int main () { int x=1, y=3, z=7; duplicate (x, y, z); cout << "x=" << x << ", y=" << y << ", z=" << z; return 0; }

ầ ạ ề ỗ ượ ể ố ể ủ ủ duplicate theo sau tên ki u c a  ề c truy n theo ố ế ứ ố Đi u đ u tiên làm b n chú ý là trong khai báo c a  ệ ằ ấ ố ề m i tham s  đ u là d u và ( &), đ  báo hi u r ng các tham s  này đ ị ả tham s  bi n ch  không ph i tham s  giá tr .

ố ướ ạ ề ả ề ự i d ng tham s  bi n chúng ta đang truy n b n thân bi n đó và  ố ế ẽ ả ớ ự ế ế ế ố ế Khi truy n tham s  d ệ ự ấ b t kì s  thay đ i nào mà chúng ta th c hi n v i tham s  đó bên trong hàm s   nh  ưở h ổ ng tr c ti p đ n bi n đó.

ế a, b và c v i các tham s  khi g i hàm ( ẽ ả ế ớ ưở ổ ớ a bên trong hàm s   nh h ọ ố ng đ n giá tr  c a

x, y và z)  ị ủ x và hoàn toàn

ụ Trong ví d  trên, chúng ta đã liên k t  và m i s  thay đ i v i  ươ  v i  t ự ớ b và y, c và z. ọ ự ng t

ể ố ạ ả ử ụ ỏ ể ữ ệ ươ ố ế ử ụ d u vàấ Ki u khai báo tham s  theo d ng tham s  bi n s  d ng  Trong ngôn ng  C chúng ta ph i s  d ng con tr  đ  làm vi c t ỉ  (&) ch  có trong C++.  ự ư ế  nh  th . ng t

ề ả ề ộ ơ ộ i d ng tham s  bi n cho phép m t hàm tr  v  nhi u h n m t giá ố ế ả ề ố ề ố ướ ạ ộ ị ướ ủ ề ề ố ầ Truy n tham s  d ụ tr . Ví d , đây là m t hàm tr  v  s  li n tr c và li n sau c a tham s  đ u tiên.

Previous=99, Next=101

// more than one returning value #include void prevnext (int x, int& prev, int& next) { prev = x-1; next = x+1; } int main () { int x=100, y, z; prevnext (x, y, z); cout << "Previous=" << y << ", Next=" << z; return 0; }

ị ặ ị

ố Giá tr  m c đ nh c a tham s .

ị ị ặ ị ể ỉ ị c ề ườ ẽ ượ ể c g i. Đ  làm ữ ị ỏ ng h p chúng b  b  qua khi hàm đ ố ố ộ ượ ọ ế ệ ơ ị ị ủ ụ ị ặ ị ẽ ị ỏ ố ọ ị ộ Khi đ nh nghĩa m t hàm chúng ta có th  ch  đ nh nh ng giá tr  m c đ nh s  đ ố ố ợ truy n cho các đ i s  trong tr ả vi c này đ n gi n ch  c n gán m t giá tr  cho đ i s  khi khai báo hàm. N u giá tr  c a  ẫ ượ tham s  đó v n đ ỉ ầ ỉ c ch  đ nh khi g i hàm thì giá tr  m c đ nh s  b  b  qua. Ví d :

6 5

// default values in functions #include int divide (int a, int b=2) { int r; r=a/b; return (r); } int main () { cout << divide (12); cout << endl; cout << divide (20,4); return 0; }

ấ ươ ờ ọ ng trình, có hai l i g i hàm

divide. Trong l nh ệ

ư Nh ng chúng ta th y trong thân ch ầ đ u tiên:

divide (12)

ố ư

cho tham s  th  hai giá tr  b ng ượ ế ế ầ ộ ỉ chúng ta ch  dùng m t tham s  nh ng hàm  ị ằ ẽ ự divide s  t ph n khai báo hàm đ ố ứ c k t thúc b i ế divide cho phép đ n hai. B i v y hàm  ị ặ ị 2 vì đó là giá tr  m c đ nh c a nó (chú ý  ả ẽ ậ ở int b=2). Vì v y k t qu  s  là ở ậ ủ 6 (12/2).

ứ ệ Trong l nh th  hai:

divide (20,4)

ố ở ậ ị ặ ị ẽ ượ ỏ ả ủ ẽ ế c b  qua. K t qu  c a hàm s  là 5 có hai tham s , b i v y giá tr  m c đ nh s  đ (20/4).

Quá t

i các hàm.

ể ố ủ ề ế ể ặ ế ề ạ ộ ố ố ể ữ ệ ể ữ ệ ủ ậ ố

Hai hàm có th  có cũng tên n u khai báo tham s  c a chúng khác nhau, đi u này có  nghĩa là b n có th  đ t cùng m t tên cho nhi u hàm n u chúng có s  tham s  khác  ả ề nhau hay ki u d  li u c a các tham s  khác nhau (hay th m chí là ki u d  li u tr  v   khác nhau). Ví d :ụ

2 2.5

// overloaded function #include int divide (int a, int b) { return (a/b); } float divide (float a, float b) { return (a/b); } int main () { int x=5,y=2; float n=5.0,m=2.0; cout << divide (x,y); cout << "\n"; cout << divide (n,m); return 0; }

ụ ư ạ ị ị ộ ẽ ế ầ ể float. Trình biên d ch s  bi i dùng ki u  ượ ọ ố ể ằ Trong ví d  này chúng ta đ nh nghĩa hai hàm có cùng tên nh ng m t hàm dùng hai tham   ả ọ ố ể int và hàm còn l t c n ph i g i hàm  s  ki u  nào b ng cách phân tích ki u tham s  khi hàm đ c g i.

ệ ề ề ắ ả ế ả ự ư ạ ộ ể ơ ộ ể ư t c  hai hàm đ u có mã l nh nh  nhau nh ng đi u này không b t  Đ  đ n gi n tôi vi ư ạ bu c. B n có th  xây d ng hai hàm có cùng tên nh ng ho t đ ng hoàn toàn khác nhau.

Các hàm inline.

ộ ị inline có th  đ ế ằ ệ c khao báo c a m t hàm đ  ch  rõ r ng l ng trình đ ằ ờ ọ c d ch. Vi c này t ấ ợ ủ ụ ươ ệ ộ ủ ể ượ ặ ướ ỉ c đ t tr Ch  th   ươ ủ ệ ẽ ượ c thay th  b ng mã l nh c a hàm khi ch s  đ ủ ộ ệ ớ ươ ng v i vi c khai báo m t macro, l đ ẽ ượ ả ố ộ ạ t c đ  ch y ch ể ỉ i g i hàm  ươ ượ ị ng  ắ ớ ỉ ể ệ i ích c a nó ch  th  hi n v i các hàm r t ng n,  ả ọ c c i thi n vì nó không ph i g i m t th  t c con. ng trình s  đ

ủ ư ấ C u trúc c a nó nh  sau:

ế ầ ả ặ ừ ộ i g i hàm cũng nh  b t kì m t hàm nào khác. Không c n thi t ph i đ t t khoá ư ấ ọ ỉ ầ ủ ệ ờ

inline type name ( arguments ... ) { instructions ... } ờ ọ l inline trong l nh g i, ch  c n trong l

i khai báo hàm là đ .

Đ  qui.

n! = n * (n-1) * (n-2) * (n-3) ... * 1

ụ ư ề ớ ộ ố ụ ể ừ ủ ộ ố ươ ế ể ọ ắ ứ ọ ủ ộ ố ể Các hàm có th  g i chính nó. Đi u này có th  có ích v i m t s  tác v  nh  là m t s   ộ ừ ủ ng pháp s p x p hay tính giai th a c a m t s . Ví d , đ  tính giai th a c a m t  ph ư ố s  (n), công th c toán h c c a nó nh  sau:

ẽ ư ệ ộ ể và m t hàm đ  qui đ  tính toán s  nh  sau:

Type a number: 9 !9 = 362880

// factorial calculator #include long factorial (long a) { if (a > 1) return (a * factorial (a-1)); else return (1); } int main () { long l; cout << "Type a number: "; cin >> l; cout << "!" << l << " = " << factorial (l); return 0; }

ư ọ ỉ ẽ ự ệ ế ế ạ ặ ẽ ả ữ ố ể ệ ố Chú ý trong hàm factorial chúng ta có th  l nh g i chính nó nh ng ch  khi tham s   ộ ơ 1, n u không thì hàm s  th c hi n m t vòng l p vô h n vì sau khi đ n 0 nó s ớ l n h n  ế ụ ti p t c nhân c  nh ng s  âm.

long) không cho phép tính giai

ể ữ ệ ộ ạ ế ừ Hàm này có m t h n ch  là ki u d  li u mà nó dùng ( th a quá

12!.

ẫ Khai báo m u cho hàm.

ờ ả ị chúng ta hoàn toàn ph i đ nh nghĩa hàm tr ả ằ ậ ướ ệ ố c l nh g i đ u tiên đ n nó,  ạ ộ

main luôn ph i n m cu i ch c đây nh ng th  đ t hàm

ướ ấ ỗ ế ế ng trình. N u b n  c b t kì m t  i. Nguyên ướ ọ ầ ươ main tr c thông báo l ư ư ử ặ ậ ượ ượ ọ ư ắ ẽ c khi nó đ c g i nh  nh nggx gì chúng ta ấ ả ế Cho đ n gi ườ main, vì v y hàm  ng là trong  mà th ướ ụ ề ộ ử ặ ạ i m t vài ví d  v  hàm tr th  l p l ầ ư ắ ạ ượ ọ ừ c g i t hàm đ  nó, b n g n nh  ch c ch n s  nh n đ ả ượ ộ c khai báo tr nhân là m t hàm ph i đ ụ t c  các ví d . đã làm trng t

ộ ể ươ ả t c  mã ch ấ ế ấ ả ng trình tr t t main hay b t kì m t hàm nào khác. Đó chính là  c dùng trong  ộ ồ ủ ể ư ắ ả ề ủ ể ế ệ ố ướ ư c khi chúng có  Nh ng có m t cách khác đ  tránh ph i vi ẫ ộ ể ượ khai báo m u cho  th  đ hàm. Cách này bao g m vi c khai báo hàm m t cách ng n g n nh ng đ  đ  cho trình  ị d ch có th  bi ọ ể ữ ệ t các tham s  và ki u d  li u tr  v  c a hàm.

ủ ư ạ D ng c a nó nh  sau:

type name ( argument_type1, argument_type2, ...);

ầ ủ ị ạ ừ ầ Đây chính là ph n đ u c a đ nh nghĩa hàm, ngo i tr :

(cid:0) ệ ặ t c  các l nh th ề ặ ượ ọ c b c trong c p ngo c nh n ồ ọ { }. (cid:0) ệ ấ ế ấ (cid:0) ườ ng đ ẩ ;).  ố ỉ ầ ể ủ ủ ệ ế ế ầ t tên t ki u c a chúng là đ . Vi c vi ộ ầ ắ ấ Nó không có b t kì l nh nào cho hàm. Đi u này có nghĩa là nó không bao g m  ớ ấ ả thân hàm v i t ằ Nó k t thúc b ng d u ch m ph y ( ệ t kê các tham s  ch  c n vi Trong ph n li ẫ ố ủ c a các tham s  trong ph n khai báo m u là không b t bu c.

Ví d :ụ

Type a number (0 to exit): 9 Number is odd. Type a number (0 to exit): 6 Number is even. Type a number (0 to exit): 1030 Number is even. Type a number (0 to exit): 0 Number is even.

// prototyping #include void odd (int a); void even (int a); int main () { int i; do { cout << "Type a number: (0 to exit)"; cin >> i; odd (i); } while (i!=0); return 0;

} void odd (int a) { if ((a%2)!=0) cout << "Number is odd.\n"; else even (a); } void even (int a) { if ((a%2)==0) cout << "Number is even.\n"; else odd (a); }

ụ ụ ề ự ệ ắ ằ ả ả ậ ượ ế c k t qu  nh  trên ch  v i m t n a s  dòng l nh. Tuy nhiên nó ắ ệ ư ế ấ ượ ơ ữ ộ ử ố c vi c khai báo m u các hàm là nh  th  nào. H n n a,  ắ ỉ ớ ẫ ộ ụ ệ ấ ộ ộ Ví d  này rõ ràng không ph i là m t ví d  v  s  hi u qu . Tôi ch c ch n r ng các  ả ư ể ạ b n có th  nh n đ ệ giúp cho chúng ta th y đ ẫ trong ví d  này vi c khai báo m u ít nh t m t hàm là b t bu c.

ẫ ủ ầ ấ Đ u tiên chúng ta th y khai báo m u c a hai hàm

odd và even:

void odd (int a); void even (int a);

c khi chúng đ c đ nh nghĩa hoàn ỉ ạ ầ ấ ộ ướ i sao ch t gi ượ ị ng trình này l i c n ít nh t m t ả ượ ộ ờ ọ ế even và trong even có m tộ ượ ậ ướ ỗ ắ ắ ươ i g i đ n  c khai báo tr c thì l i ch c ch n ể ượ ử ụ c s  d ng tr cho phép hai hàm này có th  đ ạ ả ặ ệ i thích t ch nh. Tuy nhiên lý do đ c bi ẫ c khi báo m u là trong  hàm ph i đ odd có m t l ờ ọ ế odd. Vì v y n u không có hàm nào đ ế l i g i đ n  ẽ ẩ s  x y ra.

style="BORDER­RIGHT: medium none; PADDING­RIGHT: 0in; BORDER­TOP:  medium none; PADDING­LEFT: 0in; PADDING­BOTTOM: 0in; BORDER­LEFT:  medium none; PADDING­TOP: 0in; BORDER­BOTTOM: windowtext 3pt solid">

ề ậ ượ ằ ề ấ ờ ủ ấ ả ế t c  các hàm t ư ế ả ọ ượ ế ậ ờ ấ t cấ ả các hàm nên đ ệ t R t nhi u l p trình viên kinh nghi m khuyên r ng  ườ ẫ ợ ng h p có nhi u hàm ho c chúng m u. Đó cũng là l i khuyên c a tôi, nh t là trong tr ỗ ộ ệ ấ r t dài, khi đó vi c khai báo t c th i gian.  ph i g i các hàm nh  th  nào, vì v y ti c khai báo  ặ ở  cùng m t ch  cho phép chúng ta bi ệ t ki m đ

Bài 7 : M ngả

ả ế có cùng ki u đ ể c đ t liên ti p trong b  nh  và có th ộ ấ ế ừ ầ ử ầ ử ằ ể ượ ặ ộ ộ ủ ớ ả M ng là m t dãy các ph n t truy xu t đ n t ng ph n t ỉ ố  b ng cách thêm m t ch  s  vào sau tên c a m ng.

ề ể ư ụ ầ ứ ả ị ả ị ể int mà không c n ph i  ể int có tên là ể Đi u này có nghĩa là, ví d , chúng ta có th  l u 5 giá tr  ki u  ụ ộ ế khai báo 5 bi n khác nhau.Ví d , m t m ng ch a 5 giá tr  nguyên ki u  ư ễ ể ượ billy có th  đ c bi u di n nh  sau:

ộ ễ ả ợ ị ườ ầ ử ầ ủ ể ể int. Chúng đ ầ ử ủ c a m ng, trong tr ố ừ 0 đ n ế 4 vì ph n t ng h p này là   đ u tiên c a ấ ể ộ ả ố ỗ trong đó m i m t ô tr ng bi u di n m t ph n t các giá tr  nguyên ki u  m ng luôn là ộ ượ c đánh s  t ủ 0 b t k  đ  dài c a nó là bao nhiêu.

type name [elements];

ả ượ ế ả ướ ể ử ụ c khi có th  s  d ng. ư ấ ộ ể ả ộ ộ c khai báo tr Nh  b t kì bi n nào khác, m t m ng ph i đ ư M t khai báo đi n hình cho m t m ng trong C++ nh  sau:

elements ch  đ nh m ng đó s  ch a bao nhiêu ph n t

ợ ệ ế ộ và ợ ệ int, float...), name là m t tên bi n h p l ể ữ ệ ị ( ẽ ứ ầ ử ườ ả ỉ ộ trong đó type là m t ki u d  li u h p l tr ng

int billy [5];

ư ở ỉ ầ ả ộ ơ billy nh  đã trình bày trên chúng ta ch  c n m t dòng đ n gi n ư ể ậ Vì v y, đ  khai báo  nh  sau:

ườ ị ằ ả ộ ng ả elements  bên trong c p ngo c  ố ả ả ị ị ỡ ớ ể ấ ộ ầ ướ ệ ả ộ ể ượ ị ự ệ ặ ặ [] ph i là m t giá tr  h ng khi khai báo  Chú ý: Tr ộ ớ m t m ng, vì m ng là m t kh i nh  tĩnh có kích c  xác đ nh và trình biên d ch ph i có  ả kh  năng xác đ nh xem c n bao nhiêu b  nh  đ  c p phát cho m ng tr c khi các l nh  có th  đ c th c hi n.

ở ạ

Kh i t o m t m ng.

ớ ầ ả ị ươ ặ ị ộ ng (trong m t hàm), theo m c đ nh ạ ộ ộ ủ ẽ ậ ế ị c kh i t o, vì v y n i dung c a nó là không xác đ nh cho đ n khi ở ạ ị ư ộ Khi khai báo m t m ng v i t m ho t đ ng đ a ph ượ nó s  không đ chúng ra l u các giá tr  lên đó.

ụ c kh i ẽ ượ t c  các hàm) nó s  đ ả ấ ả ậ ả ở ấ ả ầ ử ượ ặ ằ c đ t b ng 0. Vì v y n u chúng ta khai báo m ng toàn t c  các ph n t ộ ế N u chúng ta khai báo m t m ng toàn c c (bên ngoài t ế ạ  đ t o và t c c:ụ

int billy [5];

ẽ ượ ọ m i ph n t ầ ử ủ billy s  đ c a ở ạ c kh i t o là

0:

ể ả ộ ư ở ạ ầ ử ủ ừ ị Nh ng thêm vào đó, khi chúng ta khai báo m t m ng, chúng ta có th  gán các giá tr   kh i t o cho t ng ph n t ụ  c a nó. Ví d :

int billy [5] = { 16, 2, 77, 40, 12071 };

ư ẽ ả ộ ệ l nh trên s  khai báo m t m ng nh  sau:

ả ớ ặ ặ

ọ { } ph i b ng s   ặ ở ạ ố ả ằ  trong m ng mà chúng ta kh i t o v i c p ngo c nh n  ề ở ớ ặ ả ượ ể [ ]. B i vì đi u này có th    c a m ng đã đ c khai báo v i c p ngo c vuông  ặ   ữ ặ ể ố ế ộ ự ặ ạ c coi là m t s  l p l t nên C++ cho phép đ  tr ng gi a c p ngo c i không c n thi ọ ặ ị ượ ả ướ ủ ị ữ ặ ằ ố ố ầ ử S  ph n t ầ ử ủ ph n t ượ đ vuông, kích th ầ c xác đ nh b ng s  giá tr  gi a c p ngo c nh n. c c a m ng đ

ấ ế

ầ ử ủ

Truy xu t đ n các ph n t

c a m ng.

name[index]

ươ ầ ả ố ớ ủ ư ể ọ ế ộ ỉ ạ ộ ể ng trình trong t m ho t đ ng c a m ng, chúng ta có th   ử ả  c a m ng đ  đ c hay ch nh s a nh  là đ i v i m t bi n bình ườ ư ể Ở ấ ủ  b t kì đi m nào c a ch ầ ử ủ ấ ừ truy xu t t ng ph n t ủ ấ ng. C u trúc c a nó nh  sau: th

ư ở ụ ướ ả ầ ử ồ billy g m 5 ph n t có ki u ể int, chúng ta có th  ể c ta có m ng  ả ầ ử ủ ư trong ví d  tr Nh   ấ ế ừ truy xu t đ n t ng ph n t c a m ng nh  sau:

ụ ể ư ầ ử ứ ị ế Ví d , đ  l u giá tr  75 vào ph n t th  ba c a ủ billy ta vi ư t nh  sau:

billy[2] = 75;

ụ ể ị ủ ầ ử ứ ủ và, ví d , đ  gán giá tr  c a ph n t th  3 c a billy cho bi n ế a, chúng ta vi t: ế

a = billy[2];

ề ọ ươ ư ấ ể ệ ể ế ố ộ ng di n, bi u th c ứ billy[2] gi ng nh  b t kì m t bi n ki u ậ Vì v y, xét v  m i ph int.

ả ắ ầ ừ ỉ ố ch  s  0. Vì ế billy[5], chúng ta ầ ử ứ  cu i cùng s  là  ầ ử ứ t  ớ ạ ủ ủ ả ả ằ Chú ý r ng ph n t ầ ử ố ậ v y, ph n t ấ ế ẽ s  truy xu t đ n ph n t ủ billy là billy[2], vì m ng b t đ u t  th  ba c a  ế ậ ẽ billy[4]. Vì v y n u chúng ta vi ượ t quá gi  th  6 c a m ng và v i h n c a m ng.

ả i h n ch  s  c a m ng là hoàn toàn h p l ể ớ ạ ề ự ự ợ ệ ạ ệ ở t quá gi ấ ư ể ạ ệ ả ế ủ ế ơ c nói đ n kĩ h n khi chúng ta ỏ ỉ ố ủ ệ ượ , tuy nhiên nó  Trong C++, vi c v ỗ ữ ữ i  có th  gây ra nh ng v n đ  th c s  khó phát hi n b i vì chúng không t o ra nh ng l ữ ị ố trong quá trình d ch nh ng chúng có th  t o ra nh ng k t qu  không mong mu n trong  ẽ ượ ệ ự quá trình th c hi n. Nguyên nhân c a vi c này s  đ ắ ầ ử ụ b t đ u s  d ng con tr .

int billy[5]; // khai báo một mảng mới. billy[2] = 75; // truy xuất đến một phần tử của mảng.

ả ầ ạ ụ ầ ử ụ ặ ặ ứ ể ỉ ằ ả ỉ ố ộ ị c cho m ng khi khai báo chúng và th  hai, đ  ch  đ nh ch  s  cho m t ế ả ấ C n ph i nh n m nh r ng chúng ta s  d ng c p ngo c vuông cho hai tác v : đ u tiên  ướ ặ là đ t kích th ầ ử ụ ể ủ ph n t c  th  c a m ng khi xem xét đ n nó.

billy[0] = a; billy[a] = 75; b = billy [a+2]; billy[billy[a]] = billy[2] + 5;

ợ ệ ộ ả M t vài thao tác h p l ớ  khác v i m ng:

12206

// ví dụ về mảng #include int billy [] = {16, 2, 77, 40, 12071}; int n, result=0;

int main () { for ( n=0 ; n<5 ; n++ ) { result += billy[n]; } cout << result; return 0; }

ề M ng nhi u chi u.

ư ả ụ ả ề ể ữ ệ ộ ả ủ ề ả ồ ộ ể ượ ầ ử ư c nh  là m t b ng hai chi u g m các ph n t c coi nh  m ng c a m ng, ví d , m t m ng hai chi u   có ki u d  li u ề ề ả M ng nhi u chi u có th  đ ượ ể ượ ưở c t có th  đ ng t ố ụ ể c  th  và gi ng nhau.

jimmy bi u di n m t m ng hai chi u kích th ư này nh  sau:

int jimmy [3][5];

ể ễ ề ả ộ ướ c 3x5 có ki u ể int. Cách khai báo m ngả

ụ ầ ử ứ ứ ư ọ ề ề  th  hai theo chi u d c và th  t theo chi u ấ ế ư ứ ộ ể và, ví d , cách đ  truy xu t đ n ph n t ể ngang trong m t bi u th c nh  sau:

jimmy[1][3]

ỉ ố ủ ớ ằ ả (hãy nh  r ng ch  s  c a m ng luôn b t đ u t ắ ầ ừ 0).

char century [100][365][24][60][60];

ề ị ớ ạ ỉ ố ở ể ứ ề ả ặ ầ ớ ề   i h n b i hai ch  s  (hai chi u), Chúng có th  ch a bao ử ế ỉ ố ầ ề ỉ ố ượ ơ ụ ế ả ộ ộ ớ ả M ng nhi u chi u không b  gi ả ề nhi u ch  s  tùy thích m c dù ít khí c n ph i dùng đ n m ng l n h n 3 chi u. Hãy th ề xem xét l ng b  nh  mà m t m ng có nhi u ch  s  c n đ n. Ví d :

ả ầ ế ỉ ơ ỷ ộ ị char cho m i giây trong m t th  k , ph i c n đ n h n 3 t ị  giá tr ỗ ả ầ ẽ ể ả ế ộ gán m t giá tr   chars! Chúng ta s  ph i c n kho ng 3GB RAM đ  khai báo nó.

ệ ế ả ng vì chúng ta có th  có k t qu ừ ượ ơ ể ỉ ố ủ ộ ằ ề ả ự ộ ữ ề ả ộ ả M ng nhi u chi u th c ra là m t khái ni m tr u t ươ t ề ự ớ  v i m ng m t chi u b ng m t thao tác đ n gi n gi a các ch  s  c a nó: ng t

ươ ươ ớ ng v i

int jimmy [3][5];   t ng đ int jimmy [15];   (3 * 5 = 15)

// multidimensional array #include #define WIDTH 5 #define HEIGHT 3 int jimmy [HEIGHT][WIDTH]; int n,m; int main () { for (n=0;n

// pseudo-multidimensional array #include #define WIDTH 5 #define HEIGHT 3 int jimmy [HEIGHT * WIDTH]; int n,m; int main () { for (n=0;n

ộ ử ụ ả ư ộ ế ề ả ướ ộ ử ụ ụ ớ ộ ề D i đây là hai ví d  v i cùng m t k t qu  nh  nhau, m t s  d ng m ng hai chi u và ả m t s  d ng m ng m t chi u:

ươ ư ề ả ố ị t gì ra màn hình nh ng c  hai đ u gán giá tr  vào kh i ớ ộ không m t ch nh  có tên ế ng trình nào vi jimmy theo cách sau:

#define HEIGHT 3

ể ơ ữ ủ ằ ỉ ử ướ ủ ế ị ươ ụ ợ ng trình, ví d , trong tr c c a ả #define) đ  đ n gi n hóa nh ng ch nh s a sau này c a  ng h p chúng ta quy t đ nh tăng kích th ỉ ầ ề ớ ổ ị Chúng ta đã đ nh nghĩa h ng ( ườ ch m ngả  v i chi u cao là 4 thay vì là 3, chúng ta ch  c n thay đ i dòng:

thành

#define HEIGHT 4

ữ ố ớ ự ả ổ ươ và không ph i có thêm s  thay đ i nào n a đ i v i ch ng trình.

ố Dùng m ng làm tham s .

ộ ể ư ầ ộ ả ị ộ ề ố ề ộ ượ ổ ứ c t ệ ả ự ế ố ả ế ỉ ủ ề ị ộ ớ ệ ạ ượ i đ  ch c thành m t m ng. Tuy nhiên chúng ta l ở  gi ng thao tác ả ơ ề ệ ơ ả ớ Vào m t lúc nào đó có th  chúng ta c n ph i truy n m t m ng t i m t hàm nh  là  ợ ố ộ ố m t tham s . Trong C++, vi c truy n theo tham s  giá tr  m t kh i nh  là không h p  ả ệ c phép  l , ngay c  khi nó đ ư   truy n đ a ch  c a nó, vi c này cũng t o ra k t qu  th c t  trên nh ng ạ l ạ i nhanh h n nhi u và hi u qu  h n.

void procedure (int arg[])

ậ ể ể ề ấ ả ố ố ể ữ ệ ơ ả ủ ặ ả ả ặ ả ầ ỉ ị ụ ố Đ  có th  nh n m ng là tham s  thì đi u duy nh t chúng ta ph i làm khi khai báo hàm  là ch  đ nh trong ph n tham s  ki u d  li u c  b n c a m ng, tên m ng và c p ngo c  vuông tr ng. Ví d , hàm sau:

int myarray [40];

ậ ể ề ể ố ủ char" và có tên arg. Đ  truy n tham s  cho ả ố ộ nh n vào m t tham s  có ki u "m ng c a  ượ ộ hàm này m t m ng đ ả c khai báo:

procedure (myarray);

ỉ ầ ư ọ ch  c n g i hàm nh  sau:

ụ ụ ể ướ ộ D i đây là m t ví d  c  th

5 10 15 2 4 6 8 10

// arrays as parameters #include void printarray (int arg[], int length) { for (int n=0; n

ố ầ ả ấ ậ ầ ố ứ ọ ả ể ơ ậ int arg[]) ch p nh n m i m ng có ki u c   ế int, b t k  đ  dài c a nó là bao nhiêu, vì v y c n thi t ph i có tham s  th  hai  ề ủ ủ ế ộ ả ể ấ ư ạ Nh  b n có th  th y, tham s  đ u tiên ( ấ ể ộ ả b n là  ể đ  báo cho hàm này bi t đ  dài c a m ng mà chúng ta truy n cho nó.

base_type[][depth][depth]

ầ ể ề ề ả ố ủ ư ề ấ ả Trong ph n khai báo hàm chúng ta cũng có th  dùng tham s  là các m ng nhi u chi u.  C u trúc c a m ng 3 chi u nh  sau:

void procedure (int myarray[][3][4])

ể ư ụ ề ề ộ ớ ố ả ví d , m t hàm v i tham s  là m ng nhi u chi u có th  nh  sau:

ặ ằ ư ặ ầ ặ ặ ả ả ị ậ ủ ề ả ể ố chú ý r ng c p ngo c vuông đ u tiên đ  tr ng nh ng các c p ngo c sau thì không.  ộ ớ ị ả ạ B n luôn luôn ph i làm v y vì trình biên d ch C++ ph i có kh  năng xác đ nh đ  l n  ủ c a các chi u thêm vào c a m ng.

style="BORDER­RIGHT: medium none; PADDING­RIGHT: 0in; BORDER­TOP:  medium none; PADDING­LEFT: 0in; PADDING­BOTTOM: 0in; BORDER­LEFT:  medium none; PADDING­TOP: 0in; BORDER­BOTTOM: windowtext 3pt solid">

ả ả ộ ố ườ ề ề ộ ề ữ ề ỗ ạ ọ ng là i cho nh ng l p trình viên thi u kinh nghi m. Các b n nên đ c bài ư ệ ư ế ế ạ ộ ể ể ể ả M ng, c  m t chi u và nhi u chi u, khi truy n cho hàm nh  là m t tham s  th ậ nguyên nhân gây l ơ 3.3. Con trỏ đ  có th  hi u rõ h n m ng ho t đ ng nh  th  nào.

Bài 8 : Xâu Ký Tự

ươ ế ấ t c  các ch ỉ ể ể ư ễ ờ ng trình chúng ta đã th y cho đ n gi ạ ỗ ỉ ử ụ ể ố ừ , chúng cho phép chúng ta bi u di n các chu i kí t nh  là các t , câu,  ứ ứ ướ ạ ễ ỉ ế ạ ằ ế ự ư i d ng h ng ch  ch a ờ  chúng ta m i ch  dùng chúng d ể ứ ấ ả ể ố ự ả ế Trong t , chúng ta ch  s  d ng các  ố ế bi n ki u s , ch  dùng đ  bi u di n các s . Nh ng bên c nh các bi n ki u s  còn có  ể các xâu kí t ớ đo n văn b n... Cho đ n gi ế quan tâm đ n các bi n có th  ch a chúng.

ơ ả  đ  l u các xâu kí t ầ ớ ằ ể ạ ượ ủ ỉ ể ư ể ỏ ự ể ể ữ ệ c  b n . Đ  có th  th a mãn  ử ụ ể ữ ệ ể char. Hãy nh  r ng ki u d  li u này  i ta s  d ng m ng có ki u  ở ậ ữ ộ  đ n, b i v y nó đ c dùng đ  t o ra xâu c a các kí Trong C++ không có ki u d  li u  ả ườ nhu c u này, ng ự ơ ể ư (char) ch  có th  l u tr  m t kí t ự ơ t đ n.

ụ ự ả Ví d , m ng sau (hay là xâu kí t ):

char jenny [20];

ộ ự ớ ộ ự ạ ự ạ ể ưở ượ v i đ  dài c c đ i là 20 kí t . B n có th  t ng t ng nó ư ể ư có th  l u m t xâu kí t nh  sau:

ướ ự ạ ầ ụ jenny có th  l u ả c c c đ i này không c n ph i luôn luôn dùng đ n. Ví d ,  ể ư ế ự ể ư ự   ủ ộ ộ ủ ơ ộ ể ượ ắ ộ ự ộ Kích th ả xâu "Hello" hay "Merry christmas". Vì các m ng kí t  có th  l u các xâu kí t ộ ướ ể ế c đ  k t thúc m t n i dung c a  ng n h n đ  dài c a nó, trong C++ đã có m t quy  ế ự ằ '\0'.  t là  c vi m t xâu kí t b ng m t kí t null, có th  đ

ể ể ư ữ ộ ả ễ jenny (m t m ng có 20 ph n t ầ ử ể char) khi l u tr  xâu ki u Chúng ta có th  bi u di n  kí t ự "Hello" và "Merry Christmas" theo cách sau:

ằ ượ ủ ộ ể ệ ế

'\0') đ

null ( c dùng đ  báo hi u k t ộ ễ ữ ể ị ị ự Chú ý r ng sau n i dung c a xâu, m t kí t ữ thúc xâu. Nh ng ô màu xám bi u di n nh ng giá tr  không xác đ nh.

ở ạ

Kh i t o các xâu kí t

.

char mystring[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

ự ữ ả ữ ộ ị ị ươ ề ả ườ ữ Vì nh ng xâu kí t ụ ế ố d , n u chúng ta mu n kh i t o m t xâu kí t ể ng t th  làm đi u đó t ư ả ng nên chúng cũng nh  các m ng khác. Ví    là nh ng m ng bình th ở ạ ự ớ  v i nh ng giá tr  xác đ nh chúng ta có  ự ư ớ  nh  v i các m ng khác:

ở ạ ể ộ ị ự ằ ử ụ b ng cách khác: s  d ng ằ Tuy nhiên, chúng ta có th  kh i t o giá tr  cho m t xâu kí t các h ng xâu kí t ự.

"the result is: "

ụ ươ ướ ượ ệ ể ễ ấ ng tr ặ đ  xu t hi n vài l n. Chúng đ c bi u di n trong c p ngo c kép ( c các  "), ử ụ ứ ể Trong các bi u th c chúng ta đã s  d ng trong các ví d  trong các ch ặ ầ ự ể ằ h ng xâu kí t ví d :ụ

ộ ằ ự ử ụ ở ộ ố ỗ là m t h ng xâu kí t chúng ta s  d ng m t s  ch .

, c p ngo c kép ( ỗ ơ ') cho phép bi u di n h ng kí t ể ễ ộ ở ố ự ặ ự ằ ỗ  cu i chu i m t kí t ế  liên ti p, và ặ ")  '\0') luôn null ( ư ấ ố Không gi ng nh  d u nháy đ n ( ằ ự ộ ễ ể là h ng bi u di n m t chu i kí t ượ ự ộ  đ ng thêm vào.  c t đ

ở ạ ể ậ ộ Vì v y chúng ta có th  kh i t o xâu

mystring theo m t trong hai cách sau đây:

char mystring [] = { 'H', 'e', 'l', 'l', 'o', '\0' }; char mystring [] = "Hello";

ả ượ ớ ng h p m ng (hay xâu kí t ) c khai báo v i kích th ướ   c ự mystring đ ự ộ ự ộ ớ ả Trong c  hai tr : 5 kí t 6 kí t ườ ự ể  bi u di n ợ ễ Hello c ng v i m t kí t null.

mystring = "Hello"; mystring[] = "Hello";

ệ ề ầ ằ ế ụ ặ ứ ả kh i t o ư ệ ử ở ạ ằ c khi ti p t c, tôi c n ph i nh c nh  b n r ng vi c gán nhi u h ng nh  vi c s   ả ở ạ  m ng, t c là lúc khai báo m ng. Các ắ  khi ấ ứ ướ Tr ụ d ng d u ngo c kép ( ươ ể bi u th c trong ch ả ỉ ợ ệ ") ch  h p l ư ng trình nh :

mystring = { 'H', 'e', 'l', 'l', 'o', '\0' };

ợ ệ ả ệ ướ ậ là không h p l , c  câu l nh d i đây cũng v y:

ỉ ậ ể ở ạ ề ả ằ ớ Chúng ta ch  có th  "gán" nhi u h ng cho m t m ng vào lúc kh i t o  ể ả ộ ả ộ ộ ế ể ở ạ ậ ờ ữ ộ ỉ =) không th  nh n v  trái là c  m t m ng mà ch    c a nó. Vào th i đi m kh i t o m ng là m t  ặ ầ ử ủ ự ự ả ử ụ ộ ệ ặ ấ ộ t, vì nó không th c s  là m t l nh gán m c dù nó s  d ng d u ể ng h p đ c bi V y hãy nh :  nó. Nguyên nhân là m t thao tác gán ( có th  nh n m t trong nh ng ph n t ệ ườ tr ằ b ng ( ậ ợ =).

ị Gán giá tr  cho xâu kí t

ế ủ ộ ỉ ự ộ ộ ả  cho m t m ng ki u ả ể ứ  c a m ng ch  không th  là c   ộ ử ụ ể char s  d ng m t ư ầ ử ủ ể ộ ệ Vì v  trái c a m t l nh gán ch  có th  là m t ph n t ả ả ể m ng, chúng ta có th  gán m t xâu kí t ươ ng pháp nh  sau:  ph

mystring[0] = 'H'; mystring[1] = 'e'; mystring[2] = 'l'; mystring[3] = 'l'; mystring[4] = 'o'; mystring[5] = '\0';

ươ ả ộ ng pháp th c t ư ự ể ử ụ ộ ị . Đ  gán giá tr  cho m t xâu   ượ ị c đ nh ự ế ể ể strcpy (string copy), hàm này đ , chúng ta có th  s  d ng lo t hàm ki u  ư ể ượ ọ Nh ng rõ ràng đây không ph i là m t ph ạ kí t nghĩa trong string.h và có th  đ c g i nh  sau:

strcpy (string1, string2);

strcpy (mystring, "Hello");

ể ả ộ ệ ỏ ở ậ ệ ể ằ ủ string2 sang string1. string2 có th  là m t m ng, con  ộ ự, b i v y l nh sau đây là m t cách đúng đ  gán xâu h ng ộ L nh này copy n i dung c a  ằ ộ h ng xâu kí t tr  hay m t  "Hello" cho mystring:

Ví d :ụ

J. Soulie

// setting value to string #include #include

int main () { char szMyName [20]; strcpy (szMyName,"J. Soulie"); cout << szMyName; return 0; }

ể ằ ả ể ử ụ ể Đ  ý r ng chúng ta ph i include file

 đ  có th  s  d ng hàm

strcpy.

ể ế ư ả ơ ướ

setstring d

ể i đây đ ặ ự ệ ộ ố M c dù chúng ta luôn có th  vi th c hi n m t thao tác gi ng nh ộ t m t hàm đ n gi n nh  hàm  ư strcpy:

J. Soulie

// setting value to string #include

void setstring (char szOut [], char szIn []) { int n=0; do { szOut[n] = szIn[n]; n++; } while (szIn[n] != 0); }

int main () { char szMyName [20]; setstring (szMyName,"J. Soulie"); cout << szMyName; return 0; }

ử ụ ể ả ị ộ ng dùng khác đ  gán giá tr  cho m t m ng là s  d ng tr c ti p  ị ủ ự ế ở ng h p này giá tr  c a xâu kí t c gán b i ự ượ  đ ườ ự ệ ườ ứ ươ ộ ng th c th M t ph ậ ữ ệ cin). Trong tr dòng nh p d  li u ( ươ ng i dùng trong quá trình ch ườ ợ ng trình th c hi n.

ớ ươ ứ ớ c s  d ng v i các xâu kí t ng đ c dùng v i ph ng th c ươ ứ ự  nó th ể ượ ọ ượ ử ụ Khi cin đ ủ getline c a nó, ph ng th c này có th  đ ượ ườ ư c g i nh  sau:

cin.getline ( char buffer[], int length, char delimiter = ' \n');

ộ ệ ữ ữ ệ ư ả ộ ẳ ướ ủ

length là đ  dài c c đ i c a b  đ m (kích th

ả c c a m ng) và ặ ị ế ậ ộ c dùng đ  k t thúc vi c nh p, m c đ nh ­ n u chúng ta không ự ượ  đ ẽ ự ố ố ỉ ơ ẽ ư ị trong đó buffer (b  đ m) là đ a ch  n i s  l u tr  d  li u vào (nh  là m t m ng  ự ạ ủ ộ ệ ạ ch ng h n),  ể ế delimiter là kí t dùng tham s  này ­ s  là kí t ệ '\n'). xu ng dòng (

// cin with strings #include

ụ ặ ạ ấ ả ữ ư t c  nh ng gì b n gõ trên bàn phím. Nó r t đ n gi n nh ng là  ớ ả ự ư ế i t ạ ộ ạ Ví d  sau đây l p l ấ ụ m t ví d  cho th y b n có th  s  d ng ấ ơ ể ử ụ cin.getline v i các xâu kí t nh  th  nào:

What's your name? Juan Hello Juan. Which is your favourite team? Inter Milan I like Inter Milan too.

int main () { char mybuffer [100]; cout << "What's your name? "; cin.getline (mybuffer,100); cout << "Hello " << mybuffer << ".\n"; cout << "Which is your favourite team? "; cin.getline (mybuffer,100); cout << "I like " << mybuffer << " too.\n"; return 0; }

ả ử ụ ế i g i ế ộ ữ ứ ơ ộ ả i g i th  hai đ n gi n là thay th  n i ng trình làm trong l ờ ọ cin.getline chúng ta s  d ng cùng m t bi n xâu  ờ ọ ớ ằ ộ Chú ý trong c  hai l (mybuffer). Nh ng gì ch dung c a ủ buffer trong l ươ ờ ọ i g i cũ b ng n i dung m i.

cin >> mybuffer;

ớ ằ ề ớ ế ự ế ừ ầ ử ụ ể ượ ạ ẽ ẩ ứ ng th c này có th  đ ủ ươ ụ ươ cin.getline. Ví d , trong ch n trình c a chúng ta, khi  ể ế thay cho  ậ ữ ệ ừ ườ ố ầ ớ ế ạ N u b n còn nh  ph n nói v  giao ti p v i, b n s  nh  r ng chúng ta đã s  d ng toán ậ ữ ệ ể  ử >> đ  nh n d  li u tr c ti p t c dùng   đ u vào chu n. Ph t ự ớ v i các xâu kí t chúng ta mu n nh n d  li u t i dùng chúng ta có th  vi ng t:

ư ữ ế ệ ẽ ạ ệ l nh này s  làm vi c nh  nó có nh ng h n ch  sau mà

cin.getline không có:

(cid:0) ữ ứ ng th c ậ ự ố ừ ơ  đ n (không nh n đ ồ ươ c c  câu) vì ph ố ả ấ ấ ậ ượ ả ấ  tr ng(bao g m c  d u cách, d u tab và d u xu ng dòng) làm ế (cid:0) ướ ỉ ị ộ ệ c cho b  đ m. Ch ơ ủ ạ ứ ươ ỡ ủ ể ạ ả ớ ị ỉ ể Nó ch  có th  nh n nh ng t ử ụ này s  d ng kí t ệ ấ d u hi u k t thúc..  ng trình c a b n có  Nó không cho phép ch  đ nh kích th ế ữ ệ ổ th  ch y không  n đ nh n u d  li u vào l n h n kích c  c a m ng ch a nó.

ữ ậ ố ự ạ ử ụ b n nên s  d ng Vì nh ng nguyên nhân trên, khi mu n nh p vào các xâu kí t cin.getline thay vì cin >>.

ể ổ

Chuy n đ i xâu kí t

sang các ki u khác.

ễ ự ể ể ố ộ ể ư ạ ụ ộ ư ậ ộ ề ạ ỗ ồ ậ ư ộ ố ễ ấ ể ự  null) và không d  gì  ư ệ cstdlib (stdlib.h) đã cung c p 3 ữ ệ ể ữ ệ  có th  bi u di n nhi u ki u d  li u khác nh  d ng s  nên vi c  Vì m t xâu kí t ể ấ ữ ố ổ ộ chuy n đ i n i dung nh  v y sang d ng s  là r t h u ích. Ví d , m t xâu có th  mang giá tr  ị "1977"nh ng đó là m t chu i g m 5 kí t ự ể ả  (k  c  kí t chuy n thành m t s  nguyên. Vì v y th  vi n  macro/hàm h u ích sau:

(cid:0)

(cid:0)

(cid:0) ể ể ể ể int.  ể long.  ể float. atoi: chuy n xâu thành ki u  atol: chuy n xâu thành ki u  atof: chuy n xâu thành ki u

// cin and ato* functions #include #include

ấ ả ả ề ị ố int, long ho c ặ float). Các ế ợ ậ ơ ố ng th c  ầ ườ ử ụ ộ ố ươ ậ ộ T t c  các hàm này nh n m t tham s  và tr  v  giá tr  s  ( ươ ớ hàm này khi k t h p v i ph ổ ể ph ứ cin>> c  đi n khi yêu c u ng ộ ứ getline c a ủ cin là m t cách đáng tin c y h n  ậ i s  d ng nh p vào m t s : ng th c

Enter price: 2.75 Enter quantity: 21 Total price: 57.75

int main () { char mybuffer [100]; float price; int quantity; cout << "Enter price: "; cin.getline (mybuffer,100); price = atof (mybuffer); cout << "Enter quantity: "; cin.getline (mybuffer,100); quantity = atoi (mybuffer); cout << "Total price: " << price*quantity; return 0; }

ỗ Các hàm đ  thao tác trên chu i

ề ể strcpy mà còn có nhi u hàm khác đ ư ệ cstring (string.h) không ch  có hàm ướ ớ ủ ụ ấ Th  vi n  ỗ thao tác trên chu i. D i đây là gi ỉ ệ ướ i thi u l t qua c a các hàm thông d ng nh t:

strcat:   char* strcat (char* dest, const char* src); ắ G n thêm chu i ỗ src vào phía cu i c a ố ủ dest. Tr  v ả ề dest.

strcmp:   int strcmp (const char* string1, const char* string2); ế ằ So sánh hai xâu string1 và string2. Tr  v ả ề 0 n u hai xâu là b ng nhau.

strcpy:   char* strcpy (char* dest, const char* src);

ộ Copy n i dung c a ủ src cho dest. Tr  v

ả ề dest.  strlen:   size_t strlen (const char* string); ả ề ộ Tr  v  đ  dài c a ươ ươ ớ char[] ủ string.  ng đ Chú ý: char* hoàn toàn t ng v i

Bài 9 : Con Trỏ

ấ ướ ươ ữ ạ ộ ế c l u tr  t ể ớ ố ớ ỗ ữ ỉ ớ ộ ị ớ ế i các tên.  Chúng ta đã bi t các bi n chính là các ô nh  mà chúng ta có th  truy xu t d ỗ ụ ể ượ ư ế ng trình  Các bi n này đ i nh ng ch  c  th  trong b  nh . Đ i v i ch ủ ộ ị ồ ớ ộ c a chúng ta, b  nh  máy tính ch  là m t dãy g m các ô nh  1 byte, m i ô có m t đ a  ỉ ch  xác đ nh.

ớ ố ộ ố ấ ả ộ ể ế ộ ố t đ i v i b  nh  máy tính chính là m t ph  trong m t thành ph .  ấ ố ầ ự ớ  v i m t cái tên duy nh t  c đánh s  tu n t ượ ơ ạ ư c n i ớ ố ư ậ ế ố ỉ ẫ ầ ộ ộ ự ố ố ớ ộ M t s  mô hình t ề ượ ộ t c  các ngôi nhà đ u đ Trên m t ph  t ố ầ nên n u chúng ta nói đ n s  27 ph  Tr n H ng Đ o thì chúng ta có th  tìm đ đó mà không l m l n vì ch  có m t ngôi nhà v i s  nh  v y.

nh  vi c đánh s  các ngôi nhà, h  đi u hành t ng t ch c ố ế ổ ứ , nên n u chúng ta nói đ n v  trí 1776 trong  ớ ị ệ ề ị ế ỉ ư ậ ộ ị ớ ớ ỉ ự ư ệ ổ ứ ươ ớ  ch c t Cũng v i cách t ầ ự ấ ố ơ ữ ộ b  nh  thành nh ng s  đ n nh t, tu n t ớ ế ộ b  nh  chúng ta bi t chính xác ô nh  đó vì ch  có m t v  trí v i đ a ch  nh  v y.

ử ấ ị

Toán t

l y đ a ch  (

ỉ &).

ờ ể ế ả ượ ư ơ ữ ế ớ ộ ắ ằ ế ị ở ượ ề ộ ị c l u tr  trong m t v  trí  ượ ặ c đ t ­  ị  đ ng b i trình biên d ch và h  đi u hành,  ế ệ ề ể ự ộ ỉ ế ố t ữ ở ộ Vào th i đi m mà chúng ta khai báo m t bi n thì nó ph i đ ụ ể c  th  trong b  nh . Nói chung chúng ta không quy t đ nh n i nào bi n đó đ ậ c làm t th t may m n r ng đi u đó đã đ ộ ộ ị ư nh ng m t khi h  đi u hành đã gán m t đ a ch  cho bi n thì chúng ta có th  mu n bi ượ ư ế bi n đó đ ệ ề c l u tr đâu.

&), có nghĩa

ted = &andy;

ặ ướ ự ệ ộ ấ ế ề ằ c th c hi n b ng cách đ t tr c tên bi n m t d u và ( ị ể ượ ỉ ủ ". Ví d : ụ Đi u này có th  đ là "đ a ch  c a

ặ ướ ấ ị ế ted đ a ch  c a bi n  ế ế andy, vì khi đ t tr ế ế andy d u và ( ỉ ủ ị c tên bi n  ế ỉ ủ ộ ủ ỉ ẽ &)  s  gán cho bi n  chúng ta không còn nói đ n n i dung c a bi n đó mà ch  nói đ n đ a ch  c a nó trong  ớ ộ b  nh .

andy = 25; fred = andy; ted = &andy;

ả ử ằ ớ ị ế Gi s  r ng bi n ế andy đ ượ ặ ở c đ t ô nh  có đ a ch ỉ 1776 và chúng ta vi ư t nh  sau:

ả ẽ ố ơ ồ ướ ư ế k t qu  s  gi ng nh  trong s  đ  d i đây:

ư ầ ớ ề ệ ề ị ế andy nh  chúng ta đã làm r t l n nhi u  ấ ầ ỉ mà h  đi u  ế ted chúng ta đã gán đ a ch ữ ị ủ ừ ư ả ử ộ ủ Chúng ta đã gán cho fred n i dung c a bi n  ư ướ khác trong nh ng ph n tr c nh ng v i bi n  ế andy, chúng ta v a gi hành l u giá tr  c a bi n s  nó là

1776.

ữ ữ ị ế ư ế ở ư ted trong ví d  tr c g i ỉ ủ ỏ ề ư ụ ướ ượ ử ụ c s  d ng r t ộ ấ ẽ ấ ể ế ể ế ượ ượ ọ c) đ ấ ư ế c khai báo nh  th Nh ng bi n l u tr  đ a ch  c a m t bi n khác (nh   là con trỏ. Trong C++ con tr  có r t nhi u  u đi m và chúng đ ườ ng xuyên, Ti p theo chúng ta s  th y các bi n ki u này đ th nào.

Toán t

tham chi u (

ế *)

beth = *ted;

ằ ử ụ ấ ự ế ế ỏ ế ượ c tên bi n con tr  m t d u sao ( ữ ị ượ ư c l u tr    ở *) ­ ể ượ ị ị ượ ế ậ ế ế B ng cách s  d ng con tr  chúng ta có th  truy xu t tr c ti p đ n giá tr  đ trong bi n đ đây có th  đ t: ể ỏ ộ ấ ặ ướ ằ ỏ ở c tr  b i nó b ng cách đ  tr ỏ ở ". Vì v y, n u chúng ta vi c d ch là " c tr  b i giá tr  đ

ể ọ ị ượ ẽ c tr  b i ỏ ở  ted" beth s  mang giá tr ị 25, (chúng ta có th  đ c nó là: "beth b ng  vì ted b ng ằ ằ 1776 và giá tr  tr  b i giá tr  đ ị ỏ ở 1776 là 25.

ớ ị

ted có giá tr  ị 1776, nh ng ư *ted (v i m t d u sao đ ng  ữ

ộ ấ ự ằ ệ ỉ 1776, đó là 25. Hãy chú ý s  khác bi t ạ ướ ữ ế ệ ượ ằ ả t đ c r ng  B n ph i phân bi ị ượ ư ỏ ớ c) tr  t tr i giá tr  đ c l u tr  trong đ a ch   ấ ệ gi a vi c có hay không có d u sao tham chi u.

beth = ted; // beth bằng ted ( 1776 )

beth = *ted; // beth bằng giá trị được trỏ bởi( 25 )

ỉ &) ể ượ ị ị ử ấ ị  l y đ a ch  ( c dùng nh  là m t ti n t c d ch là " ỉ ủ ", vì v yậ đ a ch  c a ư ể ượ ọ Toán t ượ Nó đ &variable1 có th  đ ộ ề ố ủ  c a bi n và có th  đ ị c đ c là "đ a ch  c a ế ỉ ủ variable1".

ử tham chi u ( ộ ể ứ ượ ư c coi nh ể ượ ị c tính toán là n i dung đ ị ượ ỏ ở c tr  b i bi u th c đ ỏ ở ".. ượ c tr  b i ượ ọ c d ch là " ị ượ giá tr  đ c tr  b i "giá tr  đ ế *) Toán t ầ ượ ằ ỉ Nó ch  ra r ng cái c n đ ỉ ộ ị là m t đ a ch . Nó có th  đ c đ c là  *mypointer đ ỏ ở mypointer".

andy = 25; ted = &andy;

ữ ụ ớ Vào lúc này, v i nh ng ví d  đã vi ế ở t trên

andy == 25 &andy == 1776 ted == 1776 *ted == 25

ể ễ ậ ấ ả ể ạ b n có th  d  dàng nh n ra t ứ t c  các bi u th c sau là đúng:

ế Khai báo bi n ki u con tr

ỏ ả ỏ ớ ế ế ế ầ i nên c n thi ị ỏ ỏ ớ ự ế ế ậ ả t  i khai báo nó. Vì v y, khai báo ỏ ẽ ỉ ộ ế ẫ Vì con tr  có kh  năng tham chi u tr c ti p đ n giá tr  mà chúng tr  t ộ ể ữ ệ ph i ch  rõ ki u d  li u nào mà m t bi n con tr  tr  t ủ c a m t bi n con tr  s  có m u sau:

type * pointer_name;

int * number; char * character; float * greatnumber;

ể ủ ả ỏ ể ữ ệ ượ c tr  t ỏ ớ không ph iả  là ki u c a b n thân con tr . Ví i, trong đó type là ki u d  li u đ d : ụ

ỏ ầ ủ ỏ ể ữ ệ ớ ư ỗ ề ộ ộ ữ ệ ỏ ộ ỏ ớ ư i m t ki u d  li u khác nhau nh ng  ộ ượ ướ ủ ng b  nh  nh  nhau (kích th c c a  ỏ ớ ư i không  ể ạ ộ i ki u ộ ớ ư ng b  nh  nh  nhau, m t ki u ể char và cái còn l ể int, m t ki u ế đó là ba khai báo c a con tr . M i bi n đ u tr  t ế ề ả c  ba đ u là con tr  và chúng đ u chi m m t l ệ ề ế ộ m t bi n con tr  tùy thu c vào h  đi u hành). nh ng d  li u mà chúng tr  t ộ ượ ế chi m l float.

ả ạ ặ ấ ấ i r ng d u sao ( ỏ ạ ằ ộ Tôi ph i nh n m nh l ằ có nghĩa r ng: đó là m t con tr  và hoàn toàn không liên quan đ n toán t ỏ ỉ ộ *) mà chúng ta đ t khi khai báo m t con tr  ch   ế ử ế  tham chi u

ướ ụ ả ơ ỉ ượ c đó. Đó đ n gi n ch  là hai tác v  khác nhau đ ể c bi u ộ ấ ễ ở mà chúng ta đã xem xét tr di n b i cùng m t d u.

value1==10 / value2==20

// my first pointer #include

int main () { int value1 = 5, value2 = 15; int * mypointer;

mypointer = &value1; *mypointer = 10; mypointer = &value2; *mypointer = 20; cout << "value1==" << value1 << "/ value2==" << value2; return 0; }

ằ ượ ổ ử ấ ị ủ value1 và value2 đ ị ị ượ ầ ế c thay đ i m t cách gián ti p. Đ u tiên  ỉ &) và sau đó  ị  l y đ a ch  ( ỏ ở value1 vì  ị ượ c tr  b i ộ ỉ ủ value1 dùng toán t ỏ ở mypointer, đó là giá tr  đ ế ử Chú ý r ng giá tr  c a  chúng ta gán cho mypointer đ a ch  c a  c tr  b i  chúng ta gán 10 cho giá tr  đ ộ ậ v y chúng ta đã s a bi n ế value1 m t cách gián ti p

ộ ỏ ị ể ạ ươ ớ ộ Đ  b n có th  th y r ng m t con tr  có th  mang m t vài giá tr  trong cùng m t  ch ể ộ ỏ ớ value2 và v i cùng m t con tr . ộ ể ấ ằ ẽ ặ ạ ng trình chúng ta s  l p l i quá trình v i

ơ ộ ộ ụ ứ ạ Đây là m t ví d  ph c t p h n m t chút:

value1==10 / value2==20

// more pointers #include

int main () { int value1 = 5, value2 = 15; int *p1, *p2;

p1 = &value1; // p1 = địa chỉ của value1 p2 = &value2; // p2 = địa chỉ của value2 *p1 = 10; // giá trị trỏ bởi p1 = 10 *p2 = *p1; // giá trị trỏ bởi p2 = giá trị trỏ bởi p1 p1 = p2; // p1 = p2 (phép gán con trỏ) *p1 = 20; // giá trị trỏ bởi p1 = 20 cout << "value1==" << value1 << "/

value2==" << value2; return 0; }

int *p1, *p2;

ủ ạ ự ể ộ M t dòng có th  gây s  chú ý c a b n là:

*) tr

ặ ấ ỏ ằ ướ ả

int và vì theo th  t

ể ế ề ỗ ỏ c m i con tr . Nguyên  ứ ự ừ ả  ph i sang trái,   t c tên ki u. Chúng ta đã nói đ n đi u này trong bài ể ữ ệ ượ c tính tr 1.3: Các toán dòng này khai báo hai con tr  b ng cách đ t d u sao ( nhân là ki u d  li u khai báo cho c  dòng là  ướ ấ d u sao đ tử.

Con tr  và m ng.

int numbers [20]; int * p;

ớ ị ươ ủ ng v i đ a ch  ph n t đ u tiên c a nó, ầ ử ầ ỉ ủ ủ ỏ ớ ươ ỉ ng v i đ a ch  c a ph n t ả ng đ ầ ử ầ  đ u tiên mà nó tr  t i, vì ộ , tên c a m t m ng t ươ ỏ ươ ư ự ế ụ ự ế Trong th c t ư ộ ố gi ng nh  m t con tr  t ậ v y th c t ng đ ớ ị  chúng hoàn toàn nh  nhau. Ví d , cho hai khai báo sau:

p = numbers;

ẽ ợ ệ ệ l nh sau s  h p l :

ươ ươ ộ ệ ng và chúng có cũng thu c tính, s  khác bi

p và numbers là t ể

numbers = p;

ự t duy  ỏ p trong khi numbers luôn tr  ỏ ầ ử ầ ượ ị ớ ị ầ ử ể int mà nó đ đ u tiên trong s  20 ph n t ki u  ỏ ườ ỏ ằ ng, ậ   c đ nh nghĩa v i. Vì v y, ộ   numbers là m t con tr  h ng. ệ đây Ở ấ nh t là chúng ta có th  gán m t giá tr  khác cho con tr   ế đ n ph n t ố không gi ng nh   L nh gán sau đây là không h p l ng đ ộ ố ộ ế ư p ­ đó là m t bi n con tr  bình th ợ ệ :

ỏ ằ ể ượ ả ộ ị

numbers là m t m ng (con tr  h ng) và không có giá tr  nào có th  đ

c gán cho ở b i vì  ằ các h ng.

ấ ủ ế ọ ấ ả ứ ể ỏ t c  các bi u th c có con tr ỏ ụ ướ Vì con tr  cũng có m i tính ch t c a m t bi n nên t trong ví d  d i đây là hoàn toàn h p l ộ ợ ệ :

10, 20, 30, 40, 50,

// more pointers #include

int main () { int numbers[5];

int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", "; return 0; }

a[5] = 0; // a [offset of 5] = 0 *(a+5) = 0; // pointed by (a+5) = 0

ấ ặ ượ ặ ả  c a m ng mà   offset và ý nghĩa ỏ ế ổ ứ ế ớ ể ỉ ả ầ ử ủ Trong bài "m ng" chúng ta đã dùng d u ngo c vuông đ  ch  ra ph n t ử ư ặ ố c coi nh  là toán t chúng ta mu n tr  đ n. C p ngo c vuông này đ ể ụ ỏ ượ ủ c a chúng không đ i khi đ c dùng v i bi n con tr . Ví d , hai bi u th c sau đây:

ươ ươ ả ộ là hoàn toàn t ng đ ng và h p l ỏ ợ ệ ấ ể a là m ng hay là m t con tr . b t k

ở ạ

Kh i t o con tr

int number; int *tommy = &number;

ẽ ỏ ớ ể ỏ ố ị ỉ ế i bi n ẽ Khi khai báo con tr  có th  chúng ta s  mu n ch  đ nh rõ ràng chúng s  tr  t nào,

int number; int *tommy; tommy = &number;

ươ ươ là t ng đ ớ ng v i:

int number; int *tommy; *tommy = &number;

ỏ ị ỉ ộ ả ả ạ ầ ứ i ch   ế ả ớ ằ ỏ ị ượ ỏ ấ ử ộ i. B n c n ph i nh  r ng khi khai báo m t bi n con c dùng đ  ch  ra nó là m t con tr , và hoàn toàn khác v i toán t ộ ấ ế ớ ượ ử ế ỏ ớ ể ỉ ặ  khác nhau m c dù chúng đ c vi ợ ệ ỏ ớ Trong m t phép gán con tr  chúng ta ph i luôn luôn gán đ a ch  mà nó tr  t ộ không ph i là giá tr  mà nó tr  t ớ tr , d u sao ( *) đ t v i cùng m t d u. Vì  tham chi u. Đó là hai toán t ệ ậ v y, các câu l nh sau là không h p l :

char * terry = "hello";

ư ố ớ ở ạ ỏ ỏ ớ ả ị ị i ị ằ ể ế ờ ỏ Nh  đ i v i m ng, trình biên d ch cho phép chúng ta kh i t o giá tr  mà con tr  tr  t ằ b ng giá tr  h ng vào th i đi m khai báo bi n con tr :

ộ ượ ỏ ể ứ "hello" và m t con tr ớ ớ ượ ự c dành đ  ch a   h') đ ộ terry. N u ế ố ố  đ u tiên c a kh i nh  này (đó là kí t ỉ c gán cho  ể ượ ệ ợ ng h p này m t kh i nh  tĩnh đ ự ầ ủ ượ ư ạ ị i đ a ch  1702, l nh khai báo trên có th  đ c l u t ư ế c hình dung nh  th ườ trong tr ỏ ớ tr  t i kí t "hello" đ này:

ắ ạ ằ ứ ả ả ầ c n ph i nh c l i r ng

terry mang giá tr  ị 1702 ch  không ph i là

'h' hay "hello".

terry[4] = '!'; *(terry+4) = '!';

ỏ ớ ể ượ ử ụ ỏ terry tr  t ế ộ và nó có th  đ ầ i m t xâu kí t ả ộ ộ ỏ ằ ộ ự ỉ ơ ộ ấ ể ự ấ ằ ệ   ự 'o' b ng m t d u ch m than, chúng ta có th  th c hi n vi c ằ ố ớ ư c s  d ng nh  là đ i v i  Bi n con tr   ụ ế ớ ằ ả m t m ng (hãy nh  r ng m t m ng ch  đ n thu n là m t con tr  h ng). Ví d , n u  ệ ố chúng ta mu n thay kí t đó b ng hai cách:

ố ớ ặ t t ứ   ế *(terry+4) m c dù bi u th c ầ ộ ể ỏ ế ẽ terry tr  đ n s ế terry[4] là hoàn toàn gi ng v i vi ớ ằ hãy nh  r ng vi ụ ệ ớ ấ thông d ng nh t là cái đ u tiên. V i m t trong hai l nh trên xâu do  ị ư có giá tr  nh  sau:

ố ọ ớ

Các phép tính s  h c v i pointer

ệ ệ ỏ ơ ớ ướ ế ượ ừ ỉ ộ

ố ọ ớ ể ữ ệ ố ự Vi c th c hi n các phép tính s  h c v i con tr  h i khác so v i các ki u d  li u s   ư ộ ả ộ c phép dùng. Nh ng c  c ng và  c h t, ch  phép c ng và tr  là đ nguyên khác. Tr ỏ ỏ ế ể ữ ệ ủ cướ  c a ki u d  li u mà bi n con tr  tr   ả ụ ế ừ ề kích th tr  đ u cho k t qu  ph  thu c vào  i. ớ t

ấ ể ữ ệ ế ể ữ ệ ề ơ ơ ỗ ể i và chúng có th  chi m ch   ể ố char ề ế ế ồ ạ Chúng ta th y có nhi u ki u d  li u khác nhau t n t ặ ụ nhi u h n ho c ít h n các ki u d  li u khác. Ví d , trong các ki u s  nguyên,  short chi m 2 byte và  chi m 1 byte, ế long chi m 4 byte.

char *mychar; short *myshort; long *mylong;

ả ử ỏ Gi s  chúng ta có 3 con tr  sau:

ầ ượ ỏ ớ và chúng l n l t tr  t i ô nh ớ 1000, 2000 and 3000.

mychar++; myshort++; mylong++;

ế ế N u chúng ta vi t

ợ ư ạ ẽ ẽ ộ ể ti p theo có cùng ki u mà nó đã đ ầ ử ế ủ ỏ ớ ẽ ượ ộ i ph n t ằ ể ữ ệ ậ ế ướ ỏ ị ị 1001. Tuy nhiên myshort s  mang giá tr   mychar ­ nh  b n mong đ i ­ s  mang giá tr   2002 và mylong mang giá tr  ị 3004. Nguyên nhân là khi c ng thêm 1 vào m t con tr  thì  nó s  tr  t th ộ ỏ ượ ị c đ nh nghĩa, vì v y kích  c c ng thêm vào bi n con tr . ẽ ỏ ớ c tính b ng byte c a ki u d  li u nó tr  t i s  đ

mychar = mychar + 1; myshort = myshort + 1; mylong = mylong + 1;

ề ừ ố ớ ớ ả ỏ ượ ế ả ư ế Đi u này đúng v i c  hai phép toán c ng và tr  đ i v i con tr . Chúng ta cũng hoàn  toàn thu đ ộ ế c k t qu  nh  trên n u vi t:

++) và gi m (ả ứ ế *), vì v y bi u th c sau đây có th  d n t

*p++; *p++ = *q++;

ầ ạ ằ ử ề ử ớ tăng ( ể ể ẫ ớ ế ả  tham chi u ( ề ư --) đ u có quy n  u  ả i k t qu ả ả C n ph i c nh báo b n r ng c  hai toán t ậ ơ tiên l n h n toán t sai:

ệ ươ ự ệ ị ng v i ng đ ớ *(p++) đi u mà nó th c hi n là tăng ớ ỉ p (đ a ch  ô nh ươ ứ ầ L nh đ u tiên t ỏ ớ mà nó tr  t ề ị ỏ ớ ả i ch  không ph i là giá tr  tr  t i).

++) đ u đ

*p = *q; p++; q++;

ệ ứ ề ượ ử ự ả c ượ tăng ( ề ị ủ *q đ ớ ươ ươ ả ệ L nh th  hai, c  hai toán t gán cho *p và sau đó c  q và p đ u tăng lên 1. L nh này t c th c hi n sau khi giá tr  c a  ệ ng đ ng v i:

ư ướ ặ ơ ạ ặ ể c, tôi khuyên các b n nên dùng các c p ngo c đ n đ ữ ế ố Nh  đã nói trong các bài tr ả tránh nh ng k t qu  không mong mu n.

ỏ ỏ ớ

Con tr  tr  t

i con tr

char a; char * b; char ** c; a = 'z'; b = &a; c = &b;

ỏ ỏ ớ ử ụ ư i các con tr  khác gi ng nh  là tr  t ộ ấ ỏ ớ ữ ệ   i d  li u. ế ố ỗ ỉ ầ ể ệ ỏ C++ cho phép s  d ng các con tr  tr  t ứ *) cho m i m c tham chi u.  Đ  làm vi c đó chúng ta ch  c n thêm m t d u sao (

ể ả s  r ng a,b,c đ ượ ư ở c l u các ô nh ớ 7230, 8092 and 10502, ta có th  mô t ạ  đo n mã ả ử ằ gi ư trên nh  sau:

ớ ể ụ ẽ ươ ứ ế c, chúng ta có th  nói v  nó theo 3 cách khác nhau,  ề ộ ể ỗ ớ ị Đi m m i trong ví d  này là bi n  m i cách s  t ng  ng v i m t giá tr  khác nhau:

c là một biến có kiểu (char **) mang giá trị 8092 *c là một biến có kiểu (char*) mang giá trị 7230 **c là một biến có kiểu (char) mang giá trị 'z'

Con tr  không ki u

ể ạ ữ ệ ệ ộ ặ ấ ủ

ị ử ể ể ả ỏ ỏ ớ ế ộ ể ộ ể ỏ ớ ấ ỏ ặ ạ ỏ t. Nó có th  tr  t Con tr  không ki u là m t lo i con tr  đ c bi i b t kì lo i d  li u  ế ự ạ ộ ớ ự ị ừ ữ i m t xâu kí t  giá tr  nguyên ho c th c cho t nào, t . H n ch  duy nh t c a nó là d   ộ ể ượ ự ế ế ớ ỏ ớ ệ ượ c tham chi u t li u đ i không th  đ c tr  t i m t cách tr c ti p (chúng ta không  ậ ủ ộ ớ ế ử ể  tham chi u * v i chúng) vì đ  dài c a nó là không xác đ nh và vì v y  th  dùng toán t ỏ ể ữ ệ chúng ta ph i dùng đ n toán t  chuy n ki u d  li u hay phép gán đ  chuy n con tr   không ki u thành m t con tr  tr  t ể ạ ữ ệ ụ ể i m t lo i d  li u c  th .

ủ ữ ệ ề ầ ố ỉ ộ M t trong nh ng ti n ích c a nó là cho phép truy n tham s  cho hàm mà không c n ch rõ ki u ể

6, 10, 13

// integer increaser #include

void increase (void* data, int type) { switch (type) {

case sizeof(char) : (*((char*)data))++; break; case sizeof(short): (*((short*)data))++; break; case sizeof(long) : (*((long*)data))++; break; } }

int main () { char a = 5; short b = 9; long c = 12; increase (&a,sizeof(a)); increase (&b,sizeof(b)); increase (&c,sizeof(c)); cout << (int) a << ", " << b << ", " << c; return 0; }

ả ề ộ ữ c tính ộ ủ ề ị ằ ụ sizeof(char) b ng ằ

1 vì kích th

ướ ướ ủ c c a ử ủ  c a ngôn ng  C++, nó tr  v  m t giá tr  h ng là kích th sizeof là m t toán t ố ằ b ng byte c a tham s  truy n cho nó, ví d   char là 1 byte.

Con tr  hàmỏ

ệ ờ ỏ ư ớ ố ế ệ ể ộ ộ ộ i ả ộ ộ ặ ủ ấ ộ   ề C++ cho phép thao tác v i các con tr  hàm. Ti n ích tuy t v i này cho phép truy n m t ỏ ỏ ớ hàm nh  là m t tham s  đ n m t hàm khác. Đ  có th  khai báo m t con tr  tr  t ả m t hàm chúng ta ph i khai báo nó nh  là khai báo m u c a m t hàm nh ng ph i bao  trong m t c p ngo c đ n ể ẫ ủ ư ặ ơ () tên c a hàm và chèn d u sao ( ộ ằ *) đ ng tr ư ướ    c.

8

// pointer to functions #include

int addition (int a, int b) { return (a+b); }

int subtraction (int a, int b) { return (a-b); }

int (*minus)(int,int) = subtraction;

int operation (int x, int y, int (*functocall)(int,int)) { int g; g = (*functocall)(x,y); return (g); }

int main () { int m,n; m = operation (7, 5, &addition); n = operation (20, m, minus); cout <

ụ ụ ỏ

minus là m t con tr  toàn c c tr  t ượ

int (* minus)(int,int) = subtraction;

ấ ả ề ộ Trong ví d  này,  int, con tr  này đ ộ ể ỏ ớ c gám đ  tr  t ỏ ớ ộ subtraction, t ỏ i hàm ố ể i m t hàm có hai tham s  ki u  t c  đ u trên m t dòng:

ớ ộ

ộ Bài 10 : B  Nh  Đ ng

ủ ươ ộ ớ

ng trình c a chúng ta, t ố ượ ổ ươ ể ờ ư ớ ộ ỡ ủ ng b  nh  mà kích c  c a nó ch  có th  đ ợ ậ ấ ả ữ ầ t c  nh ng ph n b  nh  chúng ta  ng khác mà chúng ta đã khai báo.  ạ ng trình ch y.  ể ượ c xác  ừ ỉ ng h p chúng ta nh n thông tin t ụ ư ộ ớ ầ ườ ị ế Cho đ n nay, trong các ch ể ử ụ ả ế có th  s  d ng là các bi n các m ng và các đ i t ỡ ủ ố ị Kích c  c a chúng là c  đ nh và không th  thay đ i trong th i gian ch ầ ế Nh ng n u chúng ta c n m t l ị đ nh khi ch ng ộ ượ ạ ươ ng trình ch y, ví d  nh  trong tr ượ ể ng b  nh  c n thi i dùng đ  xác đ nh l ườ ế t.

ở ợ ộ b  nh  đ ng ớ ộ , C++ đã tích h p hai toán t ử new và  delete đ  ể đây chính là  ệ i pháp  ệ ả Gi ự th c hi n vi c này

ủ ẽ  ph n sau c a bài chúng ta s Ở ầ ử ỉ ươ ươ ế ớ Hai toán t ữ bi ử new và delete ch  có trong C++.  ng đ ng v i các toán t t nh ng thao tác t này trong C.

pointer = new type

ể ớ ộ c b  nh  đ ng chúng ta có th  dùng toán t ể ặ t đ ử new. Theo sau toán t  ử   ặ c đ t trong c p ngo c ế ượ ặ ớ ừ ượ ấ ứ ạ c c p phát. D ng th c ử ử new và new[ ] Toán t ượ ộ ể ể Đ  có th  có đ ố ể ữ ệ ầ ử ầ này là tên ki u d  li u và có th  là s  ph n t  c n thi ả ề ộ ố ỏ ỏ ớ ầ ủ vuông. Nó tr  v  m t con tr  tr  t i đ u c a kh i nh  v a đ ư ủ  này nh  sau:  c a toán t

pointer = new type [elements]

ho c ặ

ượ ể ấ có ki u ể type. ượ ầ ử ộ c dùng đ  c p phát b  nh  ch a m t ph n t ồ ố ớ ứ ộ ớ ể ấ ộ ả ầ ử ể ộ c dùng đ  c p phát m t kh i nh  (m t m ng) g m các ph n t ki u

ứ ầ ể Bi u th c đ u tien đ ứ ệ L nh th  hai đ type. Ví d : ụ

int * bobby; bobby = new int [5];

ợ ệ ề ộ ớ ng h p này, h  đi u hành dành ch  cho 5 ph n t ỗ ớ ậ ố ộ ầ ử ể int trong b  nh  và   ki u  ố ỏ ế   bobby tr  đ n m t kh i ườ trong tr ầ ủ ả ề ộ tr  v  m t con tr  tr  đ n đ u c a kh i nh . Vì v y lúc này ớ ợ ệ ồ nh  h p l ỏ ỏ ế  g m 5 ph n t ầ ử int.

ệ ả ộ ớ ỏ ư ề ớ ả ể ỏ ộ ả ộ ằ ớ ạ i h n kích th ấ ả ộ ề ế ế ươ t k  ch ọ ộ ấ ạ ớ ớ ệ ấ ữ ạ B n có th  h i tôi là có gì khác nhau gi a vi c khai báo m t m ng v i vi c c p phát  ộ ừ kích th b  nh  cho m t con tr  nh  chúng ta v a làm. Đi u quan tr ng nh t là  ế ộ m t m ng ph i là m t h ng, đi u này gi ớ ộ mà chúng ta ch n khi thi phép c p phát b  nh  trong quá trình ch y v i kích th ọ cướ  c a ủ ướ ướ ủ c c a m ng đ n kích th c  ấ ng trình trong khi đó c p phát b  nh  đ ng cho  ướ ấ c b t kì.

int * bobby; bobby = new int [5]; if (bobby == NULL) { // error assigning memory. Take measures. };

ộ ượ ớ ộ ở ệ ề ườ ng đa ể ạ c qu n lí b i h  đi u hành và trong các môi tr ộ ể ả ả ộ ệ ớ ể ấ ớ ư ộ ậ ế ớ ả ề ầ ộ ể ả B  nh  đ ng nói chung đ ế ộ ươ nhi m có th  ch y m t lúc vài ch ng trình có m t kh  năng có th  x y ra là h t b   ể ấ ả ề ệ ề nh  đ  c p phát. N u đi u này x y ra và h  đi u hành không th  c p phát b  nh  nh ỏ ử new, m t con tr  null (zero) s  đ c tr  v . Vì v y các    chúng ta yêu c u v i toán t ỏ ả ề ở ạ b n nên ki m tra xem con tr  tr  v  b i toán t ẽ ượ ằ ử new có b ng null hay không:

ấ ị ỉ ầ ả ầ ộ ử delete. ớ ộ ế ữ ể ả ầ ứ ủ ể ự ư Toán t ế ộ Vì b  nh  đ ng ch  c n thi t trong m t kho ng th i gian nh t đ nh, khi nó không c n  ẽ ượ i phóng đ  có th  c p phát cho các nhu c u khác trong c gi dùng đ n n a thì nó s  đ ạ ệ ệ ươ t ng lai. Đ  th c hi n vi c này ta dùng toán t ử delete, d ng th c c a nó nh  sau: ờ ể ấ

delete pointer;

ho c ặ

delete [] pointer;

ớ ượ ấ ầ ộ c dùng đ  gi ố c c p phát cho m t ph n  ề ầ ử ể  và l nh th  hai dùng đ  gi ả  (m ng). ươ ứ ể ầ ặ ng m c dù chúng là rõ ràng ứ ầ ộ ượ ể ả Bi u th c đ u tiên nên đ i phóng b  nh  đ ể ả ứ ớ ồ ệ ử ộ i phóng m t kh i nh  g m nhi u ph n t t ươ ả ị ế ng đ Trong h u h t các trình d ch c  hai bi u th c là t ử  khác nhau.  là hai toán t

// rememb-o-matic #include #include

How many numbers do you want to type in? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, 8, 32,

int main () { char input [100]; int i,n; long * l, total = 0; cout << "How many numbers do you want to type in? "; cin.getline (input,100); i=atoi (input); l= new long[i]; if (l == NULL) exit (1); for (n=0; n

#define NULL 0

ể ể ỏ ị c đ nh nghĩa trong th  vi n C++ dùng đ  bi u th  con tr  null. ố ư ệ ạ ể ự ị ườ ợ ố ượ ị ộ ằ NULL là m t h ng s  đ ằ Trong tr ư ị ng h p h ng s  này ch a đ nh nghĩa b n có th  t đ nh nghĩa nó:

ư ể ỏ ấ ộ ề ế ể ệ ư ượ c khuy n khích đ  giúp cho ch c s  d ng r t r ng rãi và đi u này đ ỏ ớ NULL v i con tr   ươ ng trình Dùng 0 hay NULL khi ki m tra con tr  là nh  nhau nh ng vi c dùng  ượ ử ụ đ ễ ọ ơ d  đ c h n.

ộ ớ ộ

B  nh  đ ng trong ANSI­C

ộ ử new và delete là đ c quy n C++ và chúng không có trong ngôn ng  C. Trong ữ ữ ư ệ ả ử ụ ề ộ ể ợ ệ trong C++ và nó v n còn Toán t ể ử ụ ớ ộ ngôn ng  C, đ  có th  s  d ng b  nh  đ ng chúng ta ph i s  d ng th  vi n  ẫ ẽ stdlib.h. Chúng ta s  xem xét cách này vì nó cũng h p l ộ ố ươ ượ ử ụ đ c s  d ng trong m t s  ch ng trình.

ỏ ấ ớ ộ ể ấ ủ ổ ộ ộ

Hàm malloc ư Đây là m t hàm t ng quát đ  c p phát b  nh  đ ng cho con tr . C u trúc c a nó nh   sau:

void * malloc (size_t nbytes);

char * ronny; ronny = (char *) malloc (10);

ả ề ộ ố ỏ ể ủ ố ể ụ ể ậ ả ỏ ỏ trong đó nbytes là s  byte chúng ta mu n gán cho con tr . Hàm này tr  v  m t con tr   ổ ki u ể void*, vì v y chúng ta ph i chuy n đ i ki u sang ki u c a con tr  đích, ví d :

int * bobby; bobby = (int *) malloc (5 * sizeof(int));

ạ ộ ố ớ ố ả ộ ớ ầ ử ơ ậ ắ ố ấ ố ữ ệ  mong mu n v i kích th ử ộ ỏ ronny m t kh i nh  10 byte. Khi chúng ta mu n  Đo n mã này c p phát cho con tr   ố ể ấ c p phát m t kh i d  li u có ki u khác char (l n h n 1 byte) chúng ta ph i nhân s   ử ướ ủ c c a chúng. Th t may m n là chúng ta có toán t ph n t ể ữ ệ ụ ể ướ ủ sizeof, toán t ớ ả ề  này tr  v  kích th c c a m t ki u d  li u c  th .

ấ ố ố ỡ ủ ể int, kích c  c a ớ ồ bobby m t kh i nh  g m 5 s  nguyên ki u  ộ ệ ố ơ ươ ng trình ộ ạ Đo n mã này c p phát cho  ể ằ ể ữ ệ ki u d  li u này có th  b ng 2, 4 hay h n tùy thu c vào h  th ng mà ch ượ ị c d ch.  đ

ạ ộ ấ ố ẫ ủ ủ ế ự ớ malloc, s  khác nhau ch  y u là khai báo m u c a Hàm calloc. calloc ho t đ ng r t gi ng v i  nó:

void * calloc (size_t nelements, size_t size);

bobby v i ớ calloc nh  sau:

int * bobby; bobby = (int *) calloc (5, sizeof(int));

ố ử ụ ượ ố ớ ượ c nhân v i nhau đ  có đ c ướ ổ ố ộ ớ ầ ấ c t ng c ng c a kh i nh  c n c p phát. Thông th ố ứ và tham s  th c hai ( ể ố ầ ng tham s  đ u tiên  ỗ ướ ủ c c a m i ph n t ầ ử . ườ size) là kích th ư ụ nó s  d ng hai tham s  thay vì m t. Hai tham s  này đ ộ ủ kích th ầ ử ố (nelements) là s  ph n t ể ị Ví d , chúng ta có th  đ nh nghĩa

ữ ở ạ ấ ả ữ malloc và calloc là calloc kh i t o t t c  các ph n t ầ ử ề ể ộ M t đi m khác nhau n a gi a  ủ c a nó v  0.

ướ ủ ớ ượ ấ ỏ ộ Hàm realloc. ổ Nó thay đ i kích th ố c c a kh i nh  đã đ c c p phát cho m t con tr .

void * realloc (void * pointer, size_t size);

ớ ỏ ộ ị ộ ẽ ấ ỏ ộ ượ ấ c c a kh i nh  m i. Hàm này s  c p phát ộ ướ ủ ả ủ ể ố ố ổ ị ườ c ố c m i c a kh i nh , trong tr ớ ị ớ ớ ể ả ộ ị ấ ả ữ ệ ậ tham s  ố pointer nh n vào m t con tr  đã đ c c p phát b  nh  hay m t con tr  null,  ớ ớ ỉ ớ và size ch  đ nh kích th size byte b  nh   ể ủ ỗ ị ỏ ớ ể cho con tr . Nó có th  ph i thay đ i v  v  trí c a kh i nh  đ  có th  đ  ch  cho kích  ố ớ ượ ợ ớ ủ ướ ờ ủ ệ th ng h p này n i dung hi n th i c a kh i nh  đ ớ ố ỏ ớ ỏ ớ i kh i nh   i v  trí m i đ  đ m b o d  li u không b  m t. Con tr  m i tr  t copy t

ổ ớ c hàm tr  v . N u không th  thay đ i kích th ẽ ả ề c c a kh i nh  thì hàm s  tr  v   ổ ố ẽ ỏ ộ ị ể ả ề ế ượ đ ư ộ m t con tr  null nh ng tham s ướ ủ ủ ố pointer và n i dung c a nó s  không b  thay đ i.

ả ớ ộ ộ ượ ấ ố i phóng m t kh i nh  đ ng đã đ c c p phát b i ở malloc, calloc ho c ặ Hàm free. Hàm này gi realloc.

void free (void * pointer);

ỉ ượ ể ả ớ ượ ấ ộ c dùng đ  gi i phóng b  nh  đ ở c c p phát b i các hàm

malloc,

Hàm này ch  đ calloc and realloc.

Bài 11 : Các C u Trúc

ữ ệ

Các c u trúc d  li u.

ể ữ ệ ữ ệ ữ ượ ộ ạ c g p l i ộ ậ ạ ư ấ ộ ấ ợ ủ M t c u trúc d  li u là m t t p h p c a nh ng ki u d  li u khác nhau đ ứ ủ ộ ớ v i m t cái tên duy nh t. D ng th c c a nó nh  sau:

struct model_name { type1 element1; type2 element2; type3 element3; . . } object_name;

ủ ố ể ữ ệ ặ ố ượ ộ ọ ặ ng. Bên trong c p ngo c nh n là tên các ph n t ọ object_name  ầ ử ủ ấ  c a c u ẫ trong đó model_name là tên c a m u ki u d  li u và tham s  tùy ch n  ợ ệ m t tên h p l  cho đ i t ể ủ trúc và ki u c a chúng.

struct products { char name [30]; float price; } ;

products apple; products orange, melon;

ị ế ố ỳ ọ ố model_name (tu  ch n), tham s  này tr ở ủ ấ ể ợ ệ ươ ộ ụ N u đ nh nghĩa c a c u trúc bao g m tham s   ớ ấ thành m t tên ki u h p l ồ ươ ng đ t ng v i c u trúc. Ví d :

ị ườ ấ

products v i hai tr

name và price, m i tr

ng ng:  ủ ớ ử ụ ể ấ ể ộ ỗ ườ products) để ố ượ Chúng ta đã đ nh nghĩa c u trúc  có m t ki u khác nhau. Chúng ta cũng đã s  d ng tên c a ki u c u trúc ( khai báo ba đ i t

apple, orange và melon.

ể ng có ki u đó :

ợ ệ ố ể ơ ả ể ở ộ

products tr  thành m t tên ki u h p l

gi ng các ki u c  b n ượ c khai báo,  Sau khi đ nh  ư int, char hay short.

struct products { char name [30]; float price; } apple, orange, melon;

ườ ể ằ ở ố ủ ầ cu i c a ph n khai báo c u trúc dùng đ ụ ể ấ ố ượ ng có ki u c u trúc. Ví d , đ  khai báo các đ i t ng ể  apple, ố ượ ư ướ ở ỳ ọ object_name có th  n m  ng tu  ch n  Tr ự ế khai báo tr c ti p đ i t orange và melon nh  đã làm ể ấ ầ  ph n tr ể c chúng ta cũng có th  làm theo cách sau:

ơ ữ ỳ ọ ế ặ ở ố model_name tr  thành tu  ch n. M c dù n u ể ẽ ố ợ ng h p này tham s   ượ ử ụ c s  d ng thì chúng ta s  không th  khai báo thêm các đ i ể ẫ ườ H n n a, trong tr model_name không đ ượ t ng có ki u m u này.

ộ ầ

ẫ  c u trúc, đâu là  ể ể ki u m u ử ụ đ i ố ẫ ấ ớ ữ ế ế ề ng ấ ể ữ ệ ố ượ ệ ọ M t đi u quan tr ng là c n phân bi t rõ ràng đâu là  ượ c u trúc. N u dùng các thu t ng  chúng ta đã s  d ng v i các bi n, ki u m u  ậ t ế là tên ki u d  li u còn đ i t ng là các bi n.

apple, orange

apple.name apple.price orange.name orange.price melon.name melon.price

ẫ ấ ng có ki u là m t m u c u trúc xác đ nh ( ạ ị ể ệ ố ượ ườ ố ớ ấ ớ ấ ử ụ ể ế ộ ườ ng t o nên chúng. Đ  làm vi c này  ụ ở ữ  gi a tên đ i t ng. Ví d ,  ng và tên tr ư ủ ấ  nào c a c u trúc nh  là đ i v i các bi n ố ượ Sau khi đã khai báo ba đ i t ớ ể and melon) chúng ta có th  thao tác v i các tr ộ ấ .) chèn  chúng ta s  d ng m t d u ch m ( ầ ử chúng ta có th  thao tác v i b t kì ph n t chu n : ẩ

ỗ ườ ể ữ ệ ươ ứ

apple.name, orange.name và melon.name có

ng có ki u d  li u t ng  ng: m i tr ki u ể char[30], và apple.price, orange.price và melon.price có ki u ể float.

// example about structures #include #include #include

ạ ệ ụ ề ể ế ộ ộ ớ Chúng ta t m bi t apples, oranges và melons đ  đ n v i m t ví d  v  các b  phim:

Enter title: Alien Enter year: 1979 My favourite movie is: 2001 A Space Odyssey (1968) And yours: Alien (1979)

struct movies_t { char title [50]; int year; } mine, yours;

void printmovie (movies_t movie);

int main () { char buffer [50];

strcpy (mine.title, "2001 A Space Odyssey"); mine.year = 1968;

cout << "Enter title: "; cin.getline (yours.title,50); cout << "Enter year: "; cin.getline (buffer,50); yours.year = atoi (buffer);

cout << "My favourite movie is:\n "; printmovie (mine); cout << "And yours:\n "; printmovie (yours); return 0; }

void printmovie (movies_t movie) { cout << movie.title; cout << " (" << movie.year << ")\n"; }

ụ ầ ử ủ ườ ư ả ợ ệ ụ yours.year là m t bi n h p l có ki u ợ ệ ớ ử ụ ấ Ví d  này cho chúng ta th y cách s  d ng các ph n t ế ấ ng. Ví d ,  c u trúc nh  là các bi n thông th ả ộ int cũng nh  ư mine.title là m t m ng h p l ộ ấ  c a m t c u trúc và b n thân  ể ế ộ ầ ử ể chars.   ki u v i 50 ph n t

ế ả mine and yours đ u đ ợ ệ ể movie_t khi đ cượ ề ộ ợ

printmovie().H n n a m t l

ư ệ ặ ầ ử ủ ề ượ c coi là các bi n h p l ọ ế ơ ữ ộ  c a chúng m t cách riêng bi ki u  ủ ấ i th  quan tr ng c a c u trúc là chúng  ộ ấ t ho c toàn b  c u trúc nh  là ộ ằ Chú ý r ng c   truy n cho hàm  ể ta có th  xét các ph n t ố m t kh i.

// array of structures #include #include

#define N_MOVIES 5

struct movies_t { char title [50];

ơ ở ữ ệ ự ặ ấ ệ ế c s  d ng r t nhi u đ  xây d ng c  s  d  li u đ c bi t n u chúng ta ề ả ể ủ ả ấ ượ ử ụ Các c u trúc đ ự ế xét đ n kh  năng xây d ng các m ng c a chúng.

Enter title: Alien Enter year: 1979 Enter title: Blade Runner Enter year: 1982 Enter title: Matrix Enter year: 1999 Enter title: Rear Window Enter year: 1954

int year; } films [N_MOVIES];

void printmovie (movies_t movie);

Enter title: Taxi Driver Enter year: 1975 You have entered these movies: Alien (1979) Blade Runner (1982) Matrix (1999) Rear Window (1954) Taxi Driver (1975)

int main () { char buffer [50]; int n; for (n=0; n

void printmovie (movies_t movie) { cout << movie.title; cout << " (" << movie.year << ")\n"; }

ỏ ỏ ế ấ Con tr  tr  đ n c u trúc

struct movies_t { char title [50]; int year; };

movies_t amovie; movies_t * pmovie;

ấ ỏ ở c tr  đ n b i con tr . ể ượ ể ữ ệ ơ ả ể ữ ệ ố ư ấ ắ ỏ ế Nh  b t kì các ki u d  li u nào khác, các c u trúc có th  đ ư ố ớ ấ Quy t c hoàn toàn gi ng nh  đ i v i b t kì ki u d  li u c  b n nào:

// pointers to structures #include #include

ộ ể movies_t và pmovie là m t con tr  tr  t ụ ẽ ớ ẽ ế ớ ộ ố ượ amovie là m t đ i t ng có ki u  ộ ờ  chúng ta s  đ n v i m t ví d  khác, nó s  gi movies_t. OK, bây gi ỏ ỏ ớ ố   i đ i ệ i thi u đây Ở ượ t ng  ộ m t toán t ử ớ     m i:

Enter title: Matrix Enter year: 1999

You have entered: Matrix (1999)

struct movies_t { char title [50]; int year; };

int main () { char buffer[50];

movies_t amovie; movies_t * pmovie; pmovie = & amovie;

cout << "Enter title: "; cin.getline (pmovie->title,50); cout << "Enter year: "; cin.getline (buffer,50); pmovie->year = atoi (buffer);

cout << "\nYou have entered:\n"; cout << pmovie->title; cout << " (" << pmovie->year << ")\n";

return 0; }

movies->title

ộ ử ọ ộ ử ->. Đây là m t toán t tham ề ấ ớ ạ ế ả ớ i thi u m t đi u quan tr ng: toán t ể ỏ ớ ỗ ụ ế ế ộ i các c u trúc và các l p (class). Nó cho phép chúng ta không  ầ ử ủ ấ  c a c u trúc. Trong ví d  này ặ ử ụ ệ Đo n mã trên gi ỉ chi u ch  dùng đ  tr  t ph i dùng ngo c m i khi tham chi u đ n m t ph n t chúng ta s  d ng:

(*movies).title

ể ượ ị nó có th  đ c d ch thành:

*movies.title

ợ ệ ề và chúng đ u dùng ứ movies->title và (*movies).title đ u h p l ủ ấ ạ ầ ượ ề ỏ ở  movies. B n c n phân  c tr  b i ầ ử title c a c u trúc  đ ể ả c  hai bi u th c  ể ế ế đ  tham chi u đ n ph n t ớ ệ t rõ ràng v i:  bi

*(movies.title)

ươ ươ ớ nó t ng đ ng v i

ủ ấ ầ ử title c a c u trúc ỏ ở ộ ề ẳ c tr  b i ph n t ỏ ể ượ ườ ả ướ ế ấ ả ữ ấ ể ệ l nh này dùng đ  tính toán giá tr  đ trong tr B n d

movies,  ợ ng h p này (title không ph i là m t con tr ) nó ch ng có ý nghĩa gì nhi u.  ổ i đây t ng k t t

ị ượ ả ế ợ t c  các k t h p có th  đ ỏ c gi a con tr  và c u trúc:

ươ ươ ng đ ng ể ứ Bi u th c Mô tả T v iớ

ủ ấ

movies

ầ ử title c a c u trúc

(*movies).title

ủ ấ ượ ỏ ở c tr  b i ầ ử title c a c u trúc đ

movies.title Ph n t movies->title Ph n t movies

ỏ ở ủ ấ c tr  b i ph n t ầ ử title c a c u

*movies.title

*(movies.title)

ị ượ Giá tr  đ trúc movies

Các c u trúc l ng nhau

struct movies_t { char title [50]; int year; }

struct friends_t { char name [50]; char email [50]; movies_t favourite_movie; } charlie, maria;

friends_t * pfriends = &charlie;

ể ượ ặ ồ ậ ộ c đ t l ng nhau vì v y m t ph n t ầ ử ợ ệ ủ  h p l ộ ấ  c a m t c u trúc ấ ể Các c u trúc có th  đ ộ ấ có th  là m t c u trúc khác.

charlie.name maria.favourite_movie.title charlie.favourite_movie.year pfriends->favourite_movie.year

ể ử ụ ứ ể ậ ầ Vì v y, sau ph n khai báo trên chúng ta có th  s  d ng các bi u th c sau:

ứ ể ố ươ ươ (trong đó hai bi u th c cu i cùng là t ng đ ng).

ượ ề ậ ệ ữ ứ ộ ớ ư ộ ớ ạ ẽ ố   ầ ế ề ấ ơ ả c đ  c p đ n trong ph n này là hoàn toàn gi ng Các khái ni m c  b n v  c u trúc đ ấ ở ộ ượ ớ v i ngôn ng  C, tuy nhiên trong C++, c u trúc đã đ c m  r ng thêm các ch c năng  ấ ả ầ ử ủ ấ ặ ủ c a m t l p v i tính ch t đ c tr ng là t  c a nó đ u là công c ng  ế (public). B n s  có thêm các thông tin chi ti t c  các ph n t t trong ph n ề ầ   4.1, L pớ .

ữ ệ

ườ

Bài 12:Các Ki u D  Li u Do Ng

ị i Dùng Đ nh Nghĩa

ướ ườ ộ c đ nh nghĩa b i ng i dùng ể ữ ệ ự ị ư ề ấ Trong bài tr ườ ậ (ng ạ ữ ệ ượ ị c chúng ta đã xem xét m t lo i d  li u đ i l p trình): c u trúc. Nh ng có còn nhi u ki u d  li u t ở  đ nh nghĩa khác:

ự ị

T  đ nh nghĩa các ki u d  li u (

ể ữ ệ typedef).

ự ị ể ữ ệ ủ ẽ ử ụ ể ữ  ứ ừ ể ể ạ

typedef, d ng th c

khoá ệ ư C++ cho phép chúng ta đ nh nghĩa các ki u d  li u c a riêng mình d a trên các ki u d ệ li u đã có. Đ  có th  làm vi c đó chúng ta s  s  d ng t nh  sau:

typedef existing_type new_type_name ;

typedef char C; typedef unsigned int WORD; typedef char * string_t; typedef char field [50];

ể ữ ệ ấ ộ ộ ủ ớ ể ữ ệ ơ ả trong đó existing_type là m t ki u d  li u c  b n hay b t kì m t ki u d  li u đã  ể ữ ệ ị đ nh nghĩa và ụ new_type_name là tên c a ki u d  li u m i. Ví d

ợ ườ ể ữ ệ ố ị ng h p này chúng ta đã đ nh nghĩa b n ki u d  li u m i: ớ C, WORD, string_t

C achar, anotherchar, *ptchar1; WORD myword; string_t ptchar2; field name;

ể ữ ệ ư Trong tr và field ki u ể char, unsigned int, char* ki u ể char[50], chúng ta hoàn toàn có th  ể ợ ệ ử ụ s  d ng chúng nh  là các ki u d  li u h p l :

typedef có th  h u d ng khi b n mu n đ nh nghĩa m t ki u d  li u đ ặ ạ l p l ố mu n nó có tên ng n h n.

ể ữ ụ ể ữ ệ ượ ạ ố ị ể ữ ệ c dùng l p đi   ạ ộ ố ươ ặ ạ i trong ch ặ ng trình ho c ki u d  li u b n mu n dùng có tên quá dài và b n  ắ ơ

Union

ể ượ ề ộ c truy xu t d ộ ị ấ ướ ạ ộ ớ ề ằ ặ ớ t c  chúng đ u n m cùng m t v  trí trong b  nh . Ph n khai báo ự ớ ấ ử ụ ư ứ ầ ộ Union cho phép m t ph n b  nh  có th  đ ấ ả khác nhau m c dù t ươ ng t và s  d ng nó t ể ữ ệ   i d ng nhi u ki u d  li u ầ  v i c u trúc nh ng ch c năng thì khác hoàn toàn:

union model_name { type1 element1; type2 element2; type3 element3; . . } object_name;

union mytypes_t { char c; int i; float f; } mytypes;

ấ ả ộ ộ ớ ỗ ướ ủ c c a ầ ử ủ union đ u chi m cùng m t ch  trong b  nh . Kích th ụ ề ầ ử ớ ướ ủ T t c  các ph n t nó là kích th ế ấ  l n nh t. Ví d : c a  c c a ph n t

mytypes.c mytypes.i mytypes.f

ầ ử ị đ nh nghĩa ba ph n t

ể ữ ệ ư ộ ấ ả ộ ưở ộ ổ ớ ề ằ t c  chúng đ u n m cùng  ầ ử ẽ ả  s   nh h ng ầ ạ ỗ ầ ử  có m t ki u d  li u khác nhau. Nh ng vì t m i ph n t ố ớ ự ỗ ộ m t ch  trong b  nh  nên b t kì s  thay đ i nào đ i v i m t ph n t ớ ấ ả t i t ấ t c  các thành ph n còn l i.

union mix_t{ long l; struct { short hi; short lo; } s; char c[4]; } mix;

ể ữ ơ ả ữ ụ ớ   ủ union là dùng đ  k t h p m t ki u d  liêu c  b n v i ồ ầ ử ỏ ơ ộ ộ ụ ả M t trong nh ng công d ng c a  ấ m t m ng hay các c u trúc g m các ph n t ộ ể ế ợ  nh  h n. Ví d :

ầ ử ộ ấ ế  cho phép chúng ta truy xu t đ n cùng m t nhóm 4 byte:

mix.l,

ể ử ụ ố ỳ ệ ể ữ ệ ư ế ể ấ ể ạ ả ể ị đ nh nghĩa ba ph n t ấ ế   mix.s và mix.c mà chúng ta có th  s  d ng tu  theo vi c chúng ta mu n truy xu t đ n ấ ề nhóm 4 byte này nh  th  nào. Tôi dùng nhi u ki u d  li u khác nhau, m ng và c u  ấ trúc trong union đ  b n có th  th y các cách khác nhau mà chúng ta có th  truy xu t  ữ ệ d  li u.

Các unions vô danh

ặ ộ ộ ấ ế ặ ặ ể ử ụ ề ể ế ầ ấ ự ế ượ ụ ệ ầ c). Ví d , hãy xem xét s  khác bi c a nó mà không  ữ   t gi a ế ầ Trong C++ chúng ta có th  s  d ng các unions vô danh. N u chúng ta đ t m t union  ọ { })  union s  tr   ẽ ở trong m t c u trúc mà không đ  tên (ph n đi sau c p ngo c nh n  ầ ử ủ thành vô danh và chúng ta có th  truy xu t tr c ti p đ n các ph n t ự ủ ầ c n đ n tên c a union (có c n cũng không đ hai ph n khai báo sau đây:

struct { char title[50]; char author[50]; union { float dollars; int yens; } price; } book;

struct { char title[50]; char author[50]; union { float dollars; int yens; }; } book;

union union vô danh

book.price.dollars book.price.yens

ệ ự ữ ặ ạ ấ ầ t duy nh t gi a hai đo n mã này là trong đo n mã đ u tiên chúng ta đ t tên ầ ử ậ ứ ấ ạ ứ ợ ườ ế S  khác bi cho union (price) còn trong cái th  hai thì không. Khi truy nh p vào các ph n t dollars và yens, trong tr ng h p th  nh t chúng ta vi t:

book.dollars book.yens

ườ ứ ợ còn trong tr ng h p th  hai:

ộ i r ng vì nó là m t union, hai tr ng

dollars và yens đ u ề

ộ ầ ữ ế ắ ạ ằ ỗ ộ ớ ị ườ M t l n n a tôi nh c l ể ữ ộ chi m cùng m t ch  trong b  nh  nên chúng không th  gi hai giá tr  khác nhau.

ể Ki u li

t kê (

enum)

ệ ể ạ ệ t kê dùng đ  t o ra các ki u d  li u ch a m t cái gì đó h i đ c bi ể ố ể ả ể ữ ệ ự ặ ứ ằ ơ ặ ạ t  ứ ho c các h ng ộ true và false. D ng th c ư ể ữ ệ Ki u d  li u li ộ m t chút, không ph i ki u s  hay ki u kí t ủ c a nó nh  sau:

enum model_name { value1, value2, value3, . . } object_name;

ụ ể ữ ệ ớ ộ ể ư ữ

color đ  l u tr  các màu

ể ạ ư ầ Ví d , chúng ta có th  t o ra m t ki u d  li u m i có tên  ớ v i ph n khai báo nh  sau:

enum colors_t {black, blue, green, cyan, red, purple, yellow, white};

colors_t mycolor; mycolor = blue; if (mycolor == green) mycolor = red;

ằ ấ ộ ể ữ ệ ơ ả ớ ử ụ ộ ự ạ c vi ấ ể ữ ệ ượ ể color_t đ ể color_t, nh ng giá tr  có th  c a ki u  ị ữ ẽ ứ ể ể ủ ệ ụ ể ầ Chú ý r ng chúng ta không s  d ng b t kì m t ki u d  li u c  b n nào trong ph n  ể ữ khai báo. Chúng ta đã t o ra m t ki u d  li u m i mà không d a trên b t kì ki u d   ế ệ li u nào có s n: ki u  ợ ệ ặ ặ c p ngo c nh n ẵ ọ {}. Ví d , sau khi khai báo ki u li t kê, bi u th c sau s  là h p l t trong  :

ộ ố ki u d  li u li ị ủ ị ự ề ỉ ị ứ ế ị ế ớ ươ ở trên, ng ể ữ ệ colors_t mà chúng ta đ nh nghĩa  ươ

white t ứ ế ụ

ị ươ ươ ươ ớ ượ ị ệ ự ế ể ữ ệ c d ch là m t s  nguyên và các giá tr  c a nó là  t kê đ Trên th c t ế ượ ố ị ằ ỉ các h ng s  nguyên đ c ch  đ nh. N u đi u này không đ oc ch  đ nh, giá tr  nguyên  ầ ử ầ ươ ươ 0 và các giá tr  ti p theo c  th  tăng lên 1, Vì   đ u tiên là  ng v i ph n t ng đ t ươ ậ ng đ v y, trong ki u d  li u  ư ế    v i ớ 0, blue t ng v i 2 và c  ti p t c nh  th . ớ 1, green t ng v i ng đ ng đ

ỉ ế ể ữ ệ ủ ị ị t kê ộ ị ế ẽ ị

enum months_t { january=1, february, march, april, may, june, july, august, september, october, november, december} y2k;

ệ ị ộ N u chúng ta ch  đ nh m t giá tr  nguyên cho m t giá tr  nào đó c a ki u d  li u li ế ầ ử ầ ụ (trong ví d  này là ph n t  đ u tiên) các giá tr  ti p theo s  là các giá tr  nguyên ti p  theo, ví d : ụ

ng h p này, bi n ế y2k có ki u d  li u li ươ t kê  ươ ể ứ ị ệ ng đ ộ months_t có th  ch a m t  ng v i các giá tr  nguyên t ừ 1

1

ợ ể ữ ệ ườ trong tr ớ ị ừ january đ n ế december và t trong 12 giá tr  t đ n ế 12, không ph i ả 0 đ n ế 11 vì chúng ta đã đ t ặ january b ng ằ

ồ Ngu n internet