Ta có thể lấy giá trị mà con trỏ trỏ đến một cách trực tiếp, nó cần thiết khi chúng ta muốn khai báo kiểu dữ liệu tương ứng với nó. Cú pháp khai báo con trỏ như sau:
Ví dụ
int *pint; char *pchar;
float *pfloat; |
Trong ví dụ trên, chúng ta khai báo ba con trỏ có kiểu dữ liệu khác nhau, nhưng về bản chất, chúng – pint, pchar, pfloat là những con trỏ và chúng có cùng số ô nhớ trong không gian bộ nhớ (trên hệ thống windows 32bit, chúng chiếm 4byte – bạn có thể sử dụng hàm
sizeof để kiểm tra kích thước thực trên hệ thống máy tính của bạn). Tuy nhiên, dữ liệu mà các con trỏ trỏ đến lại có kích thước khác nhau tương ứng với int, char và float mà chúng ta đã học (tương ứng trên hệ windows 32 bit lần lượt là 4, 1, 4).
Ví dụ | Kết quả |
#include using namespace std;
int main()
{
int *pint;
long long *pll;
cout<<
cout<<
cout<<
cout<<
return 0;
} | 4 4
4
8 |
Giải thích: trong ví dụ này, biến pint và pll dùng để lưu địa chỉ của con trỏ, chúng luôn có kích thước mặc định là 4 bytes. Các biến *pint và *pll là các biến trỏ vào các kiểu dữ liệu int và long long tương ứng. Biến int có kích thước 4 bytes và biến long long có kích thước 8 bytes.
Lưu ý, trong khai báo này, dấu * không phải là toán tử tham chiếu ngược, nó đơn thuần là con trỏ. Chúng có cùng kí hiệu, nhưng là hai thứ hoàn toàn khác nhau.
Ví dụ | Kết quả |
#include using namespace std;
int main()
{
int fval, sval;
int *p;
p = &fval;
*p = 10;
p = &sval;
*p=20;
cout<<
cout<<
return 0;
} | 10 20 |
Giải thích: Bằng cách sử dụng biến con trỏ *p, chúng ta đã làm thay đổi giá trị của biến fval và sval. Biến trỏ này trong lần đầu tiên, nó trỏ đến địa chỉ của biến fval, từ ô nhớ của địa chỉ này, nó ánh xạ đến giá trị mà ta khởi gán là 10. Do đó, giá trị của biến fval cũng ánh xạ tương ứng đến 10. Tương tự cho biến sval.
Để minh họa con trỏ có thể tạo ra sự sai khác giá trị trong cùng một chương trình, chúng ta tham khảo ví dụ sau
Ví dụ | Kết quả |
#include using namespace std;
int main()
{
int fval=5, sval=15;
int *p1, *p2;
p1 = &fval;
p2 = &sval;
*p1 = 10;
*p2 = *p1;
p1 = p2;
*p1 = 20;
cout<<
cout<<
return 0;
} | 10 20 |
Giải thích: Các biến *p1 và *p2 trỏ đến địa chỉ của fval và sval. Như vậy, *p1=10, sẽ tạo cho vùng địa chỉ mà nó trỏ đến, ánh xạ đến giá trị 10 (có nghĩa là tại thời điểm này fval = 10, sval = 15). Dòng lệnh *p2=*p1 sẽ làm cho biến trỏ *p2 trỏ đến giá trị mà *p1 trỏ đến (tức *p2 = 10). Và tại thời điểm này, biến sval có giá trị tương ứng là 10 (do ánh xạ theo vùng địa chỉ mà *p2 trỏ đến). Dòng lệnh p1=p2 sẽ gán địa chỉ mà p2 trỏ đến (địa chỉ của biến sval) cho địa chỉ mà p1 trỏ đến (địa chỉ của biến fval), như vậy, tại thời điểm này sval=fval=10. Dòng lệnh *p1=20 sẽ tạo cho vùng địa chỉ mà *p1 trỏ đến (cũng là địa chỉ của biến *p2 và fval) ánh xạ đến giá trị 20, nghĩa là fval = 20. Vì vậy, khi kết thúc chương trình, fval = 10, sval = 20. Cả hai biến *p1 và *p2 đều trỏ đến địa chỉ của biến fval.
Một con trỏ được khai báo dữ liệu của nó là một loại dữ liệu nào đó. Do đó, nếu có một biến không phải là con trỏ có cùng kiểu dữ liệu, chúng ta có thể sử dụng khai báo thu gọn
No comments:
Post a Comment