Toan tap C++
Bài 1 : C¥u Trúc Cça MÙt Ch°¡ng Trình C++
Có l½ mÙt trong nhïng cách tÑt nh¥t à b¯t §u hÍc mÙt ngôn ngï lp trình là b±ng mÙt ch°¡ng trình. Vy ây là ch°¡ng trình §u tiên cça chúng ta :
// my first program in C++
#include <iostream.h>
int main ()
{
cout << "Hello World!";
return 0;
} Hello World! Ch°¡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Á lp trình vi¿t §u tiên và k¿t qu£ cça nó là vi¿t câu "Hello, World" lên màn hình. ây là mÙt trong nhïng ch°¡ng trình ¡n gi£n nh¥t có thà vi¿t b±ng C++ nh°ng nó ã bao gÓm nhïng ph§n c¡ b£n mà mÍi ch°¡ng trình C++ có. Hãy cùng xem xét tëng dòng mÙt :
// my first program in C++
ây là dòng chú thích. T¥t c£ các dòng b¯t §u b±ng hai d¥u sÕ (//) °ãc coi là chút thích mà chúng không có b¥t kì mÙt £nh h°ßng nào ¿n ho¡t Ùng cça ch°¡ng trình. Chúng có thà °ãc các lp trình viên dùng à gi£i thích hay bình ph©m bên trong mã nguÓn cça ch°¡ng trình. Trong tr°Ýng hãp này, dòng chú thích là mÙt gi£i thích ng¯n gÍn nhïng gì mà ch°¡ng trình chúng ta làm.
#include <iostream.h>
Các câu b¯t §u b±ng d¥u (#) °ãc dùng cho preprocessor (ai dËch hÙ tôi të này vÛi). Chúng không ph£i là nhïng dòng mã thñc hiÇn nh°ng °ãc dùng à báo hiÇu cho trình dËch. Þ ây câu lÇnh #include <iostream.h> báo cho trình dËch bi¿t c§n ph£i "include" th° viÇn iostream. ây là mÙt th° viÇn vào ra c¡ b£n trong C++ và nó ph£i °ãc "include" vì nó s½ °ãc dùng trong ch°¡ng trình. ây là cách cÕ iÃn à sí dång th° viÇn iostream
int main ()
Dòng này t°¡ng éng vÛi ph§n b¯t §u khai báo hàm main. Hàm main là iÃm mà t¥t c£ các ch°¡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 này (ß §u, cuÑi hay ß giïa cça mã nguÓn) mà nÙi dung cça nó luôn °ãc thñc hiÇn §u tiên khi ch°¡ng trình b¯t §u. Thêm vào ó, do nguyên nhân nói trên, mÍi ch°¡ng 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
cout << "Hello World";
Dòng lÇnh này làm viÇc quan trÍng nh¥t cça ch°¡ng trình. cout là mÙt dòng (stream) output chu©n trong C++ °ãc Ënh ngh)a trong th° viÇn iostream và nhïng gì mà dòng lÇnh này làm là gíi chu×i kí tñ "Hello World" ra màn hình.
Chú ý r±ng dòng này k¿t thúc b±ng d¥u ch¥m ph©y ( ; ). Kí tñ này °ãc dùng à k¿t thúc mÙt lÇnh và b¯t buÙc ph£i có sau m×i lÇnh trong ch°¡ng trình C++ cça b¡n (mÙt trong nhïng l×i phÕ bi¿n nh¥t cça nhïng lp trình viên C++ là quên m¥t d¥u ch¥m ph©y).
return 0;
LÇnh 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 là mÙt k¿t thúc bình th°Ýng cça mÙt ch°¡ng trình không có mÙt l×i nào trong quá trình 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++.
Ch°¡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 nh°ng hoàn toàn không ph£i b¯t buÙc ph£i làm vy. Ví då, thay vì vi¿t
int main ()
{
cout << " Hello World ";
return 0;
}
ta có thà vi¿t
int main () { cout << " Hello World "; return 0; }
cing cho mÙt k¿t qu£ chính xác nh° nhau.
Trong C++, các dòng lÇnh °ãc phân cách b±ng d¥u ch¥m ph©y ( ;). ViÇc chia ch°¡ng 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.
Các chú thích °ãc các lp trình viên sí dång à ghi chú hay mô t£ trong các ph§n cça ch°¡ng trình. Trong C++ có hai cách à chú thích
// Chú thích theo dòng
/* Chú thích theo khÑi */
Chú thích theo dòng b¯t §u të c·p d¥u xÕ (//) cho ¿n cuÑi dòng. Chú thích theo khÑi b¯t §u b±ng /* và k¿t thúc b±ng */ và có thà bao gÓm nhiÁu dòng. Chúng ta s½ thêm các chú thích cho ch°¡ng trình :
/* my second program in C++
with more comments */
#include <iostream.h>
int main ()
{
cout << "Hello World! "; // says Hello World!
cout << "I'm a C++ program"; // says I'm a C++ program
return 0;
} Hello World! I'm a C++ program N¿u b¡n vi¿t các chú thích trong ch°¡ng trình mà không sí dång các d¥u //, /* hay */, trình dËch s½ coi chúng nh° là các lÇnh C++ và s½ hiÃn thË các l×i.
Bài 1 : C¥u Trúc Cça MÙt Ch°¡ng Trình C++
Có l½ mÙt trong nhïng cách tÑt nh¥t à b¯t §u hÍc mÙt ngôn ngï lp trình là b±ng mÙt ch°¡ng trình. Vy ây là ch°¡ng trình §u tiên cça chúng ta :
// my first program in C++
#include <iostream.h>
int main ()
{
cout << "Hello World!";
return 0;
} Hello World! Ch°¡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Á lp trình vi¿t §u tiên và k¿t qu£ cça nó là vi¿t câu "Hello, World" lên màn hình. ây là mÙt trong nhïng ch°¡ng trình ¡n gi£n nh¥t có thà vi¿t b±ng C++ nh°ng nó ã bao gÓm nhïng ph§n c¡ b£n mà mÍi ch°¡ng trình C++ có. Hãy cùng xem xét tëng dòng mÙt :
// my first program in C++
ây là dòng chú thích. T¥t c£ các dòng b¯t §u b±ng hai d¥u sÕ (//) °ãc coi là chút thích mà chúng không có b¥t kì mÙt £nh h°ßng nào ¿n ho¡t Ùng cça ch°¡ng trình. Chúng có thà °ãc các lp trình viên dùng à gi£i thích hay bình ph©m bên trong mã nguÓn cça ch°¡ng trình. Trong tr°Ýng hãp này, dòng chú thích là mÙt gi£i thích ng¯n gÍn nhïng gì mà ch°¡ng trình chúng ta làm.
#include <iostream.h>
Các câu b¯t §u b±ng d¥u (#) °ãc dùng cho preprocessor (ai dËch hÙ tôi të này vÛi). Chúng không ph£i là nhïng dòng mã thñc hiÇn nh°ng °ãc dùng à báo hiÇu cho trình dËch. Þ ây câu lÇnh #include <iostream.h> báo cho trình dËch bi¿t c§n ph£i "include" th° viÇn iostream. ây là mÙt th° viÇn vào ra c¡ b£n trong C++ và nó ph£i °ãc "include" vì nó s½ °ãc dùng trong ch°¡ng trình. ây là cách cÕ iÃn à sí dång th° viÇn iostream
int main ()
Dòng này t°¡ng éng vÛi ph§n b¯t §u khai báo hàm main. Hàm main là iÃm mà t¥t c£ các ch°¡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 này (ß §u, cuÑi hay ß giïa cça mã nguÓn) mà nÙi dung cça nó luôn °ãc thñc hiÇn §u tiên khi ch°¡ng trình b¯t §u. Thêm vào ó, do nguyên nhân nói trên, mÍi ch°¡ng 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
cout << "Hello World";
Dòng lÇnh này làm viÇc quan trÍng nh¥t cça ch°¡ng trình. cout là mÙt dòng (stream) output chu©n trong C++ °ãc Ënh ngh)a trong th° viÇn iostream và nhïng gì mà dòng lÇnh này làm là gíi chu×i kí tñ "Hello World" ra màn hình.
Chú ý r±ng dòng này k¿t thúc b±ng d¥u ch¥m ph©y ( ; ). Kí tñ này °ãc dùng à k¿t thúc mÙt lÇnh và b¯t buÙc ph£i có sau m×i lÇnh trong ch°¡ng trình C++ cça b¡n (mÙt trong nhïng l×i phÕ bi¿n nh¥t cça nhïng lp trình viên C++ là quên m¥t d¥u ch¥m ph©y).
return 0;
LÇnh 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 là mÙt k¿t thúc bình th°Ýng cça mÙt ch°¡ng trình không có mÙt l×i nào trong quá trình 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++.
Ch°¡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 nh°ng hoàn toàn không ph£i b¯t buÙc ph£i làm vy. Ví då, thay vì vi¿t
int main ()
{
cout << " Hello World ";
return 0;
}
ta có thà vi¿t
int main () { cout << " Hello World "; return 0; }
cing cho mÙt k¿t qu£ chính xác nh° nhau.
Trong C++, các dòng lÇnh °ãc phân cách b±ng d¥u ch¥m ph©y ( ;). ViÇc chia ch°¡ng 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.
Các chú thích °ãc các lp trình viên sí dång à ghi chú hay mô t£ trong các ph§n cça ch°¡ng trình. Trong C++ có hai cách à chú thích
// Chú thích theo dòng
/* Chú thích theo khÑi */
Chú thích theo dòng b¯t §u të c·p d¥u xÕ (//) cho ¿n cuÑi dòng. Chú thích theo khÑi b¯t §u b±ng /* và k¿t thúc b±ng */ và có thà bao gÓm nhiÁu dòng. Chúng ta s½ thêm các chú thích cho ch°¡ng trình :
/* my second program in C++
with more comments */
#include <iostream.h>
int main ()
{
cout << "Hello World! "; // says Hello World!
cout << "I'm a C++ program"; // says I'm a C++ program
return 0;
} Hello World! I'm a C++ program N¿u b¡n vi¿t các chú thích trong ch°¡ng trình mà không sí dång các d¥u //, /* hay */, trình dËch s½ coi chúng nh° là các lÇnh C++ và s½ hiÃn thË các l×i.
Bài 3 : Các Toán Tí
Qua bài tr°Ûc chúng ta ã bi¿t ¿n sñ tÓn t¡i cça các bi¿n và các h±ng. Trong C++, Ã thao tác vÛi chúng ta sí dång các toán tí, ó là các të khoá và các d¥u không có trong b£ng chï cái nh°ng l¡i có trên h§u h¿t các bàn phím trên th¿ giÛi. HiÃu bi¿t vÁ chúng 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++.
Toán tí gán (=).
Toán tí gán dùng à gán mÙt giá trË nào ó cho mÙt bi¿n
a = 5;
gán giá trË nguyên 5 cho bi¿n a. V¿ trái b¯t buÙc ph£i là mÙt bi¿n còn v¿ ph£i có thà là b¥t kì h±ng, bi¿n hay k¿t qu£ cça mÙt biÃu théc.
C§n ph£i nh¥n m¡nh r±ng toán tí gán luôn °ãc thñc hiÇn të trái sang ph£i và không bao giÝ £o ng°ãc
a = b;
gán giá trË cça bi¿n a b±ng giá trË ang chéa trong bi¿n b. Chú ý r±ng chúng ta chÉ gán giá trË cça b cho a và sñ thay Õi cça b sau ó s½ không £nh h°ßng ¿n giá trË cça a.
MÙt thuÙc tính cça toán tí gán trong C++ góp ph§n giúp nó v°ãt lên các ngôn ngï lp 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å:
a = 2 + (b = 5);
t°¡ng °¡ng vÛi
b = 5;
a = 2 + b;
Vì vy biÃu théc sau cing hãp lÇ trong C++
a = b = c = 5;
gán giá trË 5 cho c£ ba bi¿n a, b và c
Các toán tí sÑ hÍc ( +, -, *, /, % )
Nm toán tí sÑ hÍc °ãc h× trã bßi ngôn ngï là:
+ cÙng - trë * nhân / chia % l¥y ph§n d° (trong phép chia) Thé tñ thñc hiÇn các toán tí này cing giÑng nh° chúng °ãc thñc hiÇn trong toán hÍc. iÁu duy nh¥t có v» h¡i l¡ Ñi vÛi b¡n là phép l¥y ph§n d°, ký hiÇu b±ng d¥u ph§n trm (%). â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 a = 11 % 3;, bi¿n a s½ mang giá trË 2 vì 11 = 3*3 +2.
Các toán tí gán phéc hãp (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)
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í 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 trong nhïng toán tí c¡ b£n sau:
value += increase; t°¡ng °¡ng vÛi value = value + increase;
a -= 5; t°¡ng °¡ng vÛi a = a - 5;
a /= b; t°¡ng °¡ng vÛi a = a / b;
price *= units + 1; t°¡ng °¡ng vÛi price = price * (units + 1);
và t°¡ng tñ cho t¥t c£ các toán tí khác.
Tng và gi£m.
MÙt ví då khác cça viÇc ti¿t kiÇm khi vi¿t mã lÇnh là toán tí tng (++) và gi£m (--). Chúng tng ho·c gi£m giá trË chéa trong mÙt bi¿n i 1. Chúng t°¡ng °¡ng vÛi +=1 ho·c -=1. Vì vy, các dòng sau là t°¡ng °¡ng:
a++;
a+=1;
a=a+1;
MÙt tính ch¥t cça toán tí này là nó có thà là tiÁn tÑ ho·c hu tÑ, có ngh)a là có thà vi¿t tr°Ûc tên bi¿n (++a) ho·c sau (a++) và m·c dù trong hai biÃu théc r¥t ¡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 tng hay gi£m °ãc sí dång trong mÙt biÃu théc thì chúng có thà có mÙt khác biÇt quan trÍng vÁ ý ngh)a: Trong tr°Ýng hãp toán tí °ãc sí dång nh° là mÙt tiÁn tÑ (++a) giá trË °ãc tng tr°Ûc khi biÃu théc °ãc tính và giá trË ã tng °ãc sí dång trong biÃu théc; trong tr°Ýng hãp ng°ãc l¡i (a++) giá trË trong bi¿n a °ãc tng sau khi ã tính toán. Hãy chú ý sñ khác biÇt :
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Ç ( ==, !=, >, <, >=, <= )
à 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Ë true ho·c false, tuó theo biÃu théc k¿t 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å:
(7 == 5) s½ tr£ giá trË false
(6 >= 6) s½ tr£ giá trË true t¥t nhiên thay vì sí dång các sÑ, chúng ta có thà sí dång b¥t cé biÃu théc nào. Cho a=2, b=3 và c=6
(a*b >= c) s½ tr£ giá trË true. (b+4 < a*c) s½ tr£ giá trË false
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í gán ( gán giá trË cça biÃu théc bên ph£i cho bi¿n ß bên trái) và d¥u còn l¡i (==) là mÙt toán tí 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°Ûc chu©n ANSI-C++ cing nh° trong ngôn ngï C, các toán tí quan hÇ không tr£ vÁ giá trË logic true ho·c false mà tr£ vÁ giá trË int vÛi 0 t°¡ng éng vÛi false còn giá trË khác 0 (th°Ýng là 1) thì t°¡ng éng vÛi true.
Các toán tí logic ( !, &&, || ).
Toán tí ! t°¡ng °¡ng vÛi toán tí logic NOT, nó chÉ có mÙt Ñi sÑ ß phía bên ph£i và viÇc duy nh¥t mà nó làm là Õi ng°ãc giá trË cça Ñi sÑ të true sang false ho·c ng°ãc l¡i. Ví då:
!(5 == 5) tr£ vÁ false vì biÃu théc bên ph£i (5 == 5) có giá trËtrue. !(6 <= 4) tr£ vÁ true vì (6 <= 4)có giá trË false. !true tr£ vÁ false. !false tr£ vÁ true. Toán tí logic && và || °ãc sí dång khi tính toán hai biÃu théc à l¥y ra mÙt k¿t qu£ duy nh¥t. Chúng t°¡ng éng vÛi các toán tí logic AND và OR. K¿t qu£ cça chúng phå thuÙc vào mÑi quan hÇ cça hai Ñi sÑ:
Ñi sÑ thé nh¥t
a Ñi sÑ thé hai
b K¿t qu£
a && b K¿t qu£
a || b true true true true true false false true false true false true false false false false Ví då:
( (5 == 5) && (3 > 6) ) tr£ vÁ false ( true && false ).
( (5 == 5) || (3 > 6)) tr£ vÁ true ( true || false ).
Toán tí iÁu kiÇn ( ? ).
Toán tí 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 vào biÃu théc ó là úng hay sai. C¥u trúc cça nó nh° sau:
condition ? result1 : result2
N¿u condition là true thì giá trË tr£ vÁ s½ là result1, n¿u không giá trË tr£ vÁ là result2.
7==5 ? 4 : 3 tr£ vÁ 3 vì 7 không b±ng 5. 7==5+2 ? 4 : 3 tr£ vÁ 4 vì 7 b±ng 5+2. 5>3 ? a : b tr£ vÁ a, vì 5 lÛn h¡n 3. a>b ? a : b tr£ vÁ giá trË lÛn h¡n, a ho·c b.
Các toán tí thao tác bit ( &, |, ^, ~, <<, >> ).
Các toán tí thao tác bit thay Õi các bit biÃu diÅn mÙt bi¿n, có ngh)a là thay Õi 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 ~ NOT £o ng°ãc bit << SHL DËch bit sang trái >> SHR DËch bit sang ph£i
Các toán tí chuyÃn Õi kiÃu
Các toán tí chuyÃn Õi kiÃu cho phép b¡n chuyÃn Õi dï liÇu të kiÃu này sang kiÃu khác. Có vài cách à làm viÇc này trong C++, cách c¡ b£n nh¥t °ãc thëa k¿ të ngôn ngï C là ·t tr°Ûc biÃu théc c§n chuyÃn Õi tên kiÃu dï liÇu °ãc bÍc trong c·p ngo·c ¡n (), ví då:
int i;
float f = 3.14;
i = (int) f;
o¡n mã trên chuyÃn sÑ thp phân 3.14 sang mÙt sÑ nguyên (3). Þ ây, toán tí 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 thut ngï này °ãc dËch là c¥u tí nh°ng tôi th¥y nó có v» không xuôi tai l¯m) thay vì dùng các toán tí : ·t tr°Ûc biÃu théc c§n chuyÃn Õi kiÃu tên kiÃu mÛi và bao bÍc biÃu théc giïa mÙt c·p ngo·c ¡n.
i = int ( f );
C£ hai cách chuyÃn Õi kiÃu Áu hãp lÇ trong C++. Thêm vào ó ANSI-C++ còn có nhïng toán tí chuyÃn Õi kiÃu mÛi ·c tr°ng cho lp trình h°Ûng Ñi t°ãng.
sizeof()
Toán tí này có mÙt tham sÑ, ó có thà là mÙt kiÃu dï liÇu hay là mÙt bi¿n và tr£ vÁ kích cá b±ng byte cça kiÃu hay Ñi t°ãng ó.
a = sizeof (char);
a s½ mang giá trË 1 vì kiÃu char luôn có kích cá 1 byte trên mÍi hÇ thÑng. Giá trË tr£ vÁ cça sizeof là mÙt h±ng sÑ vì vy nó luôn luôn °ãc tính tr°Ûc khi ch°¡ng trình thñc hiÇn.
Các toán tí khác
Trong C++ còn có mÙt sÑ các toán tí khác, nh° các toán tí liên quan ¿n con trÏ hay lp trình h°Ûng Ñi t°ãng. Chúng s½ °ãc nói ¿n cå thà trong các ph§n t°¡ng éng.
Thé tñ °u tiên cça các toán tí
Khi vi¿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ñ hÏi toán h¡ng nào °ãc tính tr°Ûc, toán h¡ng nào °ãc tính sau. Ví då nh° trong biÃu théc sau:
a = 5 + 7 % 2
có thà có hai cách hiÃu sau:
a = 5 + (7 % 2) vÛi k¿t qu£ là 6, ho·c
a = (5 + 7) % 2 vÛi k¿t qu£ là 0
Câu tr£ lÝ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 lp mÙt thé tñ °u tiên giïa các toán tí, không chÉ riêng các toán tí sÑ hÍc mà t¥t c£ 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 b£ng sau theo thé tñ të cao xuÑng th¥p.
Thé tñ Toán tí Mô t£ Associativity 1 :: scope Trái 2 () [ ] -> . sizeof Trái 3 ++ -- tng/gi£m Ph£i ~ £o ng°ãc bit ! NOT & * Toán tí con trÏ (type) ChuyÃn Õi kiÃu + - D°¡ng ho·c âm 4 * / % Toán tí sÑ hÍc Trái 5 + - Toán tí sÑ hÍc Trái 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 Trái 11 ?: Toán tí iÁu kiÇn Ph£i 12 = += -= *= /= %=
>>= <<= &= ^= |= Toán tí gán Ph£i 13 , D¥u ph©y Trái Associativity Ënh ngh)a trong tr°Ýng hãp có mÙt vài toán tí có cùng thé tñ °u tiên thì cái nào s½ °ãc tính tr°Ûc, toán tí ß phía xa nh¥t bên ph£i hay là xa nh¥t bên trái.
N¿u b¡n muÑn vi¿t mÙt biÃu théc phéc t¡p mà l¡i không ch¯c l¯m vÁ thé tñ °u tiên cça các toán tí thì nên sí dång các ngo·c ¡n. Các b¡n nên thñc hiÇn iÁu này vì nó s½ giúp ch°¡ng trình dÅ Íc h¡n.
Bài 4 : Các C¥u Trúc iÁu KhiÃn
MÙt ch°¡ng trình th°Ýng không chÉ bao gÓm các lÇnh tu§n tñ nÑi ti¿p nhau. Trong quá trình ch¡y nó có thà r½ nhánh hay l·p l¡i mÙt o¡n mã nào ó. à làm iÁu này chúng ta sí dång các c¥u trúc iÁu khiÃn.
Cùng vÛi viÇc giÛi thiÇu các c¥u trúc iÁu khiÃn chúng ta cing s½ ph£i bi¿t tÛi mÙt khái niÇm mÛi: khÑi lÇnh, ó là mÙt nhóm các lÇnh °ãc ngn cách bßi d¥u ch¥m ph©y (;) nh°ng °ãc gÙp trong mÙt khÑi giÛi h¡n bßi mÙt c·p ngo·c nhÍn: { và }.
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¥u trúc này °ãc dùng khi mÙt lÇnh hay mÙt khÑi lÇnh chÉ °ãc thñc hiÇn khi mÙt iÁu kiÇn nào ó tho£ mãn. D¡ng cça nó nh° sau:
if (condition) statement
trong ó condition là biÃu théc s½ °ãc tính toán. N¿u iÁu kiÇn ó là true, statement °ãc thñc hiÇn. N¿u không statement bË bÏ qua (không thñc hiÇn) và 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.
Ví då, o¡n mã sau ây s½ vi¿t x is 100 chÉ khi bi¿n x chéa giá trË 100:
if (x == 100)
cout << "x is 100";
N¿u chúng ta muÑn có h¡n mÙt lÇnh °ãc thñc hiÇn trong tr°Ýng hãp condition là true chúng ta có thà chÉ Ënh mÙt khÑi lÇnh b±ng cách sí dång mÙt c·p ngo·c nhÍn { }:
if (x == 100)
{
cout << "x is ";
cout << x;
}
Chúng ta cing có thà chÉ Ënh iÁu gì s½ x£y ra n¿u iÁu kiÇn không °ãc tho£ mãn b±ng cách síu dång të khoá else. Nó °ãc sí dång cùng vÛi if nh° sau:
if (condition) statement1 else statement2
Ví då:
if (x == 100)
cout << "x is 100";
else
cout << "x is not 100";
C¥u trúc if + else có thà °ãc móc nÑi à kiÃm tra nhiÁu giá trË. Ví då sau ây s½ kiÃm tra xem giá trË chéa trong bi¿n x là d°¡ng, âm hay b±ng không.
if (x > 0)
cout << "x is positive";
else if (x < 0)
cout << "x is negative";
else
cout << "x is 0";
Các c¥u trúc l·p
Måc ích cça các vòng l·p là l·p l¡i mÙt thao tác vÛi mÙt sÑ l§n nh¥t Ënh ho·c trong 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
và chéc nng cça nó ¡n gi£n chÉ là l·p l¡i statement khi iÁu kiÇn 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:
// custom countdown using while
#include <iostream.h>
int main ()
{
int n;
cout << "Enter the starting number > ";
cin >> n;
while (n>0) {
cout << n << ", ";
--n;
}
cout << "FIRE!";
return 0;
} Enter the starting number > 8
8, 7, 6, 5, 4, 3, 2, 1, FIRE! Khi ch°¡ng trình ch¡y ng°Ýi sí dång °ãc yêu c§u nhp vào mÙt sÑ Ã ¿m ng°ãc. Sau ó, khi vòng l·p while b¯t §u n¿u sÑ mà ng°Ýi dùng nhp vào tho£ mãn iÁu kiÇn iÁu kiÇn n>0 khÑi lÇnh s½ °ãc thñc hiÇn mÙt sÑ l§n không xác Ënh chëng nào iÁu kiÇn (n>0) còn °ãc tho£ mãn.
Chúng ta c§n ph£i nhÛ r±ng vòng l·p ph£i k¿t thúc ß mÙt iÃm nào ó, vì vy bên trong vòng l·p chúng ta ph£i cung c¥p mÙt ph°¡ng théc nào ó Ã buÙc condition trß thành sai n¿u không thì nó s½ l·p l¡i mãi mãi. Trong ví då trên vòng l·p ph£i có lÇnh --n; Ã làm cho condition trß 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);
Chéc nng cça nó là hoàn toàn giÑng vòng l·p while chÉ trë có mÙt iÁu là iÁu kiÇn iÁu khiÃn vòng l·p °ãc tính toán sau khi statement °ãc thñc hiÇn, vì vy statement s½ °ãc thñc hiÇn ít nh¥t mÙt l§n ngay c£ khi condition không bao giÝ °ãc tho£ mãn. Ví då, ch°¡ng trình d°Ûi ây s½ vi¿t ra b¥t kì sÑ nào mà b¡n nhp vào cho ¿n khi b¡n nhp sÑ 0.
// number echoer
#include <iostream.h>
int main ()
{
unsigned long n;
do {
cout << "Enter number (0 to end): ";
cin >> n;
cout << "You entered: " << n << "
";
} while (n != 0);
return 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 Vòng l·p do-while th°Ýng °ãc dùng khi iÁu kiÇn à k¿t thúc vòng l·p n±m trong vòng l·p, nh° trong ví då trên, sÑ mà ng°Ýi dùng nhp vào là iÁu kiÇn kiÃm tra à k¿t thúc vòng l·p. N¿u b¡n không nhp 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;
và chéc nng chính cça nó là l·p l¡i statement chëng nào condition còn mang giá trË úng, nh° trong vòng l·p while. Nh°ng thêm vào ó, for cung c¥p ch× dành cho lÇnh khßi t¡o và lÇnh tng. Vì vy vòng l·p này °ãc thi¿t k¿ ·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:
1, initialization °ãc thñc hiÇn. Nói chung nó ·t mÙt giá khí ban §u cho bi¿n iÁu khiÃn. LÇnh này °ãc thñc hiÇn chÉ mÙt l§n.
2, condition °ãc kiÃm tra, n¿u nó là úng vòng l·p ti¿p tåc còn n¿u không vòng l·p k¿t thúc và statement °ãc bÏ qua.
3, statement °ãc thñc hiÇn. Nó có thà là mÙt lÇnh ¡n ho·c là mÙt khÑi lÇnh °ãc bao trong mÙt c·p ngo·c nhÍn.
4, CuÑi cùng, increase °ãc thñc hiÇn à tng bi¿n iÁu khiÃn và vòng l·p quay trß l¡i b°Ûc 2.
Sau ây là mÙt ví då ¿m ng°ãc sí dång vòng for.
// countdown using a for loop
#include <iostream.h>
int main ()
{
for (int n=10; n>0; n--) {
cout << n << ", ";
}
cout << "FIRE!";
return 0;
} 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE! Ph§n khßi t¡o và lÇnh tng 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 ngn cách giïa các ph§n. Vì vy, chúng ta có thà vi¿t for (;n<10;) ho·c for (;n<10;n++).
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°Ýng nào trong vòng for, nh° là trong ph§n khßi t¡o. Ví då chúng ta có thà khßi t¡o mÙt lúc nhiÁu bi¿n trong vòng l·p:
for ( n=0, i=100 ; n!=i ; n++, i-- )
{
// cái gì ß ây cing °ãc...
}
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:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgloop1.gif" \* MERGEFORMATINET
Các lÇnh r½ nhánh và lÇnh nh£y
LÇnh break.
Sí dång break chúng ta có thà thoát khÏi vòng l·p ngay c£ khi iÁu kiÇn à nó k¿t thúc ch°a °ãc tho£ mãn. LÇnh này có thà °ãc dùng à k¿t thúc mÙt 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°ãc tr°Ûc khi nó k¿t thúc:
// break loop example
#include <iostream.h>
int main ()
{
int n;
for (n=10; n>0; n--) {
cout << n << ", ";
if (n==3)
{
cout << "countdown aborted!";
break;
}
}
return 0;
} 10, 9, 8, 7, 6, 5, 4, countdown aborted! LÇnh continue.
LÇnh continue làm cho ch°¡ng trình bÏ qua ph§n còn l¡i cça vòng l·p và nh£y sang l§n l·p ti¿p theo. Ví då chúng ta s½ bÏ qua sÑ 5 trong ph§n ¿m ng°ãc:
// break loop example
#include <iostream.h>
int main ()
{
for (int n=10; n>0; n--) {
if (n==5) continue;
cout << n << ", ";
}
cout << "FIRE!";
return 0;
} 10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE! LÇnh goto.
LÇnh này cho phép nh£y vô iÁu kiÇn tÛi b¥t kì iÃm nào trong ch°¡ng trình. Nói chung b¡n nên tránh dùng nó trong ch°¡ng trình C++. Tuy nhiên chúng ta v«n có mÙt ví då dùng lÇnh goto à ¿m ng°ãc:
// goto loop example
#include <iostream.h>
int main ()
{
int n=10;
loop: ;
cout << n << ", ";
n--;
if (n>0) goto loop;
cout << "FIRE!";
return 0;
} 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE! Hàm exit.
Måc ích cça exit là k¿t thúc ch°¡ng trình và tr£ vÁ mÙt mã xác Ënh. D¡ng théc cça nó nh° sau
void exit (int exit code);
exit code °ãc dùng bßi mÙt sÑ hÇ iÁu hành ho·c có thà °ãc dùng bßi các ch°¡ng trình gÍi. Theo quy °Ûc, mã tr£ vÁ 0 có ngh)a là ch°¡ng trình k¿t thúc bình th°Ý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.
Cú pháp cça lÇnh switch h¡i ·c biÇt mÙt chút. Måc ích cça nó là kiÃm tra mÙt vài giá trË h±ng cho mÙt biÃu théc, t°¡ng tñ vÛi nhïng gì chúng ta làm ß §u bài này khi 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
}
Nó ho¡t Ùng theo cách sau: switch tính biÃu théc và kiÃm tra xem nó có b±ng constant1 hay không, n¿u úng thì nó thñc hiÇn block of instructions 1 cho ¿n khi tìm th¥y të khoá break, sau ó nh£y ¿n ph§n cuÑi cça c¥u trúc lña chÍn switch.
Còn n¿u không, switch s½ kiÃm tra xem biÃu théc có b±ng constant2 hay không. N¿u úng nó s½ thñc hiÇn block of instructions 2 cho ¿n khi tìm th¥y të khoá break.
CuÑi cùng, n¿u giá trË biÃu théc không b±ng b¥t kì h±ng nào °ãc chÉ Ënh ß trên (b¡n có thà chÉ Ënh bao nhiêu câu lÇnh case tuó thích), ch°¡ng trình s½ thñc hiÇn các lÇnh trong ph§n default: n¿u nó tÓn t¡i vì ph§n này không b¯t buÙc ph£i có.
Hai o¡n mã sau là t°¡ng °¡ng:
ví då switch if-else t°¡ng °¡ng switch (x) {
case 1:
cout << "x is 1";
break;
case 2:
cout << "x is 2";
break;
default:
cout << "value of x unknown";
} if (x == 1) {
cout << "x is 1";
}
else if (x == 2) {
cout << "x is 2";
}
else {
cout << "value of x unknown";
} Tôi ã nói ß trên r±ng c¥u trúc cça lÇnh switch h¡i ·c biÇt. Chú ý sñ tÓn t¡i cça lÇnh break ß cuÑi m×i khÑi lÇnh. iÁu này là c§n thi¿t vì n¿u không thì sau khi thñc hiÇn block of instructions 1 ch°¡ng trình s½ không nh£y ¿n cuÑi cça lÇnh switch mà s½ thñc hiÇn các khÑi lÇnh ti¿p theo cho ¿n khi nó tìm th¥y lÇnh break §u tiên. iÁu này khi¿n cho viÇc ·t c·p ngo·c nhÍn { } trong m×i tr°Ýng hãp là không c§n thi¿t và có thà °ãc dùng khi b¡n muÑn thñc hiÇn mÙt khÑi lÇnh cho nhiÁu tr°Ýng hãp khác nhau, ví då:
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";
} Chú ý r±ng lÇnh switch chÉ có thà °ãc dùng à so sánh mÙt biÃu théc vÛi các h±ng. Vì vy chúng ta không thà ·t các bi¿n (case (n*2):) hay các kho£ng (case (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)
Hàm là mÙt khÑi lÇnh °ãc thñc hiÇn khi nó °ãc gÍi të mÙt iÃm khác cça ch°¡ng trình. D¡ng théc cça nó nh° sau:
type name ( argument1, argument2, ...) statement
trong ó:
type là kiÃu dï liÇu °ãc tr£ vÁ cça hàm
name là tên gÍi cça hàm.
arguments là các tham sÑ (có nhiÁu bao nhiêu cing °ãc tuó theo nhu c§u). MÙt tham 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 gÍi. Các tham sÑ khác nhau °ãc ngn cách bßi 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:
// function example
#include <iostream.h>
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;
} The result is 8 à có thà hiÃu °ãc o¡n mã này, tr°Ûc h¿t hãy nhÛ l¡i nhïng iÁu ã nói ß bài §u tiên: mÙt ch°¡ng trình C++ luôn b¯t §u thñc hiÇn të hàm main. Vì vy chúng ta b¯t §u të ây.
Chúng ta có thà th¥y hàm main b¯t §u b±ng viÇc khai báo bi¿n z kiÃu int. Ngay sau ó là mÙt lÝi gÍi tÛi hàm addition. N¿u à ý chúng ta s½ th¥y sñ t°¡ng tñ giïa c¥u trúc cça lÝi gÍi hàm vÛi khai báo cça hàm:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgfunc1.gif" \* MERGEFORMATINET
Các tham sÑ có vai trò tht rõ ràng. Bên trong hàm main chúng ta gÍi hàm addition và truyÁn hai giá trË: 5 và 3 t°¡ng éng vÛi hai tham sÑ int a và int b °ãc khai báo cho hàm addition.
Vào thÝi iÃm hàm °ãc gÍi të main, quyÁn iÁu khiÃn °ãc chuyÃn sang cho hàm addition. Giá trË cça c hai tham sÑ (5 và 3) °ãc copy sang hai bi¿n cåc bÙ int a và int b bên trong hàm.
Dòng lÇnh sau:
return (r);
k¿t thúc hàm addition, và tr£ l¡i quyÁn iÁu khiÃn cho hàm nào ã gÍi nó (main) và ti¿p tåc ch°¡ng trình ß cái iÃm mà nó bË ng¯t bßi lÝi gÍi ¿n addition. Nh°ng thêm 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.\
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgfunc2.gif" \* MERGEFORMATINET
Giá trË tr£ vÁ bßi mÙt hàm chính là giá trË cça hàm khi nó °ãc tính toán. Vì vy bi¿n z s½ có có giá trË °ãc tr£ vÁ bßi addition (5, 3), ó là 8.
Ph¡m vi ho¡t Ùng cça các bi¿n [nh¯c l¡i]
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°¡ng trình ví då trên, b¡n không thà sí dång trñc ti¿p các bi¿n a, b hay r trong hàm main vì chúng là các bi¿n cåc bÙ cça hàm addition. Thêm vào ó b¡n cing không thà sí dång bi¿n z trñc ti¿p bên trong hàm addition vì nó làm bi¿n cåc bÙ cça hàm main.
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¥t kì âu, 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:
// function example
#include <iostream.h>
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 << '
';
cout << "The second result is " << subtraction (7,2) << '
';
cout << "The third result is " << subtraction (x,y) << '
';
z= 4 + subtraction (x,y);
cout << "The fourth result is " << z << '
';
return 0;
} The first result is 5
The second result is 5
The third result is 2
The fourth result is 6 Trong tr°Ýng hãp này chúng ta t¡o ra hàm subtraction. Chéc nng cça hàm này là 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 main các b¡n s½ th¥y ch°¡ng trình ã vài l§n gÍi ¿n 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.
à có hiÃu c·n k½ ví då này b¡n c§n nhÛ r±ng mÙt lÝi gÍi ¿n mÙt hàm có thà hoàn 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° vy
cout << "The second result is " << subtraction (7,2);
cing cho k¿t qu£ giÑng nh° hai dòng lÇnh trên nh°ng trong tr°Ýng hãp này chúng ta gÍi hàm subtraction trñc ti¿p nh° là mÙt tham sÑ cça cout. Chúng ta cing có thà vi¿t:
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);
iÁu mÛi m» duy nh¥t ß ây là các tham sÑ cça subtraction là các bi¿n thay vì các h±ng. iÁu này là hoàn toàn hãp lÇ. Trong tr°Ýng hãp này giá trË °ãc truyÁn cho hàm subtraction là giá trË cça x and y.
Tr°Ýng hãp thé t° cing 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;
cing hoàn toàn cho k¿t qu£ t°¡ng °¡ng. Chú ý r±ng d¥u ch¥m ph©y °ãc ·t ß cuÑi biÃu théc ché không c§n thi¿t ph£i ·t ngay sau lÝ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
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½ °ãc hàm 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 ?
Hãy t°ßng 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 cing không c§n nhn tham sÑ nào h¿t. Vì vy ng°Ýi ta ã ngh) ra kiÃu dï liÇu void trong ngôn ngï C. Hãy xem xét ch°¡ng trình sau:
// void function example
#include <iostream.h>
void dummyfunction (void)
{
cout << "I'm a function!";
}
int main ()
{
dummyfunction ();
return 0;
} I'm a function! Të khoá void trong ph§n danh sách tham sÑ có ngh)a là hàm này không nhn mÙt tham sÑ nào. Tuy nhiên trong C++ không c§n thi¿t ph£i sí dång void à làm iÁu này. B¡n chÉ ¡n gi£n sí dång c·p ngo·c ¡n ( ) là xong.
Bßi vì hàm cça chúng ta không có mÙt tham sÑ nào, vì vy lÝi gÍi hàm dummyfunction 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">
Hai d¥u ngo·c ¡n là c§n thi¿t à cho trình dËch hiÃu ó là mÙt lÝi gÍi hàm ché 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)
TruyÁn tham sÑ theo tham sÑ giá trË hay tham sÑ bi¿n.
Cho ¿n nay, trong t¥t c£ các hàm chúng ta ã bi¿t, t¥t c£ các tham sÑ truyÁn cho hàm Áu °ãc truyÁn theo giá trË. iÁu này có ngh)a là khi chúng ta gÍi hàm vÛi các tham sÑ, nhïng gì chúng ta truyÁn cho hàm là các giá trË ché không ph£i b£n thân các bi¿n. Ví då, gi£ sí chúng ta gÍi hàm addition nh° sau:
int x=5, y=3, z;
z = addition ( x , y );
Trong tr°Ýng hãp này khi chúng ta gÍi hàm addition thì các giá trË 5 and 3 °ãc truyÁn cho hàm, không ph£i là b£n thân các bi¿n.
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgfunc3.gif" \* MERGEFORMATINET
¿n ây các b¡n có thà hÏi tôi: Nh° vy thì sao, có £nh h°ß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 và y v«n không thay Õi vì chúng âu có °ãc truyÁn cho hàm chÉ có giá trË cça chúng °ãc truyÁn mà thôi.
Hãy xét tr°Ýng hãp b¡n c§n thao tác vÛi mÙt bi¿n ngoài ß bên trong mÙt hàm. Vì vy b¡n s½ ph£i truyÁn tham sÑ d°Ûi d¡ng tham sÑ bi¿n nh° ß trong hàm duplicate trong ví då d°Ûi ây:
// passing parameters by reference
#include <iostream.h>
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;
} x=2, y=6, z=14 iÁu §u tiên làm b¡n chú ý là trong khai báo cça duplicate theo sau tên kiÃu cça m×i tham sÑ Áu là d¥u và (&), Ã báo hiÇu r±ng các tham sÑ này °ãc truyÁn theo tham sÑ bi¿n ché không ph£i tham sÑ giá trË.
Khi truyÁn tham sÑ d°Ûi d¡ng tham sÑ bi¿n chúng ta ang truyÁn b£n thân bi¿n ó và 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 ó.
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgfunc4.gif" \* MERGEFORMATINET
Trong ví då trên, chúng ta ã liên k¿t a, b và c vÛi các tham sÑ khi gÍi hàm (x, y và z) và mÍi sñ thay Õi vÛi a bên trong hàm s½ £nh h°ßng ¿n giá trË cça x và hoàn toàn t°¡ng tñ vÛi b và y, c và z.
KiÃu khai báo tham sÑ theo d¡ng tham sÑ bi¿n sí dång d¥u và (&) chÉ có trong C++. Trong ngôn ngï C chúng ta ph£i sí dång con trÏ Ã làm viÇc t°¡ng tñ nh° th¿. TruyÁn tham sÑ d°Ûi d¡ng tham sÑ bi¿n cho phép mÙt hàm tr£ vÁ nhiÁu h¡n mÙt giá 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.
// more than one returning value
#include <iostream.h>
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;
} Previous=99, Next=101 Giá trË m·c Ënh cça tham sÑ.
Khi Ënh ngh)a mÙt hàm chúng ta có thà chÉ Ënh nhïng giá trË m·c Ënh s½ °ãc truyÁn cho các Ñi sÑ trong tr°Ýng hãp chúng bË bÏ qua khi hàm °ãc gÍi. à làm 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å:
// default values in functions
#include <iostream.h>
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;
} 6
5 Nh°ng chúng ta th¥y trong thân ch°¡ng trình, có hai lÝi gÍi hàm divide. Trong lÇnh §u tiên:
divide (12)
chúng ta chÉ dùng mÙt tham sÑ nh°ng hàm divide cho phép ¿n hai. Bßi vy hàm divide s½ tñ cho tham sÑ thé hai giá trË b±ng 2 vì ó là giá trË m·c Ënh cça nó (chú ý ph§n khai báo hàm °ãc k¿t thúc bßi int b=2). Vì vy k¿t qu£ s½ là 6 (12/2).
Trong lÇnh thé hai:
divide (20,4)
có hai tham sÑ, bßi vy giá trË m·c Ënh s½ °ãc bÏ qua. K¿t qu£ cça hàm s½ là 5 (20/4).
Quá t£i các hàm.
Hai hàm có thà có cing 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 thm chí là kiÃu dï liÇu tr£ vÁ khác nhau). Ví då:
// overloaded function
#include <iostream.h>
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 << "
";
cout << divide (n,m);
return 0;
} 2
2.5 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 sÑ kiÃu int và hàm còn l¡i dùng kiÃu float. Trình biên dËch s½ bi¿t c§n ph£i gÍi hàm nào b±ng cách phân tích kiÃu tham sÑ khi hàm °ãc gÍi.
à ¡n gi£n tôi vi¿t c£ hai hàm Áu có mã lÇnh nh° nhau nh°ng iÁu này không b¯t 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.
ChÉ thË inline có thà °ãc ·t tr°Ûc khao báo cça mÙt hàm à chÉ rõ r±ng lÝi gÍi hàm s½ °ãc thay th¿ b±ng mã lÇnh cça hàm khi ch°¡ng trình °ãc dËch. ViÇc này t°¡ng °¡ng vÛi viÇc khai báo mÙt macro, lãi ích cça nó chÉ thà hiÇn vÛi các hàm r¥t ng¯n, tÑc Ù ch¡y ch°¡ng trình s½ °ãc c£i thiÇn vì nó không ph£i gÍi mÙt thç tåc con.
C¥u trúc cça nó nh° sau:
inline type name ( arguments ... ) { instructions ... }
lÝi gÍi hàm cing nh° b¥t kì mÙt hàm nào khác. Không c§n thi¿t ph£i ·t të khoá inline trong lÇnh gÍi, chÉ c§n trong lÝi khai báo hàm là ç.
Ç qui.
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Ñ ph°¡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 sÑ (n), công théc toán hÍc cça nó nh° sau:
n! = n * (n-1) * (n-2) * (n-3) ... * 1
và mÙt hàm Ç qui à tính toán s½ nh° sau:
// factorial calculator
#include <iostream.h>
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;
} Type a number: 9
!9 = 362880 Chú ý trong hàm factorial chúng ta có thà lÇnh gÍi chính nó nh°ng chÉ khi tham sÑ lÛn h¡n 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½ ti¿p tåc nhân c£ nhïng sÑ âm.
Hàm này có mÙt h¡n ch¿ là kiÃu dï liÇu mà nó dùng (long) không cho phép tính giai thëa quá 12!.
Khai báo m«u cho hàm.
Cho ¿n giÝ 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ó, mà th°Ýng là trong main, vì vy hàm main luôn ph£i n±m cuÑi ch°¡ng trình. N¿u b¡n thí l·p l¡i mÙt vài ví då vÁ hàm tr°Ûc ây nh°ng thí ·t hàm main tr°Ûc b¥t kì mÙt hàm °ãc gÍi të nó, b¡n g§n nh° ch¯c ch¯n s½ nhn °ãc thông báo l×i. Nguyên nhân là mÙt hàm ph£i °ãc khai báo tr°Ûc khi nó °ãc gÍi nh° nh°nggx gì chúng ta ã làm trng t¥t c£ các ví då.
Nh°ng có mÙt cách khác à tránh ph£i vi¿t t¥t c£ mã ch°¡ng trình tr°Ûc khi chúng có thà °ãc dùng trong main hay b¥t kì mÙt hàm nào khác. ó chính là khai báo m«u cho 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ë:
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¥t c£ các lÇnh th°Ýng °ãc bÍc trong c·p ngo·c nhÍn { }.
Nó k¿t thúc b±ng d¥u ch¥m ph©y (;).
Trong ph§n liÇt kê các tham sÑ chÉ c§n vi¿t kiÃu cça chúng là ç. ViÇc vi¿t tên cça các tham sÑ trong ph§n khai báo m«u là không b¯t buÙc.
Ví då:
// prototyping
#include <iostream.h>
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.
";
else even (a);
}
void even (int a)
{
if ((a%2)==0) cout << "Number is even.
";
else odd (a);
} 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. 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à nhn °ãc k¿t qu£ nh° trên chÉ vÛi mÙt nía sÑ dòng lÇnh. Tuy nhiên nó giúp cho chúng ta th¥y °ãc viÇc khai báo m«u các hàm là nh° th¿ nào. H¡n nïa, 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);
cho phép hai hàm này có thà °ãc sí dång tr°Ûc khi chúng °ãc Ënh ngh)a hoàn chÉnh. Tuy nhiên lý do ·c biÇt gi£i thích t¡i sao ch°¡ng trình này l¡i c§n ít nh¥t mÙt hàm ph£i °ãc khi báo m«u là trong odd có mÙt lÝi gÍi ¿n even và trong even có mÙt lÝi gÍi ¿n odd. Vì vy n¿u không có hàm nào °ãc khai báo tr°Ûc thì l×i ch¯c ch¯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">
R¥t nhiÁu lp trình viên kinh nghiÇm khuyên r±ng t¥t c£ các hàm nên °ãc khai báo m«u. ó cing là lÝi khuyên cça tôi, nh¥t là trong tr°Ýng hãp có nhiÁu hàm ho·c chúng r¥t dài, khi ó viÇc khai báo t¥t c£ các hàm ß cùng mÙt ch× cho phép chúng ta bi¿t ph£i gÍi các hàm nh° th¿ nào, vì vy ti¿t kiÇm °ãc thÝi gian.
Bài 7 : M£ng
M£ng là mÙt dãy các ph§n tí có cùng kiÃu °ãc ·t liên ti¿p trong bÙ nhÛ và có thà 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.
iÁu này có ngh)a là, ví då, chúng ta có thà l°u 5 giá trË kiÃu int mà không c§n ph£i khai báo 5 bi¿n khác nhau.Ví då, mÙt m£ng chéa 5 giá trË nguyên kiÃu int có tên là billy có thà °ãc biÃu diÅn nh° sau:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgarra1.gif" \* MERGEFORMATINET
trong ó m×i mÙt ô trÑng biÃu diÅn mÙt ph§n tí cça m£ng, trong tr°Ýng hãp này là các giá trË nguyên kiÃu int. Chúng °ãc ánh sÑ të 0 ¿n 4 vì ph§n tí §u tiên cça m£ng luôn là 0 b¥t kà ٠dài cça nó là bao nhiêu.
Nh° b¥t kì bi¿n nào khác, mÙt m£ng ph£i °ãc khai báo tr°Ûc khi có thà sí dång. MÙt khai báo iÃn hình cho mÙt m£ng trong C++ nh° sau:
type name [elements];
trong ó type là mÙt kiÃu dï liÇu hãp lÇ (int, float...), name là mÙt tên bi¿n hãp lÇ và tr°Ýng elements chÉ Ënh m£ng ó s½ chéa bao nhiêu ph§n tí
Vì vy, Ã khai báo billy nh° ã trình bày ß trên chúng ta chÉ c§n mÙt dòng ¡n gi£n nh° sau:
int billy [5];
Chú ý: Tr°Ýng elements bên trong c·p ngo·c [] ph£i là mÙt giá trË h±ng khi khai báo 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£ nng 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.
Khi khai báo mÙt m£ng vÛi t§m ho¡t Ùng Ëa ph°¡ng (trong mÙt hàm), theo m·c Ënh nó s½ không °ãc khßi t¡o, vì vy nÙi dung cça nó là không xác Ënh cho ¿n khi chúng ra l°u các giá trË lên ó.
N¿u chúng ta khai báo mÙt m£ng toàn cåc (bên ngoài t¥t c£ các hàm) nó s½ °ãc khßi t¡o và t¥t c£ các ph§n tí °ãc ·t b±ng 0. Vì vy n¿u chúng ta khai báo m£ng toàn cåc:
int billy [5];
mÍi ph§n tí cça billy s½ °ãc khßi t¡o là 0:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgarra2.gif" \* MERGEFORMATINET
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:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgarra3.gif" \* MERGEFORMATINET
SÑ ph§n tí trong m£ng mà chúng ta khßi t¡o vÛi c·p ngo·c nhÍn { } ph£i b±ng sÑ ph§n tí cça m£ng ã °ãc khai báo vÛi c·p ngo·c vuông [ ]. Bßi vì iÁu này có thà °ãc coi là mÙt sñ l·p l¡i không c§n thi¿t nên C++ cho phép à trÑng giïa c·p ngo·c vuông, kích th°Ûc cça m£ng °ãc xác Ënh b±ng sÑ giá trË giïa c·p ngo·c nhÍn.
Truy xu¥t ¿n các ph§n tí cça m£ng.
Þ b¥t kì iÃm nào cça ch°¡ng trình trong t§m ho¡t Ùng cça m£ng, chúng ta có thà truy xu¥t tëng ph§n tí cça m£ng à Íc hay chÉnh sía nh° là Ñi vÛi mÙt bi¿n bình th°Ýng. C¥u trúc cça nó nh° sau:
name[index]
Nh° ß trong ví då tr°Ûc ta có m£ng billy gÓm 5 ph§n tí có kiÃu int, chúng ta có thà truy xu¥t ¿n tëng ph§n tí cça m£ng nh° sau:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgarra4.gif" \* MERGEFORMATINET
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];
Vì vy, xét vÁ mÍi ph°¡ng diÇn, biÃu théc billy[2] giÑng nh° b¥t kì mÙt bi¿n kiÃu int.
Chú ý r±ng ph§n tí thé ba cça billy là billy[2], vì m£ng b¯t §u të chÉ sÑ 0. Vì vy, ph§n tí cuÑi cùng s½ là billy[4]. Vì vy n¿u chúng ta vi¿t billy[5], chúng ta s½ truy xu¥t ¿n ph§n tí thé 6 cça m£ng và v°ãt quá giÛi h¡n cça m£ng.
Trong C++, viÇc v°ãt quá giÛi h¡n chÉ sÑ cça m£ng là hoàn toàn hãp lÇ, tuy nhiên nó 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×i 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½ °ãc nói ¿n k) h¡n khi chúng ta b¯t §u sí dång con trÏ.
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°Ûc cho m£ng khi khai báo chúng và thé hai, à chÉ Ënh chÉ sÑ cho mÙt ph§n tí cå thà cça m£ng khi xem xét ¿n nó.
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.
MÙt vài thao tác hãp lÇ khác vÛi m£ng:
billy[0] = a;
billy[a] = 75;
b = billy [a+2];
billy[billy[a]] = billy[2] + 5;
// ví då vÁ m£ng
#include <iostream.h>
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;
} 12206 M£ng nhiÁu chiÁu.
M£ng nhiÁu chiÁu có thà °ãc coi nh° m£ng cça m£ng, ví då, mÙt m£ng hai chiÁu có thà °ãc t°ßng t°ãc nh° là mÙt b£ng hai chiÁu gÓm các ph§n tí có kiÃu dï liÇu cå thà và giÑng nhau.
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgarra5.gif" \* MERGEFORMATINET
jimmy biÃu diÅn mÙt m£ng hai chiÁu kích th°Ûc 3x5 có kiÃu int. Cách khai báo m£ng này nh° sau:
int jimmy [3][5];
và, ví då, cách à truy xu¥t ¿n ph§n tí thé hai theo chiÁu dÍc và thé t° theo chiÁu ngang trong mÙt biÃu théc nh° sau:
jimmy[1][3]
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgarra6.gif" \* MERGEFORMATINET
(hãy nhÛ r±ng chÉ sÑ cça m£ng luôn b¯t §u të 0).
M£ng nhiÁu chiÁu không bË giÛi h¡n bßi hai chÉ sÑ (hai chiÁu), Chúng có thà chéa bao 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 century [100][365][24][60][60];
gán mÙt giá trË char cho m×i giây trong mÙt th¿ kÉ, ph£i c§n ¿n h¡n 3 t÷ giá trË chars! Chúng ta s½ ph£i c§n kho£ng 3GB RAM Ã khai báo nó.
M£ng nhiÁu chiÁu thñc ra là mÙt khái niÇm trëu t°ãng vì chúng ta có thà có k¿t qu£ t°¡ng 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ó:
int jimmy [3][5]; t°¡ng °¡ng vÛi
int jimmy [15]; (3 * 5 = 15)
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:
// multidimensional array
#include <iostream.h>
#define WIDTH 5
#define HEIGHT 3
int jimmy [HEIGHT][WIDTH];
int n,m;
int main ()
{
for (n=0;n<HEIGHT;n++)
for (m=0;m<WIDTH;m++)
{
jimmy[n][m]=(n+1)*(m+1);
}
return 0;
} // pseudo-multidimensional array
#include <iostream.h>
#define WIDTH 5
#define HEIGHT 3
int jimmy [HEIGHT * WIDTH];
int n,m;
int main ()
{
for (n=0;n<HEIGHT;n++)
for (m=0;m<WIDTH;m++)
{
jimmy[n * WIDTH + m]=(n+1)*(m+1);
}
return 0;
} không mÙt ch°¡ng trình nào vi¿t gì ra màn hình nh°ng c£ hai Áu gán giá trË vào khÑi nhÛ có tên jimmy theo cách sau:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgarra7.gif" \* MERGEFORMATINET
Chúng ta ã Ënh ngh)a h±ng (#define) Ã ¡n gi£n hóa nhïng chÉnh sía sau này cça ch°¡ng trình, ví då, trong tr°Ýng hãp chúng ta quy¿t Ënh tng kích th°Ûc cça m£ng vÛi chiÁu cao là 4 thay vì là 3, chúng ta chÉ c§n thay Õi dòng:
#define HEIGHT 3
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Ñ.
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 lÇ, ngay c£ khi nó °ãc tÕ chéc thành mÙt m£ng. Tuy nhiên chúng ta l¡i °ãc phép truyÁn Ëa chÉ cça nó, viÇc này cing t¡o ra k¿t qu£ thñc t¿ giÑng thao tác ß trên nh°ng l¡i nhanh h¡n nhiÁu và hiÇu qu£ h¡n.
à có thà nhn 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:
void procedure (int arg[])
nhn vào mÙt tham sÑ có kiÃu "m£ng cça char" và có tên arg. Ã truyÁn tham sÑ cho hàm này mÙt m£ng °ãc khai báo:
int myarray [40];
chÉ c§n gÍi hàm nh° sau:
procedure (myarray);
D°Ûi ây là mÙt ví då cå thÃ
// arrays as parameters
#include <iostream.h>
void printarray (int arg[], int length) {
for (int n=0; n<length; n++)
cout << arg[n] << " ";
cout << "
";
}
int main ()
{
int firstarray[] = {5, 10, 15};
int secondarray[] = {2, 4, 6, 8, 10};
printarray (firstarray,3);
printarray (secondarray,5);
return 0;
} 5 10 15
2 4 6 8 10 Nh° b¡n có thà th¥y, tham sÑ §u tiên (int arg[]) ch¥p nhn mÍi m£ng có kiÃu c¡ b£n là int, b¥t kà ٠dài cça nó là bao nhiêu, vì vy c§n thi¿t ph£i có tham sÑ thé hai à báo cho hàm này bi¿t Ù dài cça m£ng mà chúng ta truyÁn cho nó.
Trong ph§n khai báo hàm chúng ta cing 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:
base_type[][depth][depth]
ví då, mÙt hàm vÛi tham sÑ là m£ng nhiÁu chiÁu có thà nh° sau:
void procedure (int myarray[][3][4])
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 vy vì trình biên dËch C++ ph£i có kh£ nng 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">
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°Ýng là nguyên nhân gây l×i cho nhïng lp trình viên thi¿u kinh nghiÇm. Các b¡n nên Íc bài 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ñ
Trong t¥t c£ các ch°¡ng trình chúng ta ã th¥y cho ¿n giÝ, 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ñ, 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, o¡n vn b£n... Cho ¿n giÝ chúng ta mÛi chÉ dùng chúng d°Ûi d¡ng h±ng ché chéa quan tâm ¿n các bi¿n có thà chéa chúng.
Trong C++ không có kiÃu dï liÇu c¡ b£n à l°u các xâu kí tñ. à có thà thÏa mãn nhu c§u này, ng°Ýi ta sí dång m£ng có kiÃu char. Hãy nhÛ r±ng kiÃu dï liÇu này (char) chÉ có thà l°u trï mÙt kí tñ ¡n, bßi vy nó °ãc dùng à t¡o ra xâu cça các kí tñ ¡n.
Ví då, m£ng sau (hay là xâu kí tñ):
char jenny [20];
có thà l°u mÙt xâu kí tñ vÛi Ù dài cñc ¡i là 20 kí tñ. B¡n có thà t°ßng t°ãng nó nh° sau:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgstri1.gif" \* MERGEFORMATINET
Kích th°Ûc cñc ¡i này không c§n ph£i luôn luôn dùng ¿n. Ví då, jenny có thà l°u xâu "Hello" hay "Merry christmas". Vì các m£ng kí tñ có thà l°u các xâu kí tñ ng¯n h¡n Ù dài cça nó, trong C++ ã có mÙt quy °Ûc à k¿t thúc mÙt nÙi dung cça mÙt xâu kí tñ b±ng mÙt kí tñ null, có thà °ãc vi¿t là '\0'.
Chúng ta có thà biÃu diÅn jenny (mÙt m£ng có 20 ph§n tí kiÃu char) khi l°u trï xâu kí tñ "Hello" và "Merry Christmas" theo cách sau:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgstri2.gif" \* MERGEFORMATINET
Chú ý r±ng sau nÙi dung cça xâu, mÙt kí tñ null ('\0') °ãc dùng à báo hiÇu 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ñ.
Vì nhïng xâu kí tñ là nhïng m£ng bình th°Ýng nên chúng cing nh° các m£ng khác. Ví då, n¿u chúng ta muÑn khßi t¡o mÙt xâu kí tñ vÛi nhïng giá trË xác Ënh chúng ta có thà làm iÁu ó t°¡ng tñ nh° vÛi các m£ng khác:
char mystring[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
Tuy nhiên, chúng ta có thà khßi t¡o giá trË cho mÙt xâu kí tñ b±ng cách khác: sí dång các h±ng xâu kí tñ.
Trong các biÃu théc chúng ta ã sí dång trong các ví då trong các ch°¡ng tr°Ûc các h±ng xâu kí tñ Ã xu¥t hiÇn vài l§n. Chúng °ãc biÃu diÅn trong c·p ngo·c kép ("), ví då:
"the result is: "
là mÙt h±ng xâu kí tñ chúng ta sí dång ß mÙt sÑ ch×.
Không giÑng nh° d¥u nháy ¡n (') cho phép biÃu diÅn h±ng kí tñ, c·p ngo·c kép (") là h±ng biÃu diÅn mÙt chu×i kí tñ liên ti¿p, và ß cuÑi chu×i mÙt kí tñ null ('\0') luôn °ãc tñ Ùng thêm vào.
Vì vy 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";
Trong c£ hai tr°Ýng hãp m£ng (hay xâu kí tñ) mystring °ãc khai báo vÛi kích th°Ûc 6 kí tñ: 5 kí tñ biÃu diÅn Hello cÙng vÛi mÙt kí tñ null.
Tr°Û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í dång d¥u ngo·c kép (") chÉ hãp lÇ khi khßi t¡o m£ng, téc là lúc khai báo m£ng. Các biÃu théc trong ch°¡ng trình nh°:
mystring = "Hello";
mystring[] = "Hello";
là không hãp lÇ, c£ câu lÇnh d°Ûi ây cing vy:
mystring = { 'H', 'e', 'l', 'l', 'o', '\0' };
Vy hãy nhÛ: 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 nó. Nguyên nhân là mÙt thao tác gán (=) không thà nhn v¿ trái là c£ mÙt m£ng mà chÉ có thà nhn mÙt trong nhïng ph§n tí cça nó. Vào thÝi iÃm khßi t¡o m£ng là mÙt tr°Ýng hãp ·c biÇt, vì nó không thñc sñ là mÙt lÇnh gán m·c dù nó sí dång d¥u b±ng (=).
Gán giá trË cho xâu kí tñ
Vì v¿ trái cça mÙt lÇnh gán chÉ có thà là mÙt ph§n tí cça m£ng ché không thà là c£ m£ng, chúng ta có thà gán mÙt xâu kí tñ cho mÙt m£ng kiÃu char sí dång mÙt ph°¡ng pháp nh° sau:
mystring[0] = 'H';
mystring[1] = 'e';
mystring[2] = 'l';
mystring[3] = 'l';
mystring[4] = 'o';
mystring[5] = '\0';
Nh°ng rõ ràng ây không ph£i là mÙt ph°¡ng pháp thñc t¿. à gán giá trË cho mÙt xâu kí tñ, chúng ta có thà sí dång lo¡t hàm kiÃu strcpy (string copy), hàm này °ãc Ënh ngh)a trong string.h và có thà °ãc gÍi nh° sau:
strcpy (string1, string2);
LÇnh này copy nÙi dung cça string2 sang string1. string2 có thà là mÙt m£ng, con trÏ hay mÙt h±ng xâu kí tñ, bßi vy lÇnh sau ây là mÙt cách úng à gán xâu h±ng "Hello" cho mystring:
strcpy (mystring, "Hello");
Ví då:
// setting value to string
#include <iostream.h>
#include <string.h>
int main ()
{
char szMyName [20];
strcpy (szMyName,"J. Soulie");
cout << szMyName;
return 0;
} J. Soulie à ý r±ng chúng ta ph£i include file <string.h> à có thà sí dång hàm strcpy.
M·c dù chúng ta luôn có thà vi¿t mÙt hàm ¡n gi£n nh° hàm setstring d°Ûi ây à thñc hiÇn mÙt thao tác giÑng nh° strcpy:
// setting value to string
#include <iostream.h>
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;
} J. Soulie MÙt ph°¡ng théc th°Ýng dùng khác à gán giá trË cho mÙt m£ng là sí dång trñc ti¿p dòng nhp dï liÇu (cin). Trong tr°Ýng hãp này giá trË cça xâu kí tñ °ãc gán bßi ng°Ýi dùng trong quá trình ch°¡ng trình thñc hiÇn.
Khi cin °ãc sí dång vÛi các xâu kí tñ nó th°Ýng °ãc dùng vÛi ph°¡ng théc 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 = '
');
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), length là Ù dài cñc ¡i cça bÙ Çm (kích th°Ûc cça m£ng) và delimiter là kí tñ °ãc dùng à k¿t thúc viÇc nhp, m·c Ënh - n¿u chúng ta không dùng tham sÑ này - s½ là kí tñ xuÑng dòng ('
').
Ví då sau ây l·p l¡i t¥t c£ nhïng gì b¡n gõ trên bàn phím. Nó r¥t ¡n gi£n nh°ng 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:
// cin with strings
#include <iostream.h>
int main ()
{
char mybuffer [100];
cout << "What's your name? ";
cin.getline (mybuffer,100);
cout << "Hello " << mybuffer << ".
";
cout << "Which is your favourite team? ";
cin.getline (mybuffer,100);
cout << "I like " << mybuffer << " too.
";
return 0;
} What's your name? Juan
Hello Juan.
Which is your favourite team? Inter Milan
I like Inter Milan too. Chú ý trong c£ hai lÝi gÍi cin.getline chúng ta sí dång cùng mÙt bi¿n xâu (mybuffer). Nhïng gì ch°¡ng trình làm trong lÝi gÍi thé hai ¡n gi£n là thay th¿ nÙi dung cça buffer trong lÝi gÍi ci b±ng nÙi dung mÛi.
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 tí >> à nhn dï liÇu trñc ti¿p të §u vào chu©n. Ph°¡ng théc này có thà °ãc dùng vÛi các xâu kí tñ thay cho cin.getline. Ví då, trong ch°¡n trình cça chúng ta, khi chúng ta muÑn nhn dï liÇu të ng°Ýi dùng chúng ta có thà vi¿t:
cin >> mybuffer;
lÇnh này s½ làm viÇc nh° nó có nhïng h¡n ch¿ sau mà cin.getline không có:
Nó chÉ có thà nhn nhïng të ¡n (không nhn °ãc c£ câu) vì ph°¡ng théc này sí dång kí tñ trÑng(bao gÓm c£ d¥u cách, d¥u tab và d¥u xuÑng dòng) làm d¥u hiÇu k¿t thúc..
Nó không cho phép chÉ Ënh kích th°Ûc cho bÙ Çm. Ch°¡ng trình cça b¡n có 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ó.
Vì nhïng nguyên nhân trên, khi muÑn nhp vào các xâu kí tñ b¡n nên sí dång cin.getline thay vì cin >>.
ChuyÃn Õi xâu kí tñ sang các kiÃu khác.
Vì mÙt xâu kí tñ có thà biÃu diÅn nhiÁu kiÃu dï liÇu khác nh° d¡ng sÑ nên viÇc chuyÃn Õi nÙi dung nh° vy 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ñ null) và không dÅ gì chuyÃn thành mÙt sÑ nguyên. Vì vy th° viÇn cstdlib (stdlib.h) ã cung c¥p 3 macro/hàm hïu ích sau:
atoi: chuyÃn xâu thành kiÃu int.
atol: chuyÃn xâu thành kiÃu long.
atof: chuyÃn xâu thành kiÃu float.
T¥t c£ các hàm này nhn mÙt tham sÑ và tr£ vÁ giá trË sÑ (int, long ho·c float). Các hàm này khi k¿t hãp vÛi ph°¡ng théc getline cça cin là mÙt cách áng tin cy h¡n ph°¡ng théc cin>> cÕ iÃn khi yêu c§u ng°Ýi sí dång nhp vào mÙt sÑ:
// cin and ato* functions
#include <iostream.h>
#include <stdlib.h>
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;
} Enter price: 2.75
Enter quantity: 21
Total price: 57.75 Các hàm à thao tác trên chu×i
Th° viÇn cstring (string.h) không chÉ có hàm strcpy mà còn có nhiÁu hàm khác à 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 string.
Chú ý: char* hoàn toàn t°¡ng °¡ng vÛi char[]
Bài 9 : Con TrÏ
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°Ûi các tên. Các bi¿n này °ãc l°u trï t¡i nhïng ch× cå thà trong bÙ nhÛ. Ñi vÛi ch°¡ng trình 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.
MÙt sñ mô hình tÑt Ñi vÛi bÙ nhÛ máy tính chính là mÙt phÑ trong mÙt thành phÑ. Trên mÙt phÑ t¥t c£ các ngôi nhà Áu °ãc ánh sÑ tu§n tñ vÛi mÙt cái tên duy nh¥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 °ãc n¡i ó mà không l§m l«n vì chÉ có mÙt ngôi nhà vÛi sÑ nh° vy.
Cing vÛi cách tÕ chéc t°¡ng tñ nh° viÇc ánh sÑ các ngôi nhà, hÇ iÁu hành tÕ chéc bÙ nhÛ thành nhïng sÑ ¡n nh¥t, tu§n tñ, nên n¿u chúng ta nói ¿n vË trí 1776 trong bÙ nhÛ chúng ta bi¿t chính xác ô nhÛ ó vì chÉ có mÙt vË trí vÛi Ëa chÉ nh° vy.
Toán tí l¥y Ëa chÉ (&).
Vào thÝi iÃm mà chúng ta khai báo mÙt bi¿n thì nó ph£i °ãc l°u trï trong mÙt vË trí cå thà trong bÙ nhÛ. Nói chung chúng ta không quy¿t Ënh n¡i nào bi¿n ó °ãc ·t - tht may m¯n r±ng iÁu ó ã °ãc làm tñ Ùng bßi trình biên dËch và hÇ iÁu hành, 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¿t bi¿n ó °ãc l°u trï ß âu.
iÁu này có thà °ãc thñc hiÇn b±ng cách ·t tr°Ûc tên bi¿n mÙt d¥u và (&), có ngh)a là "Ëa chÉ cça". Ví då:
ted = &andy;
s½ gán cho bi¿n ted Ëa chÉ cça bi¿n andy, vì khi ·t tr°Ûc tên bi¿n andy d¥u và (&) 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Û.
Gi£ sí r±ng bi¿n andy °ãc ·t ß ô nhÛ có Ëa chÉ 1776 và chúng ta vi¿t nh° sau:
andy = 25;
fred = andy;
ted = &andy;
k¿t qu£ s½ giÑng nh° trong s¡ Ó d°Ûi ây:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgpoin1.gif" \* MERGEFORMATINET
Chúng ta ã gán cho fred nÙi dung cça bi¿n andy nh° chúng ta ã làm r¥t l§n nhiÁu khác trong nhïng ph§n tr°Ûc nh°ng vÛi bi¿n ted chúng ta ã gán Ëa chÉ mà hÇ iÁu hành l°u giá trË cça bi¿n andy, chúng ta vëa gi£ sí nó là 1776.
Nhïng bi¿n l°u trï Ëa chÉ cça mÙt bi¿n khác (nh° ted ß trong ví då tr°Ûc) °ãc gÍi là con trÏ. Trong C++ con trÏ có r¥t nhiÁu °u iÃm và chúng °ãc sí dång r¥t th°Ýng xuyên, Ti¿p theo chúng ta s½ th¥y các bi¿n kiÃu này °ãc khai báo nh° th¿ nào.
Toán tí tham chi¿u (*)
B±ng cách sí dång con trÏ chúng ta có thà truy xu¥t trñc ti¿p ¿n giá trË °ãc l°u trï trong bi¿n °ãc trÏ bßi nó b±ng cách · tr°Ûc tên bi¿n con trÏ mÙt d¥u sao (*) - ß ây có thà °ãc dËch là "giá trË °ãc trÏ bßi". Vì vy, n¿u chúng ta vi¿t:
beth = *ted;
(chúng ta có thà Íc nó là: "beth b±ng giá trË °ãc trÏ bßi ted" beth s½ mang giá trË 25, vì ted b±ng 1776 và giá trË trÏ bßi 1776 là 25.
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgpoin2.gif" \* MERGEFORMATINET
B¡n ph£i phân biÇt °ãc r±ng ted có giá trË 1776, nh°ng *ted (vÛi mÙt d¥u sao ±ng tr°Ûc) trÏ tÛi giá trË °ãc l°u trï trong Ëa chÉ 1776, ó là 25. Hãy chú ý sñ khác biÇt 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 )
Toán tí l¥y Ëa chÉ (&)
Nó °ãc dùng nh° là mÙt tiÁn tÑ cça bi¿n và có thà °ãc dËch là "Ëa chÉ cça", vì vy &variable1 có thà °ãc Íc là "Ëa chÉ cça variable1".
Toán tí tham chi¿u (*)
Nó chÉ ra r±ng cái c§n °ãc tính toán là nÙi dung °ãc trÏ bßi biÃu théc °ãc coi nh° là mÙt Ëa chÉ. Nó có thà °ãc dËch là "giá trË °ãc trÏ bßi"..
*mypointer °ãc Íc là "giá trË °ãc trÏ bßi mypointer". Vào lúc này, vÛi nhïng ví då ã vi¿t ß trên
andy = 25;
ted = &andy;
b¡n có thà dÅ dàng nhn ra t¥t c£ các biÃu théc sau là úng:
andy == 25
&andy == 1776
ted == 1776
*ted == 25
Khai báo bi¿n kiÃu con trÏ
Vì con trÏ có kh£ nng tham chi¿u trñc ti¿p ¿n giá trË mà chúng trÏ tÛi nên c§n thi¿t ph£i chÉ rõ kiÃu dï liÇu nào mà mÙt bi¿n con trÏ trÏ tÛi khai báo nó. Vì vy, khai báo cça mÙt bi¿n con trÏ s½ có m«u sau:
type * pointer_name;
trong ó type là kiÃu dï liÇu °ãc trÏ tÛi, không ph£i là kiÃu cça b£n thân con trÏ. Ví då:
int * number;
char * character;
float * greatnumber;
ó là ba khai báo cça con trÏ. M×i bi¿n §u trÏ tÛi mÙt kiÃu dï liÇu khác nhau nh°ng c£ ba Áu là con trÏ và chúng Áu chi¿m mÙt l°ãng bÙ nhÛ nh° nhau (kích th°Ûc cça 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Ûi không chi¿m l°ãng bÙ nhÛ nh° nhau, mÙt kiÃu int, mÙt kiÃu char và cái còn l¡i kiÃu float.
Tôi ph£i nh¥n m¡nh l¡i r±ng d¥u sao (*) mà chúng ta ·t khi khai báo mÙt con trÏ chÉ có ngh)a r±ng: ó là mÙt con trÏ và hoàn toàn không liên quan ¿n toán tí tham chi¿u mà chúng ta ã xem xét tr°Ûc ó. ó ¡n gi£n chÉ là hai tác vå khác nhau °ãc biÃu diÅn bßi cùng mÙt d¥u.
// my first pointer
#include <iostream.h>
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==10 / value2==20 Chú ý r±ng giá trË cça value1 và value2 °ãc thay Õi mÙt cách gián ti¿p. §u tiên chúng ta gán cho mypointer Ëa chÉ cça value1 dùng toán tí l¥y Ëa chÉ (&) và sau ó chúng ta gán 10 cho giá trË °ãc trÏ bßi mypointer, ó là giá trË °ãc trÏ bßi value1 vì vy 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°¡ng trình chúng ta s½ l·p l¡i quá trình vÛi value2 và vÛi cùng mÙt con trÏ.
ây là mÙt ví då phéc t¡p h¡n mÙt chút:
// more pointers
#include <iostream.h>
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;
} value1==10 / value2==20 MÙt dòng có thà gây sñ chú ý cça b¡n là:
int *p1, *p2;
dòng này khai báo hai con trÏ b±ng cách ·t d¥u sao (*) tr°Ûc m×i con trÏ. Nguyên nhân là kiÃu dï liÇu khai báo cho c£ dòng là int và vì theo thé tñ të ph£i sang trái, d¥u sao °ãc tính tr°Ûc tên kiÃu. Chúng ta ã nói ¿n iÁu này trong bài HYPERLINK "http://www.diendantinhoc.net/tute/laptrinh/c/cpp-nmthang/bai1_3.htm" 1.3: Các toán tí.
Con trÏ và m£ng.
Trong thñc t¿, tên cça mÙt m£ng t°¡ng °¡ng vÛi Ëa chÉ ph§n tí §u tiên cça nó, giÑng nh° mÙt con trÏ t°¡ng °¡ng vÛi Ëa chÉ cça ph§n tí §u tiên mà nó trÏ tÛi, vì vy thñc t¿ chúng hoàn toàn nh° nhau. Ví då, cho hai khai báo sau:
int numbers [20];
int * p;
lÇnh sau s½ hãp lÇ:
p = numbers;
Þ ây p và numbers là t°¡ng °¡ng và chúng có cing thuÙc tính, sñ khác biÇt duy nh¥t là chúng ta có thà gán mÙt giá trË khác cho con trÏ p trong khi numbers luôn trÏ ¿n ph§n tí §u tiên trong sÑ 20 ph§n tí kiÃu int mà nó °ãc Ënh ngh)a vÛi. Vì vy, không giÑng nh° p - ó là mÙt bi¿n con trÏ bình th°Ýng, numbers là mÙt con trÏ h±ng. LÇnh gán sau ây là không hãp lÇ:
numbers = p;
bßi vì numbers là mÙt m£ng (con trÏ h±ng) và không có giá trË nào có thà °ãc gán cho các h±ng.
Vì con trÏ cing có mÍi tính ch¥t cça mÙt bi¿n nên t¥t c£ các biÃu théc có con trÏ trong ví då d°Ûi ây là hoàn toàn hãp lÇ:
// more pointers
#include <iostream.h>
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;
} 10, 20, 30, 40, 50, Trong bài "m£ng" chúng ta ã dùng d¥u ngo·c vuông à chÉ ra ph§n tí cça m£ng mà chúng ta muÑn trÏ ¿n. C·p ngo·c vuông này °ãc coi nh° là toán tí offset và ý ngh)a 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:
a[5] = 0; // a [offset of 5] = 0
*(a+5) = 0; // pointed by (a+5) = 0
là hoàn toàn t°¡ng °¡ng và hãp lÇ b¥t kà a là m£ng hay là mÙt con trÏ.
Khßi t¡o con trÏ
Khi khai báo con trÏ có thà chúng ta s½ muÑn chÉ Ënh rõ ràng chúng s½ trÏ tÛi bi¿n nào,
int number;
int *tommy = &number;
là t°¡ng °¡ng vÛi:
int number;
int *tommy;
tommy = &number;
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Ûi ché không ph£i là giá trË mà nó trÏ tÛi. B¡n c§n ph£i nhÛ r±ng khi khai báo mÙt bi¿n con trÏ, d¥u sao (*) °ãc dùng à chÉ ra nó là mÙt con trÏ, và hoàn toàn khác vÛi toán tí tham chi¿u. ó là hai toán tí khác nhau m·c dù chúng °ãc vi¿t vÛi cùng mÙt d¥u. Vì vy, các câu lÇnh sau là không hãp lÇ:
int number;
int *tommy;
*tommy = &number;
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Ûi b±ng giá trË h±ng vào thÝi iÃm khai báo bi¿n con trÏ:
char * terry = "hello";
trong tr°Ýng hãp này mÙt khÑi nhÛ t)nh °ãc dành à chéa "hello" và mÙt con trÏ trÏ tÛi kí tñ §u tiên cça khÑi nhÛ này (ó là kí tñ h') °ãc gán cho terry. N¿u "hello" °ãc l°u t¡i Ëa chÉ 1702, lÇnh khai báo trên có thà °ãc hình dung nh° th¿ này:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgpoin3.gif" \* MERGEFORMATINET
c§n ph£i nh¯c l¡i r±ng terry mang giá trË 1702 ché không ph£i là 'h' hay "hello".
Bi¿n con trÏ terry trÏ tÛi mÙt xâu kí tñ và nó có thà °ãc sí dång nh° là Ñi vÛi 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ñ 'o' b±ng mÙt d¥u ch¥m than, chúng ta có thà thñc hiÇn viÇc ó b±ng hai cách:
terry[4] = '!';
*(terry+4) = '!';
hãy nhÛ r±ng vi¿t terry[4] là hoàn toàn giÑng vÛi vi¿t *(terry+4) m·c dù biÃu théc 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 terry trÏ ¿n s½ có giá trË nh° sau:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgpoin4.gif" \* MERGEFORMATINET
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Ñ nguyên khác. Tr°Ûc h¿t, chÉ phép cÙng và trë là °ãc phép dùng. Nh°ng c£ cÙng và trë Áu cho k¿t qu£ phå thuÙc vào kích th°Ûc cça kiÃu dï liÇu mà bi¿n con trÏ trÏ tÛi.
Chúng ta th¥y có nhiÁu kiÃu dï liÇu khác nhau tÓn t¡i và chúng có thà chi¿m ch× 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, char chi¿m 1 byte, short chi¿m 2 byte và long chi¿m 4 byte.
Gi£ sí chúng ta có 3 con trÏ sau:
char *mychar;
short *myshort;
long *mylong;
và chúng l§n l°ãt trÏ tÛi ô nhÛ 1000, 2000 and 3000.
N¿u chúng ta vi¿t
mychar++;
myshort++;
mylong++;
mychar - nh° b¡n mong ãi - s½ mang giá trË 1001. Tuy nhiên myshort 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Ûi ph§n tí ti¿p theo có cùng kiÃu mà nó ã °ãc Ënh ngh)a, vì vy kích th°Ûc tính b±ng byte cça kiÃu dï liÇu nó trÏ tÛi s½ °ãc cÙng thêm vào bi¿n con trÏ.
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 cing hoàn toàn thu °ãc k¿t qu£ nh° trên n¿u vi¿t:
mychar = mychar + 1;
myshort = myshort + 1;
mylong = mylong + 1;
C§n ph£i c£nh báo b¡n r±ng c£ hai toán tí tng (++) và gi£m (--) Áu có quyÁn °u tiên lÛn h¡n toán tí tham chi¿u (*), vì vy biÃu théc sau ây có thà d«n tÛi k¿t qu£ sai:
*p++;
*p++ = *q++;
LÇnh §u tiên t°¡ng °¡ng vÛi *(p++) iÁu mà nó thñc hiÇn là tng p (Ëa chÉ ô nhÛ mà nó trÏ tÛi ché không ph£i là giá trË trÏ tÛi).
LÇnh thé hai, c£ hai toán tí tng (++) Áu °ãc thñc hiÇn sau khi giá trË cça *q °ãc gán cho *p và sau ó c£ q và p Áu tng lên 1. LÇnh này t°¡ng °¡ng vÛi:
*p = *q;
p++;
q++;
Nh° ã nói trong các bài tr°Ûc, tôi khuyên các b¡n nên dùng các c·p ngo·c ¡n à tránh nhïng k¿t qu£ không mong muÑn.
Con trÏ trÏ tÛi con trÏ
C++ cho phép sí dång các con trÏ trÏ tÛi các con trÏ khác giÑng nh° là trÏ tÛi dï liÇu. Ã làm viÇc ó chúng ta chÉ c§n thêm mÙt d¥u sao (*) cho m×i méc tham chi¿u.
char a;
char * b;
char ** c;
a = 'z';
b = &a;
c = &b;
gi£ sí r±ng a,b,c °ãc l°u ß các ô nhÛ 7230, 8092 and 10502, ta có thà mô t£ o¡n mã trên nh° sau:
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgpoin6.gif" \* MERGEFORMATINET
iÃm mÛi trong ví då này là bi¿n c, chúng ta có thà nói vÁ nó theo 3 cách khác nhau, 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
Con trÏ không kiÃu là mÙt lo¡i con trÏ ·c biÇt. Nó có thà trÏ tÛi b¥t kì lo¡i dï liÇu nào, të giá trË nguyên ho·c thñc cho tÛi mÙt xâu kí tñ. H¡n ch¿ duy nh¥t cça nó là dï liÇu °ãc trÏ tÛi không thà °ãc tham chi¿u tÛi mÙt cách trñc ti¿p (chúng ta không thà dùng toán tí tham chi¿u * vÛi chúng) vì Ù dài cça nó là không xác Ënh và vì vy 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
// integer increaser
#include <iostream.h>
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;
} 6, 10, 13 sizeof là mÙt toán tí cça ngôn ngï C++, nó tr£ vÁ mÙt giá trË h±ng là kích th°Ûc tính b±ng byte cça tham sÑ truyÁn cho nó, ví då sizeof(char) b±ng 1 vì kích th°Ûc cça char là 1 byte.
Con trÏ hàm
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Ûi 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.
// pointer to functions
#include <iostream.h>
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 <<n;
return 0;
} 8 Trong ví då này, minus là mÙt con trÏ toàn cåc trÏ tÛi mÙt hàm có hai tham sÑ kiÃu int, con trÏ này °ãc gám à trÏ tÛi hàm subtraction, t¥t c£ Áu trên mÙt dòng:
int (* minus)(int,int) = subtraction;
Bài 10 : BÙ NhÛ Ùng
Cho ¿n nay, trong các ch°¡ng trình cça chúng ta, t¥t c£ nhïng ph§n bÙ nhÛ chúng ta có thà sí dång là các bi¿n các m£ng và các Ñi t°ãng khác mà chúng ta ã khai báo. Kích cá cça chúng là cÑ Ënh và không thà thay Õi trong thÝi gian ch°¡ng trình ch¡y. Nh°ng n¿u chúng ta c§n mÙt l°ãng bÙ nhÛ mà kích cá cça nó chÉ có thà °ãc xác Ënh khi ch°¡ng trình ch¡y, ví då nh° trong tr°Ýng hãp chúng ta nhn thông tin të ng°Ýi dùng à xác Ënh l°ãng bÙ nhÛ c§n thi¿t.
Gi£i pháp ß ây chính là bÙ nhÛ Ùng, C++ ã tích hãp hai toán tí new và delete à thñc hiÇn viÇc này
Hai toán tí new và delete chÉ có trong C++. Þ ph§n sau cça bài chúng ta s½ bi¿t nhïng thao tác t°¡ng °¡ng vÛi các toán tí này trong C. Toán tí new và new[ ]
à có thà có °ãc bÙ nhÛ Ùng chúng ta có thà dùng toán tí new. Theo sau toán tí này là tên kiÃu dï liÇu và có thà là sÑ ph§n tí c§n thi¿t °ãc ·t trong c·p ngo·c vuông. Nó tr£ vÁ mÙt con trÏ trÏ tÛi §u cça khÑi nhÛ vëa °ãc c¥p phát. D¡ng théc cça toán tí này nh° sau:
pointer = new type
ho·c
pointer = new type [elements]
BiÃu théc §u tien °ãc dùng à c¥p phát bÙ nhÛ chéa mÙt ph§n tí có kiÃu type. LÇnh thé hai °ã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 type.
Ví då:
int * bobby;
bobby = new int [5];
trong tr°Ýng hãp này, hÇ iÁu hành dành ch× cho 5 ph§n tí kiÃu int trong bÙ nhÛ và tr£ vÁ mÙt con trÏ trÏ ¿n §u cça khÑi nhÛ. Vì vy lúc này bobby trÏ ¿n mÙt khÑi nhÛ hãp lÇ gÓm 5 ph§n tí int.
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgdyna1.gif" \* MERGEFORMATINET
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 bÙ nhÛ cho mÙt con trÏ nh° chúng ta vëa làm. iÁu quan trÍng nh¥t là kích th°Ûc cça mÙt m£ng ph£i là mÙt h±ng, iÁu này giÛi h¡n kích th°Ûc cça m£ng ¿n kích th°Ûc mà chúng ta chÍn khi thi¿t k¿ ch°¡ng trình trong khi ó c¥p phát bÙ nhÛ Ùng cho phép c¥p phát bÙ nhÛ trong quá trình ch¡y vÛi kích th°Ûc b¥t kì.
BÙ nhÛ Ùng nói chung °ãc qu£n lí bßi hÇ iÁu hành và trong các môi tr°Ýng a nhiÇm có thà ch¡y mÙt lúc vài ch°¡ng trình có mÙt kh£ nng 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° chúng ta yêu c§u vÛi toán tí new, mÙt con trÏ null (zero) s½ °ãc tr£ vÁ. Vì vy các 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:
int * bobby;
bobby = new int [5];
if (bobby == NULL) {
// error assigning memory. Take measures.
};
Toán tí delete.
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 dùng ¿n nïa thì nó s½ °ãc gi£i phóng à có thà c¥p phát cho các nhu c§u khác trong 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;
BiÃu théc §u tiên nên °ãc dùng à gi£i phóng bÙ nhÛ °ãc c¥p phát cho mÙt ph§n tí và lÇnh thé hai dùng à gi£i phóng mÙt khÑi nhÛ gÓm nhiÁu ph§n tí (m£ng). Trong h§u h¿t các trình dËch c£ hai biÃu théc là t°¡ng °¡ng m·c dù chúng là rõ ràng là hai toán tí khác nhau.
// rememb-o-matic
#include <iostream.h>
#include <stdlib.h>
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<i; n++)
{
cout << "Enter number: ";
cin.getline (input,100); l[n]=atol (input);
}
cout << "You have entered: ";
for (n=0; n<i; n++)
cout << l[n] << ", ";
delete[] l;
return 0;
} 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, NULL là mÙt h±ng sÑ °ãc Ënh ngh)a trong th° viÇn C++ dùng à biÃu thË con trÏ null. Trong tr°Ýng hãp h±ng sÑ này ch°a Ënh ngh)a b¡n có thà tñ Ënh ngh)a nó:
#define NULL 0
Dùng 0 hay NULL khi kiÃm tra con trÏ là nh° nhau nh°ng viÇc dùng NULL vÛi con trÏ °ãc sí dång r¥t rÙng rãi và iÁu này °ãc khuy¿n khích à giúp cho ch°¡ng trình dÅ Íc h¡n.
BÙ nhÛ Ùng trong ANSI-C
Toán tí new và delete là Ùc quyÁn C++ và chúng không có trong ngôn ngï C. Trong 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ó cing hãp lÇ trong C++ và nó v«n còn °ã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);
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ì vy chúng ta ph£i chuyÃn Õi kiÃu sang kiÃu cça con trÏ ích, ví då:
char * ronny;
ronny = (char *) malloc (10);
o¡n mã này c¥p phát cho con trÏ ronny mÙt khÑi nhÛ 10 byte. Khi chúng ta muÑn 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Ñ ph§n tí mong muÑn vÛi kích th°Ûc cça chúng. Tht may m¯n là chúng ta có toá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 * bobby;
bobby = (int *) malloc (5 * sizeof(int));
o¡n mã này c¥p phát cho bobby mÙt khÑi nhÛ gÓm 5 sÑ nguyên kiÃu int, kích cá cça 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°¡ng trình °ãc dËch.
Hàm calloc.
calloc ho¡t Ùng r¥t giÑng vÛi malloc, sñ khác nhau chç y¿u là khai báo m«u cça nó:
void * calloc (size_t nelements, size_t size);
nó sí dång hai tham sÑ thay vì mÙt. Hai tham sÑ này °ãc nhân vÛi nhau à có °ãc kích th°Ûc tÕng cÙng cça khÑi nhÛ c§n c¥p phát. Thông th°Ýng tham sÑ §u tiên (nelements) là sÑ ph§n tí và tham sÑ théc hai (size) là kích th°Ûc cça m×i ph§n tí. Ví då, chúng ta có thà Ënh ngh)a bobby vÛi calloc nh° sau:
int * bobby;
bobby = (int *) calloc (5, sizeof(int));
MÙt iÃm khác nhau nïa giïa malloc và calloc là calloc khßi t¡o t¥t c£ các ph§n tí 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);
tham sÑ pointer nhn 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°Ûc cça khÑi nhÛ mÛi. Hàm này s½ c¥p phát 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°Ûc mÛi cça khÑi nhÛ, trong tr°Ýng hãp này nÙi dung hiÇn thÝi cça khÑi nhÛ °ãc copy tÛi vË trí mÛi à £m b£o dï liÇu không bË m¥t. Con trÏ mÛi trÏ tÛi khÑi nhÛ °ã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.
Hàm free.
Hàm này gi£i phóng mÙt khÑi nhÛ Ùng ã °ãc c¥p phát bßi malloc, calloc ho·c realloc.
void free (void * pointer);
Hàm này chÉ °ãc dùng à gi£i phóng bÙ nhÛ °ãc c¥p phát bßi các hàm malloc, calloc and realloc.
Bài 11 : Các C¥u Trúc
Các c¥u trúc dï liÇu.
MÙt c¥u trúc dï liÇu là mÙt tp hãp cça nhïng kiÃu dï liÇu khác nhau °ãc gÙp l¡i 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;
trong ó model_name là tên cça m«u kiÃu dï liÇu và tham sÑ tùy chÍn object_name mÙt tên hãp lÇ cho Ñi t°ãng. Bên trong c·p ngo·c nhÍn là tên các ph§n tí cça c¥u trúc và kiÃu cça chúng.
N¿u Ënh ngh)a cça c¥u trúc bao gÓm tham sÑ model_name (tuó chÍn), tham sÑ này trß thành mÙt tên kiÃu hãp lÇ t°¡ng °¡ng vÛi c¥u trúc. Ví då:
struct products {
char name [30];
float price;
} ;
products apple;
products orange, melon;
Chúng ta ã Ënh ngh)a c¥u trúc products vÛi hai tr°Ýng: name và price, m×i tr°Ýng có mÙt kiÃu khác nhau. Chúng ta cing ã sí dång tên cça kiÃu c¥u trúc (products) Ã khai báo ba Ñi t°ãng có kiÃu ó : apple, orange và melon.
Sau khi °ãc khai báo, products trß thành mÙt tên kiÃu hãp lÇ giÑng các kiÃu c¡ b£n nh° int, char hay short.
Tr°Ýng tuó chÍn object_name có thà n±m ß cuÑi cça ph§n khai báo c¥u trúc dùng à khai báo trñc ti¿p Ñi t°ãng có kiÃu c¥u trúc. Ví då, à khai báo các Ñi t°ãng apple, orange và melon nh° ã làm ß ph§n tr°Ûc chúng ta cing có thà làm theo cách sau:
struct products {
char name [30];
float price;
} apple, orange, melon;
H¡n nïa, trong tr°Ýng hãp này tham sÑ model_name trß thành tuó chÍn. M·c dù n¿u model_name không °ãc sí dång thì chúng ta s½ không thà khai báo thêm các Ñi t°ãng có kiÃu m«u này.
MÙt iÁu quan trÍng là c§n phân biÇt rõ ràng âu là kiÃu m«u c¥u trúc, âu là Ñi t°ãng c¥u trúc. N¿u dùng các thut ngï chúng ta ã sí dång vÛi các bi¿n, kiÃu m«u là tên kiÃu dï liÇu còn Ñi t°ãng là các bi¿n.
Sau khi ã khai báo ba Ñi t°ãng có kiÃu là mÙt m«u c¥u trúc xác Ënh (apple, orange and melon) chúng ta có thà thao tác vÛi các tr°Ýng t¡o nên chúng. à làm viÇc này chúng ta sí dång mÙt d¥u ch¥m (.) chèn ß giïa tên Ñi t°ãng và tên tr°Ýng. Ví då, chúng ta có thà thao tác vÛi b¥t kì ph§n tí nào cça c¥u trúc nh° là Ñi vÛi các bi¿n chu©n :
apple.name
apple.price
orange.name
orange.price
melon.name
melon.price
m×i tr°Ýng có kiÃu dï liÇu t°¡ng éng: apple.name, orange.name và melon.name có kiÃu char[30], và apple.price, orange.price và melon.price có kiÃu float.
Chúng ta t¡m biÇt apples, oranges và melons à ¿n vÛi mÙt ví då vÁ các bÙ phim:
// example about structures
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
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:
";
printmovie (mine);
cout << "And yours:
";
printmovie (yours);
return 0;
}
void printmovie (movies_t movie)
{
cout << movie.title;
cout << " (" << movie.year << ")
";
}
Enter title: Alien
Enter year: 1979
My favourite movie is:
2001 A Space Odyssey (1968)
And yours:
Alien (1979) Ví då này cho chúng ta th¥y cách sí dång các ph§n tí cça mÙt c¥u trúc và b£n thân c¥u trúc nh° là các bi¿n thông th°Ýng. Ví då, yours.year là mÙt bi¿n hãp lÇ có kiÃu int cing nh° mine.title là mÙt m£ng hãp lÇ vÛi 50 ph§n tí kiÃu chars.
Chú ý r±ng c£ mine and yours Áu °ãc coi là các bi¿n hãp lÇ kiÃu movie_t khi °ãc truyÁn cho hàm printmovie().H¡n nïa mÙt lãi th¿ quan trÍng cça c¥u trúc là chúng ta có thà xét các ph§n tí cça chúng mÙt cách riêng biÇt ho·c toàn bÙ c¥u trúc nh° là mÙt khÑi.
Các c¥u trúc °ã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 xét ¿n kh£ nng xây dñng các m£ng cça chúng.
// array of structures
#include <iostream.h>
#include <stdlib.h>
#define N_MOVIES 5
struct movies_t {
char title [50];
int year;
} films [N_MOVIES];
void printmovie (movies_t movie);
int main ()
{
char buffer [50];
int n;
for (n=0; n<N_MOVIES; n++)
{
cout << "Enter title: ";
cin.getline (films[n].title,50);
cout << "Enter year: ";
cin.getline (buffer,50);
films[n].year = atoi (buffer);
}
cout << "
You have entered these movies:
";
for (n=0; n<N_MOVIES; n++)
printmovie (films[n]);
return 0;
}
void printmovie (movies_t movie)
{
cout << movie.title;
cout << " (" << movie.year << ")
";
}
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
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) Con trÏ trÏ ¿n c¥u trúc
Nh° b¥t kì các kiÃu dï liÇu nào khác, các c¥u trúc có thà °ãc trÏ ¿n bßi con trÏ. 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:
struct movies_t {
char title [50];
int year;
};
movies_t amovie;
movies_t * pmovie;
Þ ây amovie là mÙt Ñi t°ãng có kiÃu movies_t và pmovie là mÙt con trÏ trÏ tÛi Ñi t°ãng movies_t. OK, bây giÝ chúng ta s½ ¿n vÛi mÙt ví då khác, nó s½ giÛi thiÇu mÙt toán tí mÛi:
// pointers to structures
#include <iostream.h>
#include <stdlib.h>
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 << "
You have entered:
";
cout << pmovie->title;
cout << " (" << pmovie->year << ")
";
return 0;
}
Enter title: Matrix
Enter year: 1999
You have entered:
Matrix (1999) o¡n mã trên giÛi thiÇu mÙt iÁu quan trÍng: toán tí ->. ây là mÙt toán tí tham chi¿u chÉ dùng à trÏ tÛi các c¥u trúc và các lÛp (class). Nó cho phép chúng ta không ph£i dùng ngo·c m×i khi tham chi¿u ¿n mÙt ph§n tí cça c¥u trúc. Trong ví då này chúng ta sí dång:
movies->title
nó có thà °ãc dËch thành:
(*movies).title
c£ hai biÃu théc movies->title và (*movies).title Áu hãp lÇ và chúng Áu dùng à tham chi¿u ¿n ph§n tí title cça c¥u trúc °ãc trÏ bßi movies. B¡n c§n phân biÇt rõ ràng vÛi:
*movies.title
nó t°¡ng °¡ng vÛi
*(movies.title)
lÇnh này dùng à tính toán giá trË °ãc trÏ bßi ph§n tí title cça c¥u trúc movies, trong tr°Ýng hãp này (title không ph£i là mÙt con trÏ) nó ch³ng có ý ngh)a gì nhiÁu. B£n d°Û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:
BiÃu théc Mô t£ T°¡ng °¡ng vÛi movies.title Ph§n tí title cça c¥u trúc movies movies->title Ph§n tí title cça c¥u trúc °ãc trÏ bßi movies (*movies).title *movies.title Giá trË °ãc trÏ bßi ph§n tí title cça c¥u trúc movies *(movies.title) Các c¥u trúc lÓng nhau
Các c¥u trúc có thà °ãc ·t lÓng nhau vì vy mÙt ph§n tí hãp lÇ cça mÙt c¥u trúc có thà là mÙt c¥u trúc khác.
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;
Vì vy, sau ph§n khai báo trên chúng ta có thà sí dång các biÃu théc sau:
charlie.name
maria.favourite_movie.title
charlie.favourite_movie.year
pfriends->favourite_movie.year
(trong ó hai biÃu théc cuÑi cùng là t°¡ng °¡ng).
Các khái niÇm c¡ b£n vÁ c¥u trúc °ãc Á cp ¿n trong ph§n này là hoàn toàn giÑng 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 nng cça mÙt lÛp vÛi tính ch¥t ·c tr°ng là t¥t c£ các ph§n 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 trong ph§n HYPERLINK "http://www.diendantinhoc.net/tute/laptrinh/c/cpp-nmthang/bai4_1.htm" 4.1, LÛp.
Bài 12:Các KiÃu Dï LiÇu Do Ng°Ýi Dùng Ënh Ngh)a
Trong bài tr°Ûc chúng ta ã xem xét mÙt lo¡i dï liÇu °ãc Ënh ngh)a bßi ng°Ýi dùng (ng°Ýi lp 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).
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ë khoá typedef, d¡ng théc nh° sau:
typedef existing_type new_type_name ;
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å
typedef char C;
typedef unsigned int WORD;
typedef char * string_t;
typedef char field [50];
Trong tr°Ýng hãp này chúng ta ã Ënh ngh)a bÑn kiÃu dï liÇu mÛi: C, WORD, string_t 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Ç:
C achar, anotherchar, *ptchar1;
WORD myword;
string_t ptchar2;
field name;
typedef có thà hïu dång khi b¡n muÑn Ënh ngh)a mÙt kiÃu dï liÇu °ãc dùng l·p i l·p l¡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 muÑn nó có tên ng¯n h¡n.
Union
Union cho phép mÙt ph§n bÙ nhÛ có thà °ãc truy xu¥t d°Ûi d¡ng nhiÁu kiÃu dï liÇu khác nhau m·c dù t¥t c£ chúng Áu n±m cùng mÙt vË trí trong bÙ nhÛ. Ph§n khai báo và sí dång nó t°¡ng tñ vÛi c¥u trúc nh°ng chéc nng thì khác hoàn toàn:
union model_name {
type1 element1;
type2 element2;
type3 element3;
.
.
} object_name;
T¥t c£ các ph§n tí cça union Áu chi¿m cùng mÙt ch× trong bÙ nhÛ. Kích th°Ûc cça nó là kích th°Ûc cça ph§n tí lÛn nh¥t. Ví då:
union mytypes_t {
char c;
int i;
float f;
} mytypes;
Ënh ngh)a ba ph§n tí
mytypes.c
mytypes.i
mytypes.f
m×i ph§n tí có mÙt kiÃu dï liÇu khác nhau. Nh°ng vì t¥t c£ chúng Áu n±m cùng mÙt ch× trong bÙ nhÛ nên b¥t kì sñ thay Õi nào Ñi vÛi mÙt ph§n tí s½ £nh h°ßng tÛi t¥t c£ các thành ph§n còn l¡i.
MÙt trong nhïng công dång cça union là dùng à k¿t hãp mÙt kiÃu dï liêu c¡ b£n vÛi mÙt m£ng hay các c¥u trúc gÓm các ph§n tí nhÏ h¡n. Ví då:
union mix_t{
long l;
struct {
short hi;
short lo;
} s;
char c[4];
} mix;
Ënh ngh)a ba ph§n tí cho phép chúng ta truy xu¥t ¿n cùng mÙt nhóm 4 byte: mix.l, 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.
INCLUDEPICTURE "http://www.lamdong.gov.vn/truongkt/thuvien/TailieuvaC++hung/HINH/imgunio1.gif" \* MERGEFORMATINET
Các unions vô danh
Trong C++ chúng ta có thà sí dång các unions vô danh. N¿u chúng ta ·t mÙt union trong mÙt c¥u trúc mà không Á tên (ph§n i sau c·p ngo·c nhÍn { }) union s½ trß thành vô danh và chúng ta có thà truy xu¥t trñc ti¿p ¿n các ph§n tí cça nó mà không c§n ¿n tên cça union (có c§n cing không °ãc). Ví då, hãy xem xét sñ khác biÇt giïa hai ph§n khai báo sau ây:
union union vô danh 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; Sñ khác biÇ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 cho union (price) còn trong cái thé hai thì không. Khi truy nhp vào các ph§n tí dollars và yens, trong tr°Ýng hãp thé nh¥t chúng ta vi¿t:
book.price.dollars
book.price.yens
còn trong tr°Ýng hãp thé hai:
book.dollars
book.yens
MÙt l§n nïa tôi nh¯c l¡i r±ng vì nó là mÙt union, hai tr°Ýng dollars và yens Áu 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)
KiÃu dï liÇu liÇ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 mÙt chút, không ph£i kiÃu sÑ hay kiÃu kí tñ ho·c các h±ng true và false. D¡ng théc cça nó nh° sau:
enum model_name {
value1,
value2,
value3,
.
.
} object_name;
Ví då, chúng ta có thà t¡o ra mÙt kiÃu dï liÇu mÛi có tên color à l°u trï các màu vÛi ph§n khai báo nh° sau:
enum colors_t {black, blue, green, cyan, red, purple, yellow, white};
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 color_t, nhïng giá trË có thà cça kiÃu color_t °ãc vi¿t trong 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Ç:
colors_t mycolor;
mycolor = blue;
if (mycolor == green) mycolor = red;
Trên thñc t¿ kiÃu dï liÇu liÇt kê °ãc dËch là mÙt sÑ nguyên và các giá trË cça nó là 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 t°¡ng °¡ng vÛi ph§n tí §u tiên là 0 và các giá trË ti¿p theo cé th¿ tng lên 1, Vì vy, trong kiÃu dï liÇu colors_t mà chúng ta Ënh ngh)a ß trên, white t°¡ng °¡ng vÛi 0, blue t°¡ng °¡ng vÛi 1, green t°¡ng °¡ng vÛi 2 và cé ti¿p tåc nh° th¿.
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Çt kê (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å:
enum months_t { january=1, february, march, april,
may, june, july, august,
september, october, november, december} y2k;
trong tr°Ýng hãp này, bi¿n y2k có kiÃu dï liÇu liÇt kê months_t có thà chéa mÙt trong 12 giá trË të january ¿n december và t°¡ng °¡ng vÛi các giá trË nguyên të 1 ¿n 12, không ph£i 0 ¿n 11 vì chúng ta ã ·t january b±ng 1
NguÓn internet
Bạn đang đọc truyện trên: AzTruyen.Top