Trong bài này, bạn sẽ được học về mối quan hệ giữa mảng và con trỏ, và cách sử dụng chúng hiệu quả trong chương trình của bạn.
Con trỏ là các biến chứa địa chỉ. Con trỏ không những có thể chứa được địa chỉ của một biến duy nhất, nó còn có thể chứa được địa chỉ các ô nhớ của một mảng.
Xét ví dụ sau:
int* ptr;
int a[5];
ptr = &a[2]; // &a[2] là địa chỉ của phần tử thứ 3 trong a[5].
Giả sử, con trỏ cần trỏ tới phần tử thứ tư của một mảng, nghĩa là nó chứa địa chỉ của phần tử thứ tư của mảng trong trường hợp trên.
Vì ptr trỏ tới phần tử thứ ba trong trường hợp trên, ptr+1 sẽ trỏ tới phần tử thứ 4.
Bạn có thể nghĩ ptr+1 sẽ trả về địa chỉ của byte tiếp theo. Nhưng điều đó không đúng.
Vì con trỏ ptr là một con trỏ kiểu int và kích thước của int là cố định trên một hệ điều hành (kích thước của int là 4 bytes trên hệ điều hành 64 bits). Vì thế địa chỉ giữa ptr và ptr+1 sẽ lệnh nhau 4 bytes.
Nếu con trỏ ptr trỏ tới char, vậy địa chỉ giữa ptr và ptr+1 sẽ lệch nhau 1 byte, vì kích thước của char là 1 byte.
Ví dụ 1: Con trỏ và mảng trong C++
Chương trình C++ giúp hiển thị địa chỉ của các phần tử trong một mảng sử dụng cả mảng và con trỏ.
#include <iostream>
using namespace std;
int main()
{
float arr[5];
float *ptr;
cout << "Displaying address using arrays: " << endl;
for (int i = 0; i < 5; ++i)
{
cout << "&arr[" << i << "] = " << &arr[i] << endl;
}
// ptr = &arr[0]
ptr = arr;
cout<<"nDisplaying address using pointers: "<< endl;
for (int i = 0; i < 5; ++i)
{
cout << "ptr + " << i << " = "<< ptr + i << endl;
}
return 0;
}
Đầu ra
Displaying address using arrays:
&arr[0] = 0x7fff5fbff880 &arr[1] = 0x7fff5fbff884 &arr[2] = 0x7fff5fbff888 &arr[3] = 0x7fff5fbff88c &arr[4] = 0x7fff5fbff890 Displaying address using pointers: ptr + 0 = 0x7fff5fbff880 ptr + 1 = 0x7fff5fbff884 ptr + 2 = 0x7fff5fbff888 ptr + 3 = 0x7fff5fbff88c ptr + 4 = 0x7fff5fbff890 |
Trong chương trình trên, một con trỏ ptr khác được sử dụng để hiện thị địa chỉ của các phần tử trong mảng arr.
Nhưng các phần tử trong mảng có thể được truy xuất bằng cách sử dụng ký hiệu con trỏ với cùng tên mảng arr. Ví dụ:
int arr[3];
&arr[0] tương đương với arr
&arr[1] tương đương với arr + 1
&arr[2] tương đương với arr + 2
Ví dụ 2: Con trỏ và mảng
Chương trình C++ giúp hiển thị địa chỉ các phần tử của mảng sử dụng ký hiệu con trỏ.
#include <iostream>
using namespace std;
int main() {
float arr[5];
cout<<"Displaying address using pointers notation: "<< endl;
for (int i = 0; i < 5; ++i) {
cout << arr + i <<endl;
}
return 0;
}
Đầu ra
Displaying address using pointers notation:
0x7fff5fbff8a0 0x7fff5fbff8a4 0x7fff5fbff8a8 0x7fff5fbff8ac 0x7fff5fbff8b0 |
Bạn biết rằng con trỏ ptr chứa địa chỉ và biểu thức *ptr trả về giá trị lưu tại địa chỉ đó.
Tương tự, bạn có thể lấy giá trị lưu trong con trỏ ptr+1 bằng cách sử dụng *(ptr+1).
Xem đoạn mã dưới đây:
int ptr[5] = {3, 4, 5, 5, 3};
- &ptr[0] tương đương với ptr và *ptr tương đương với ptr[0]
- &ptr[1] tương đương với ptr + 1 và *(ptr + 1) tương đương với ptr[1]
- &ptr[2] tương đương với ptr + 2 và *(ptr + 2) tương đương với ptr[2]
- &ptr[i] tương đương với ptr + i và *(ptr + i) tương đương với ptr[i]
Ví dụ 3: Con trỏ và mảng trong C++
Chương trình C++ giúp chèn và hiển thị dữ liệu nhập vào sử dụng ký hiệu con trỏ.
#include <iostream>
using namespace std;
int main() {
float arr[5];
// Chèn vào dữ liệu sử dụng ký hiệu con trỏ
cout << "Enter 5 numbers: ";
for (int i = 0; i < 5; ++i) {
cin >> *(arr + i) ;
}
// Hiển thị dữ liệu sử dụng ký hiệu con trỏ
cout << "Displaying data: " << endl;
for (int i = 0; i < 5; ++i) {
cout << *(arr + i) << endl ;
}
return 0;
}
Đầu ra
Enter 5 numbers: 2.5
3.5 4.5 5 2 Displaying data: 2.5 3.5 4.5 5 2 |