Professional Documents
Culture Documents
Chng ny gii thiu v mng, con tr, cc kiu d liu tham chiu v minh ha cch dng chng nh ngha cc bin. Mng (array) gm mt tp cc i tng (c gi l cc phn t) tt c chng c cng kiu v c sp xp lin tip trong b nh. Ni chung ch c mng l c tn i din ch khng phi l cc phn t ca n. Mi phn t c xc nh bi mt ch s biu th v tr ca phn t trong mng. S lng phn t trong mng c gi l kch thc ca mng. Kch thc ca mng l c nh v phi c xc nh trc; n khng th thay i trong sut qu trnh thc hin chng trnh. Mng i din cho d liu hn hp gm nhiu hng mc ring l tng t. V d: danh sch cc tn, bng cc thnh ph trn th gii cng vi nhit hin ti ca cc chng, hoc cc giao dch hng thng ca mt ti khon ngn hng. Con tr (pointer) n gin l a ch ca mt i tng trong b nh. Thng thng, cc i tng c th c truy xut trong hai cch: trc tip bi tn i din hoc gin tip thng qua con tr. Cc bin con tr c nh ngha tr ti cc i tng ca mt kiu c th sao cho khi con tr hy th vng nh m i tng chim gi c thu hi. Cc con tr thng c dng cho vic to ra cc i tng ng trong thi gian thc thi chng trnh. Khng ging nh cc i tng bnh thng (ton cc v cc b) c cp pht lu tr trn runtime stack, mt i tng ng c cp pht vng nh t vng lu tr khc c gi l heap. Cc i tng khng tun theo cc lut phm vi thng thng. Phm vi ca chng c iu khin r rng bi lp trnh vin. Tham chiu (reference) cung cp mt tn tng trng khc gi l bit hiu (alias) cho mt i tng. Truy xut mt i tng thng qua mt tham chiu ging nh l truy xut thng qua tn gc ca n. Tham chiu nng cao tnh hu dng ca cc con tr v s tin li ca vic truy xut trc tip cc i tng. Chng c s dng h tr cc kiu gi thng qua tham chiu ca cc tham s hm c bit khi cc i tng ln c truyn ti hm.
Chapter 5: Mng, con tr, v tham chiu
59
Mi phn t trong mng c th c truy xut thng qua ch s mng. Phn t u tin ca mng lun c ch s 0. V th, heights[0] v heights[9] biu th tng ng cho phn t u v phn t cui ca mng heights. Mi phn t ca mng heights c th c xem nh l mt bin s nguyn. V th, v d t phn t th ba ti gi tr 177 chng ta c th vit:
heights[2] = 177;
Vic c gng truy xut mt phn t mng khng tn ti (v d, heights[-1] hoc heights[10]) dn ti li thc thi rt nghim trng (c gi l li vt ngoi bin). Vic x l mng thng lin quan n mt vng lp duyt qua cc phn t mng ln lt tng phn t mt. Danh sch 5.1 minh ha iu ny bng vic s dng mt hm nhn vo mt mng cc s nguyn v tr v gi tr trung bnh ca cc phn t trong mng.
Danh sch 5.1 1 const int size = 3; 2 double Average (int nums[size]) 3 { 4 double average = 0; 5 6 7 8 } for (register i = 0; i < size; ++i) average += nums[i]; return average/size;
Ging nh cc bin khc, mt mng c th c mt b khi to. Cc du ngoc nhn c s dng c t danh sch cc gi tr khi to c phn cch bi du phy cho cc phn t mng. V d,
int nums[3] = {5, 10, 15};
khi to ba phn t ca mng nums tng ng ti 5, 10, v 15. Khi s gi tr trong b khi to nh hn s phn t th cc phn t cn li c khi to ti 0:
int nums[3] = {5, 10}; // nums[2] khi to ti 0
60
Khi b khi to c s dng hon tt th kch c mng tr thnh d tha bi v s cc phn t l n trong b khi to. V th nh ngha u tin ca nums c th vit tng ng nh sau:
int nums[] = {5, 10, 15}; // khng cn khai bo tng minh // kch c ca mng
Mt tnh hung khc m kch c c th c b qua i vi mng tham s hm. V d, hm Average trn c th c ci tin bng cch vit li n sao cho kch c mng nums khng c nh ti mt hng m c ch nh bng mt tham s thm vo. Danh sch 5.2 minh ha iu ny.
Danh sch 5.2 1 double Average (int nums[], int size) 2 { 3 double average = 0; 4 5 6 7 } for (register i = 0; i < size; ++i) average += nums[i]; return average/size;
nh ngha chui str l mt mng ca 6 k t: nm ch ci v mt k t null. K t kt thc null c chn vo bi trnh bin dch. Tri li,
char str[] = {'H', 'E', 'L', 'L', 'O'};
nh ngha str l mng ca 5 k t. Kch c ca mng c th c tnh mt cch d dng nh vo ton t sizeof. V d, vi mng ar cho m kiu phn t ca n l Type th kch c ca ar l:
sizeof(ar) / sizeof(Type)
61
Bng 5.1
Cch t chc mng ny trong b nh nh l 12 phn t s nguyn lin tip nhau. Tuy nhin, lp trnh vin c th tng tng n nh l mt mng gm ba hng vi mi hng c bn phn t s nguyn (xem Hnh 5.1).
Hnh 5.1
...
32
19
13
28
38
25
20
...
Second row
hng hai
Third hngrow ba
Nh trc, cc phn t c truy xut thng qua ch s mng. Mt ch s ring bit c cn cho mi mng. V d, nhit ma h trung bnh ca thnh ph Sydney (hng u tin ct th hai) c cho bi seasonTemp[0][1]. Mng c th c khi to bng cch s dng mt b khi to lng nhau:
int seasonTemp[3][4] = { {26, 34, 22, 17}, {24, 32, 19, 13}, {28, 38, 25, 20} };
B khi to lng nhau c a chung hn bi v n linh hot v d hiu hn. V d, n c th khi to ch phn t u tin ca mi hng v phn cn li mc nh l 0:
int seasonTemp[3][4] = {{26}, {24}, {28}};
62
};
X l mng nhiu chiu th tng t nh l mng mt chiu nhng phi x l cc vng lp lng nhau thay v vng lp n. Danh sch 5.3 minh ha iu ny bng cch trnh by mt hm tm nhit cao nht trong mng seasonTemp.
Danh sch 5.3 1 const int rows 2 const int columns = 3; = 4;
3 int seasonTemp[rows][columns] = { 4 {26, 34, 22, 17}, 5 {24, 32, 19, 13}, 6 {28, 38, 25, 20} 7 }; 8 int HighestTemp (int temp[rows][columns]) 9 { 10 int highest = 0; 11 12 13 14 15 16 } for (register i = 0; i < rows; ++i) for (register j = 0; j < columns; ++j) if (temp[i][j] > highest) highest = temp[i][j]; return highest;
5.3. Con tr
Con tr n gin ch l a ch ca mt v tr b nh v cung cp cch gin tip truy xut d liu trong b nh. Bin con tr c nh ngha tr ti d liu thuc kiu d liu c th. V d,
int char *ptr1; *ptr2; // tr ti mt int // tr ti mt char
chng ta c th vit:
ptr1 = #
num c khi to ti ptr1. V th, chng ta ni rng ptr1 tr ti num. Hnh 5.2 minh ha s lc iu ny.
Hnh 5.2 Mt con tr s nguyn n gin.
ptr1 num
Vi ptr1 tr ti num th biu thc *ptr1 nhn gi tr ca bin ptr1 tr ti v v th n tng ng vi num. K hiu * l ton t ly gi tr; n nhn con tr nh mt i s v tr v ni dung ca v tr m con tr tr ti. Thng thng th kiu con tr phi khp vi kiu d liu m c tr ti. Tuy nhin, mt con tr kiu void* s hp vi tt c cc kiu. iu ny tht thun tin nh ngha cc con tr c th tr n d liu ca nhng kiu khc nhau hay l cc kiu d liu gc khng c bit. Con tr c th c p (chuyn kiu) thnh mt kiu khc. V d,
ptr2 = (char*) ptr1;
chuyn con tr ptr1 thnh con tr char trc khi gn n ti con tr ptr2. Khng quan tm n kiu ca n th con tr c th c gn ti gi tr null (gi l con tr null). Con tr null c s dng khi to cho cc con tr v to ra im kt thc cho cc cu trc da trn con tr (v d, danh sch lin kt).
5.4. B nh ng
Ngoi vng nh stack ca chng trnh (thnh phn c s dng lu tr cc bin ton cc v cc khung stack cho cc li gi hm), mt vng b nh khc gi l heap c cung cp. Heap c s dng cho vic cp pht ng cc khi b nh trong thi gian thc thi chng trnh. V th heap cng c gi l b nh ng (dynamic memory). Vng nh stack ca chng trnh cng c gi l b nh tnh (static memory). C hai ton t c s dng cho vic cp pht v thu hi cc khi b nh trn heap. Ton t new nhn mt kiu nh l mt i s v c cp pht mt khi b nh cho mt i tng ca kiu . N tr v mt con tr ti khi c cp pht. V d,
int *ptr = new int; char *str = new char[10];
B nh c cp pht t heap khng tun theo lut phm vi nh cc bin thng thng. V d, trong
void Foo (void) { char *str = new char[10]; //... }
khi Foo tr v cc bin cc b str c thu hi nhng cc khi b nh c tr ti bi str th khng. Cc khi b nh vn cn cho n khi chng c gii phng r rng bi cc lp trnh vin. Ton t delete c s dng gii phng cc khi b nh c cp pht bi new. N nhn mt con tr nh l i s v gii phng khi b nh m n tr ti. V d:
delete ptr; delete [] str; // xa mt i tng // xa mt mng cc i tng
Ch rng khi khi nh c xa l mt mng th mt cp du [] phi c chn vo ch nh cng vic ny. S quan trng s c gii thch sau khi chng ta tho lun v lp. Ton t delete nn c p dng ti con tr m tr ti bt c th g v mt i tng c cp pht ng (v d, mt bin trn stack), mt li thc thi nghim trng c th xy ra. Hon ton v hi khi p dng delete ti mt bin khng l con tr. Cc i tng ng c s dng to ra d liu ko di ti khi li gi hm to ra chng. Danh sch 5.4 minh ha iu ny bng cch s dng mt hm nhn mt tham s chui v tr v bn sao ca mt chui.
Danh sch 5.4 1 #include <string.h> 2 char* CopyOf (const char *str) 3 { 4 char *copy = new char[strlen(str) + 1]; 5 6 7 } Ch gii strcpy(copy, str); return copy;
1 4
y l tp tin header chui chun khai bo cc dng hm cho thao tc trn chui. Hm strlen (c khai bo trong th vin string.h) m cc k t trong i s chui ca n cho n (nhng khng vt qu) k t null sau cng. Bi v k t null khng c tnh vo trong vic m nn chng ta cng thm 1 ti tng v cp pht mt mng k t ca kch thc .
65
Hm strcpy (c khai bo trong th vin string.h) sao chp i s th hai n i s th nht ca n theo tng k t mt bao gm lun c k t null sau cng.
V ti nguyn b nh l c gii hn nn rt c th b nh ng c th b cn kit trong thi gian thc thi chng trnh, c bit l khi nhiu khi ln c cp pht v khng c gii phng. Ton t new khng th cp pht mt khi c kch thc c yu cu th n tr v 0. Chnh lp trnh vin phi chu trch nhim gii quyt nhng vn ny. C ch iu khin ngoi l ca C++ cung cp mt cch thc thc t gii quyt nhng vn nh th.
// tr ti phn t u tin
str++ tng str ln mt char (ngha l 1 byte) sao cho n tr ti k t th hai ca chui "HELLO" nhng ngc li ptr++ tng ptr ln mt int (ngha l 4 bytes) sao cho n tr ti phn t th hai ca nums. Hnh 5.3 minh ha s lc iu ny.
Hnh 5.3 Tnh ton con tr.
H E L L O \0 10 20 30 40
str str++
ptr ptr++
V th, cc phn t ca chui "HELLO" c th c tham kho ti nh *str, *(str + 1), *(str + 2), vng vng. Tng t, cc phn t ca nums c th c tham kho ti nh *ptr, *(ptr + 1), *(ptr + 2), v *(ptr + 3). Mt hnh thc khc ca tnh ton con tr c cho php trong C++ lin quan n tr hai con tr ca cng kiu. V d:
int *ptr1 = &nums[1]; int *ptr2 = &nums[3]; int n = ptr2 - ptr1;
// n tr thnh 2
66
Tnh ton con tr cn kho lo khi x l cc phn t ca mng. Danh sch 5.5 trnh by v d mt hm sao chp chui tng t nh hm nh ngha sn strcpy.
Danh sch 5.5 1 void CopyString (char *dest, char *src) 2 { 3 while (*dest++ = *src++) ; 4 }
Ch gii
iu kin ca vng lp ny gn ni dung ca chui src cho ni dung ca chui dest v sau tng c hai con tr. iu kin ny tr thnh 0 khi k t null kt thc ca chui src c chp ti chui dest.
Mt bin mng (nh nums) chnh n l a ch ca phn t u tin ca mng m n i din. V th cc phn t ca mng nums cng c th c tham kho ti bng cch s dng tnh ton con tr trn nums, ngha l nums[i] tng ng vi *(nums + i). Khc nhau gia nums v ptr ch nums l mt hng v th n khng th c to ra tr ti bt c th g na trong khi ptr l mt bin v c th c to ra tr ti cc s nguyn bt k. Danh sch 5.6 trnh by hm HighestTemp ( c trnh by trc trong Danh sch 5.3) c th c ci tin nh th no bng cch s dng tnh ton con tr.
Danh sch 5.6 1 int HighestTemp (const int *temp, const int rows, const int columns) 2 { 3 int highest = 0; 4 5 6 7 8 9 } Ch gii for (register i = 0; i < rows; ++i) for (register j = 0; j < columns; ++j) if (*(temp + i * columns + j) > highest) highest = *(temp + i * columns + j); return highest;
Thay v truyn mt mng ti hm, chng ta truyn mt con tr int v hai tham s thm vo c t kch c ca mng. Theo cch ny th hm khng b hn ch ti mt kch thc mng c th. Biu thc *(temp + i * columns + j) tng ng vi temp[i][j] trong phin bn hm trc.
67
Hm HighestTemp c th c n gin ha hn na bng cch xem temp nh l mt mng mt chiu ca row * column s nguyn. iu ny c trnh by trong Danh sch 5.7.
Danh sch 5.7 1 int HighestTemp (const int *temp, const int rows, const int columns) 2 { 3 int highest = 0; 4 5 6 7 8 } for (register i = 0; i < rows * columns; ++i) if (*(temp + i) > highest) highest = *(temp + i); return highest;
5.6. Con tr hm
Chng ta c th ly a ch mt hm v lu vo trong mt con tr hm. Sau con tr c th c s dng gi gin tip hm. V d,
int (*Compare)(const char*, const char*);
nh ngha mt con tr hm tn l Compare c th gi a ch ca bt k hm no nhn hai con tr k t hng nh l cc i s v tr v mt s nguyn. V d hm th vin so snh chui strcmp thc hin nh th. V th:
Compare = &strcmp; // Compare tr ti hm strcmp
Khi a ch hm c gn ti con tr hm th hai kiu phi khp vi nhau. nh ngha trn l hp l bi v hm strcmp c mt nguyn mu hm khp vi hm.
int strcmp(const char*, const char*);
Vi nh ngha trn ca Compare th hm strcmp hoc c th c gi trc tip hoc c th c gi gin tip thng qua Compare. Ba li gi hm sau l tng ng:
strcmp("Tom", "Tim"); (*Compare)("Tom", "Tim"); Compare("Tom", "Tim"); // gi trc tip // gi gin tip // gi gin tip (ngn gn)
Cch s dng chung ca con tr hm l truyn n nh mt i s ti mt hm khc; bi v thng thng cc hm sau yu cu cc phin bn khc nhau ca hm trc trong cc tnh hung khc nhau. Mt v d d hiu l hm tm
Chapter 5: Mng, con tr, v tham chiu
68
kim nh phn thng qua mt mng sp xp cc chui. Hm ny c th s dng mt hm so snh (nh l strcmp) so snh chui tm kim ngc li chui ca mng. iu ny c th khng thch hp i vi tt c cc trng hp. V d, hm strcmp l phn bit ch hoa hay ch thng. Nu chng ta thc hin tm kim theo cch khng phn bit dng ch sau mt hm so snh khc s c cn. Nh c trnh by trong Danh sch 5.8 bng cch cho hm so snh mt tham s ca hm tm kim, chng ta c th lm cho hm tm kim c lp vi hm so snh.
Danh sch 5.8 1 int BinSearch (char *item, char *table[], int n, 2 int (*Compare)(const char*, const char*)) 3 { 4 int bot = 0; 5 int top = n - 1; 6 int mid, cmp; 7 8 9 10 11 12 13 14 15 16 17 } Ch gii while (bot <= top) { mid = (bot + top) / 2; if ((cmp = Compare(item,table[mid])) == 0) return mid; // tra ve chi so hangg muc else if (cmp < 0) top = mid - 1; // gioi hn tim kiem toi nua thap hon else bot = mid + 1; // gioi han tim kiem toi nua cao hon } return -1; // khong tim thay
Tm kim nh phn l mt gii thut ni ting tm kim thng qua mt danh sch cc hng mc c sp xp. Danh sch tm kim c biu din bi table mt mng cc chui c kch thc n. Hng mc tm kim c biu th bi item. 2 Compare l con tr hm c s dng so snh item vi cc phn t ca mng. 7 mi vng lp, vic tm kim c gim i phn na. iu ny c lp li cho ti khi hai u tm kim giao nhau (c biu th bi bot v top) hoc cho ti khi mt so khp c tm thy. 9 Hng mc c so snh vi mc gia ca mng. 10 Nu item khp vi hng mc gia th tr v ch mc ca phn sau. 11 Nu item nh hn hng mc gia th sau tm kim c gii hn ti na thp hn ca mng. 14 Nu item ln hn hng mc gia th sau tm kim c gii hn ti na cao hn ca mng..
Chapter 5: Mng, con tr, v tham chiu
69
16 Tr v -1 ch nh rng khng c mt hng mc so khp. V d sau trnh by hm BinSearch c th c gi vi strcmp c truyn nh hm so snh nh th no:
char *cities[] = {"Boston", "London", "Sydney", "Tokyo"}; cout << BinSearch("Sydney", cities, 4, strcmp) << '\n';
iu ny s xut ra 2 nh c mong i.
nh ngha num2 nh l mt tham chiu ti num1. Sau nh ngha ny c hai num1 v num2 tham kho ti cng mt i tng nh th chng l cng bin. Cn bit r l mt tham chiu khng to ra mt bn sao ca mt i tng m ch n thun l mt bit hiu cho n. V vy, sau php gn
num1 = 0.16;
c hai num1 v num2 s biu th gi tr 0.16. Mt tham chiu phi lun c khi to khi n c nh ngha: n l mt bit danh cho ci g . Vic nh ngha mt tham chiu ri sau mi khi to n l khng ng lut.
double &num3; // khng ng lut: tham chiu khng c khi to num3 = num1;
Bn cng c th khi to tham chiu ti mt hng. Trong trng hp ny, mt bn sao ca hng c to ra (sau khi bt k s chuyn kiu cn thit no ) v tham chiu c thit lp tham chiu ti bn sao .
int &n = 1; // n tham kho ti bn sao ca 1
L do m n li tham chiu ti bn sao ca 1 hn l tham chiu ti chnh 1 l s an ton. Bn hy xem xt iu g s xy ra trong trng hp sau:
int &x = 1; ++x; int y = x + 1;
1 hng u tin v 1 hng th ba ging nhau l cng i tng (hu ht cc trnh bin dch thc hin ti u hng v cp pht c hai 1 trong cng mt v tr b nh). V th chng ta mong i y l 3 nhng n c th chuyn thnh
Chapter 5: Mng, con tr, v tham chiu
70
4. Tuy nhin, bng cch p buc x l mt bn sao ca 1 nn trnh bin dch m bo rng i tng c biu th bi x s khc vi c hai 1. Vic s dng chung nht ca tham chiu l cho cc tham s ca hm. Cc tham s ca hm thng lm cho d dng kiu truyn-bng-tham chiu, tri vi kiu truyn-bng-gi tr m chng ta s dng n thi im ny. quan st s khc nhau hy xem xt ba hm swap trong Danh sch 5.9.
Danh sch 5.9 1 void Swap1 (int x, int y) 2 { 3 int temp = x; 4 x = y; 5 y = temp; 6 } 7 void Swap2 (int *x, int *y) 8 { 9 int temp = *x; 10 *x = *y; 11 *y = temp; 12 } 13 void Swap3 (int &x, int &y) 14 { 15 int temp = x; 16 x = y; 17 y = temp; 18 } Ch gii
Mc d Swap1 chuyn i x v y, iu ny khng nh hng ti cc i s c truyn ti hm bi v Swap1 nhn mt bn sao ca cc i s. Nhng thay i trn bn sao th khng nh hng n d liu gc. 7 Swap2 vt qua vn ca Swap1 bng cch s dng cc tham s con tr thay th. Thng qua gii tham kho (dereferencing) cc con tr Swap2 ly gi tr gc v chuyn i chng. 13 Swap3 vt qua vn ca Swap1 bng cch s dng cc tham s tham chiu thay th. Cc tham s tr thnh cc bit danh cho cc i s c truyn ti hm v v th chuyn i chng khi cn. Swap3 c thun li thm, c php gi ca n ging nh Swap1 v khng c lin quan n nh a ch (addressing) hay l gii tham kho (dereferencing). Hm main sau minh ha s khc nhau gia cc li gi hm Swap1, Swap2, v Swap3.
int main (void) { int i = 10, j = 20; Swap1(i, j); cout << i << ", " << j << '\n'; Swap2(&i, &j); cout << i << ", " << j << '\n';
71
Swap3(i, j);
Tc dng ca cc nh ngha ny l String tr thnh mt bit danh cho char*, Name tr thnh mt bit danh cho mt mng gm 12 char, v uint tr thnh mt bit danh cho unsigned int. V th:
String Name uint n; str; name; // th tng t nh: char *str; // th tng t nh: char name[12]; // th tng t nh: unsigned int n;
Khai bo phc tp ca Compare trong Danh sch 5.8 l mt minh ha tt cho typedef:
typedef int (*Compare)(const char*, const char*); int BinSearch (char *item, char *table[], int n, Compare comp) { //... if ((cmp = comp(item, table[mid])) == 0) return mid; //... }
typedef m u Compare nh l mt tn kiu mi cho bt k hm vi nguyn mu (prototype) cho trc. Ngi ta cho rng iu ny lm cho du hiu ca BinSearch n gin hn.
72
Bi tp cui chng 5
5.1 nh ngha hai hm tng ng thc hin nhp vo cc gi tr cho cc phn t ca mng v xut cc phn t ca mng:
void ReadArray (double nums[], const int size); void WriteArray (double nums[], const int size);
5.2 5.3
Bng sau c t cc ni dung chnh ca bn loi hng ca cc ng cc im tm. nh ngha mt mng hai chiu bt d liu ny:
Top Flake Cornabix Oatabix Ultrabran S 12g 22g 28g 32g ng 25g 4g 5g 7g Bo 16g 8g 9g 2g Mui 0.4g 0.3g 0.5g 0.2g
Vit mt hm xut bng ny tng phn t mt. 5.4 nh ngha mt hm nhp vo danh sch cc tn v lu tr chng nh l cc chui c cp pht ng trong mt mng v mt hm xut chng:
void ReadNames (char *names[], const int size); void WriteNames (char *names[], const int size);
Vit mt hm khc sp xp danh sch bng cch s dng gii thut sp xp ni bt (bubble sort):
void BubbleSort (char *names[], const int size);
Sp xp ni bt lin quan n vic qut lp li danh sch, trong trong khi thc hin qut cc hng mc k nhau c so snh v i ch nu khng theo th t. Qut m khng lin quan n vic i ch ch ra rng danh sch c sp xp th t. 5.5 Vit li hm sau bng cch s dng tnh ton con tr:
char* ReverseString (char *str) { int len = strlen(str); char *result = new char[len + 1]; for (register i = 0; i < len; ++i) result[i] = str[len - i - 1]; result[len] = '\0'; return result;
73
5.6 5.7
Vit li gii thut BubbleSort (t bi 5.4) sao cho n s dng mt con tr hm so snh cc tn. Vit li cc m sau bng cch s dng nh ngha kiu:
void (*Swap)(double, double); char *table[]; char *&name; usigned long *values[10][20];
74