Xem mẫu

  1. Updatesofts.com Ebooks Team 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ì v y &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 nh n 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 năng 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ì v y, 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. value1==10 / value2==20 // my first pointer #include Trang 56
  2. Updatesofts.com Ebooks Team int main () { int value1 = 5, value2 = 15; int * mypointer; mypointer = &value1; *mypointer = 10; mypointer = &value2; *mypointer = 20; cout
  3. Updatesofts.com Ebooks Team 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 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ì v y 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ó cũng 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ì v y, 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 cũng 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 : 10, 20, 30, 40, 50, // more pointers #include int main () { int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n
  4. Updatesofts.com Ebooks Team } 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 tương ñương và h p l b t k a là m là hoàn toàn 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ì v y, 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: Trang 59
  5. Updatesofts.com Ebooks Team 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: 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. Trang 60
  6. Updatesofts.com Ebooks Team 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ì v y 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 cũng 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 tăng (++) và gi m (--) ñ u có quy n ưu tiên l n hơn toán t tham chi u (*), vì v y 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à tăng 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 tăng (++) ñ 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 tăng lên 1. L nh này tương ñương v i: *p = *q; p++; q++; Trang 61
  7. Updatesofts.com Ebooks Team 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: ð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ì v y chúng ta ph i dùng ñ n toán t chuy n ki u d li u hay phép gán ñ chuy n con tr không ki u thành m t con tr tr t i m t lo i d li u c th . M t trong nh ng ti n ích c a nó là cho phép truy n tham s cho hàm mà không c n ch rõ ki u 6, 10, 13 // integer increaser #include void increase (void* data, int Trang 62
  8. Updatesofts.com Ebooks Team 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