Contrỏ
Lậptrìnhnângcao
MộtsốnộidunglấytừslicecủaUriDekel,CMU
Outline
• Cơchếbộnhớ
• Cáchsửdụng
• Cơchếtruyềnthamsố
– Truyềnbằngcontrỏ-Pass-by-pointer
• Lỗithườnggặp
• Cácphéptoán
– Đổikiểu,+,-,++,--
• Contrỏvàmảng
Cơchếbộnhớ
• Contrỏlàmộtbiến
– Nócómộtđịachỉvàlưumộtgiátrị
– Nhưnggiátrịcủanóđượchiểulàđịachỉbộnhớ.
• Xx;
//biếnkiểuX
• X*p; //biếnkiểucontrỏtớigiátrịkiểuX
• Kíchthướccủacontrỏkhôngphụthuộckiểudữliệu
nótrỏtới.
Gángiátrịchocontrỏ
Gángiátrịsố
Gánđịachỉcủabiến
Gángiátrịcontrỏkhác
Gánđịachỉcủahàm(ngoàichươngtrình)
Dereferencing
Lấygiátrịbiếncontrỏtrỏtới
NếupXlàcontrỏthì(*pX)truynhập
vùngnhớpXtrỏtới.
-(*pC1)tươngđươngvớic
-ctươngđươngvới(*(&c))
Dereferencing-Vídụ
Cóthểdùng(*pX)tươngtự
nhưdùngbiếnmàpXtrỏtới
- Đọcgiátrị
- Ghigiátrịmới
- Trảvềgiátrị
pass-by-pointer
void swap(int* px, int* py) {
int c;
c = *px;
*px = *py;
*py = c;
}
int main() {
int a = 20;
int b = 25;
swap(&a, &b);
cout << a << "," << b;
}
return 0
pass-by-pointer
void swap(int* px, int* py) {
int c;
c = *px;
*px = *py;
*py = c;
}
int main() {
int a = 20;
int b = 25;
swap(&a, &b);
cout << a << "," << b;
}
return 0
pass-by-pointer
void swap(int* px, int* py) {
int c;
c = *px;
*px = *py;
*py = c;
}
int main() {
int a = 20;
int b = 25;
swap(&a, &b);
cout << a << "," << b;
}
return 0
pass-by-pointer
void swap(int* px, int* py) {
int c;
c = *px;
*px = *py;
*py = c;
}
int main() {
int a = 20;
int b = 25;
swap(&a, &b);
cout << a << "," << b;
}
return 0
pass-by-pointer
void swap(int* px, int* py) {
int c;
c = *px;
*px = *py;
Thamsốlàcontrỏ
*py = c;
}
int main() {
int a = 20;
int b = 25;
swap(&a, &b);
cout << a << "," << b;
}
return 0
Đốisốlàđịachỉ
Lỗithườnggặp–contrỏchưakhởitạo
• Contrỏchưakhởitạocóthểchứadữliệurác
–địachỉngẫunhiên
• Truynhậpchúngdẫnđếncáclỗighiđèdữ
liệu,ghivàovùngcấmghi….segmenta~on
faults,v.v..
Lỗithườnggặp:truynhậpcontrỏnull
• Tươngđươngtruynhậpđịachỉ0trongbộ
nhớ
Lỗithườnggặp:danglingreferences
• danglingreference:truynhậptớivùngnhớkhông
cònhợplệ
• Vídụ:trảvềcontrỏtớibiếnđịaphương
int* weird_sum(int a, int b) {
int c;
c = a + b;
return &c;
}
• Lờikhuyên:đừnggiữcontrỏtớibiếncóphạmvi
nhỏhơnchínhbiếncontrỏđó.
Đổikiểu
char a = ‘a’;
char* p1 = &a;
int* p2 = (int*)p1;
*p2 = ‘b’;
• Rủiro,khôngkhuyếnkhích
• Trìnhbiêndịchcảnhbáo
• Phảiđổikiểulàdấuhiệucủathiếtkếtồi
void*
• Kiểucontrỏtrỏđếnloạidữliệukhôngxác
địnhkiểu.
• Lậptrìnhviêntựchịutráchnhiệmépkiểu
Hằngcontrỏ
• Đọctừphảisangtrái
constint*p1=&a;//contrỏtớihằngint
int*constp2=&b;//hằngcontrỏ
constint*constp3=&c;//hằngcontrỏtớihằngint
Hằngcontrỏ
Quytắclậptrìnhantoàn
• Khóatấtcảnhữnggìcóthểkhóa
• Gắnconstvàotấtcảnhữnggìkhôngnênbị
sửagiátrị.
Contrỏtớicontrỏ