Con trỏ và mảng trong C++
Trong bài viết dưới đây, eLib sẽ cùng các bạn đi tìm hiểu mối quan hệ giữa con trỏ và mảng trong ngôn ngữ lập trình C++. Bạn sẽ học thêm về một số toán tử của con trỏ, sử dụng các toán tử đó để duyệt mảng. Do đó, bạn sẽ biết thêm 1 cách mới để lặp qua mảng sử dụng con trỏ. Cùng theo dõi nhé!
1. Mối quan hệ giữa con trỏ và mảng
Con trỏ và mảng trong C++ có mối liên hệ chặt chẽ với nhau. Thực tế, con trỏ và mảng có thể thay thế cho nhau trong một số trường hợp. Ví dụ, một con trỏ mà trỏ tới phần đầu của mảng có thể truy cập mảng đó bởi sử dụng: con trỏ số học hoặc chỉ số của mảng.
Ví dụ:
#include <iostream>
using namespace std;
const int MAX = 3;
int main() {
int arr[MAX] = {10, 20, 30};
int *contro;
// contro tro toi mang
contro = arr; // arr dai dien cho gia tri dau tien cua mang arr
for (int i = 0; i < MAX; i++) {
cout << "Dia chi cua arr[" << i << "] = ";
cout << contro << endl;
cout << "Gia tri cua arr[" << i << "] = ";
cout << *contro << endl;
// tro toi vi tri tiep theo
contro++;
}
return 0;
}
Dia chi cua arr[0] = 0x6ffe30
Gia tri cua arr[0] = 10
Dia chi cua arr[1] = 0x6ffe34
Gia tri cua arr[1] = 20
Dia chi cua arr[2] = 0x6ffe38
Gia tri cua arr[2] = 30
Tuy nhiên, con trỏ và mảng không hoàn toàn thay thế được cho nhau. Ví dụ:
#include
using namespace std;
const int MAX = 3;
int main() {
int arr[MAX] = {10, 20, 30};
for (int i = 0; i < MAX; i++) {
*arr = i; // cu phap nay la dung.
arr++; // cu phap nay la sai.
cout << arr[i];
}
return 0;
}
Việc áp dụng toán tử con trỏ * tới biến mảng arr là hợp lệ, nhưng nó không hợp lệ khi sửa đổi giá trị biến arr. Lý do là biến mảng arr là một hằng số con trỏ trỏ tới phần đầu mảng.
Bởi vì, một tên mảng tạo một hằng con trỏ, nó có thể vẫn được sử dụng trong các biểu thức con trỏ, miễn là nó không bị sửa đổi. Ví dụ sau là một lệnh hợp lệ mà gán arr[2] giá trị 100.
*(arr + 2) = 100;
Lệnh trên là hợp lệ và sẽ biên dịch thành công vì arr không bị thay đổi.
2. Sự khác nhau giữa con trỏ và mảng trong C++
Việc sao chép 1 số lượng lớn các phần tử sẽ gây tốn rất nhiều vùng nhớ và giảm hiệu suất.
Vì vậy, khi truyền một mảng cho một hàm, mảng sẽ được chuyển đổi ngầm định thành một con trỏ trỏ đến mảng, và con trỏ được truyền vào hàm:
#include <iostream>
using namespace std;
void printSize(int *array)
{
// tham số array là con trỏ int*
cout << sizeof(array) << '\n'; // kích thước con trỏ int*, không phải kích thước mảng
}
int main()
{
int array[] = { 5, 8, 2, 7 };
cout << sizeof(array) << '\n'; // kích thước mảng: sizeof(int) * array length
printSize(array); // đối số array được chuyển thành con trỏ int* tại đây
system("pause");
return 0;
}
Output:
14
6
Lưu ý rằng điều này xảy ra ngay cả khi tham số được khai báo là một mảng cố định:
void printSize(int a[100]);
void printSize(int a[]);
Chú ý: Để tránh nhầm lẫn về việc đang thao tác với mảng hay con trỏ, ưu tiên sử dụng cú pháp con trỏ (*) cho tham số hàm là mảng.
Trên đây là bài viết của eLib.VN về Con trỏ và mảng trong C++. Việc sử dụng con trỏ để quản lý mảng một chiều thường được dùng khi viết các hàm thao tác với mảng. Chúc các bạn thuần thục và sử dụng dễ dàng hơn các thao tác liên quan đến mảng và con trỏ.
Tham khảo thêm
- doc Con trỏ trong C++
- doc Con trỏ NULL trong C++
- doc Con trỏ số học trong C++
- doc Mảng con trỏ trong C++
- doc Con trỏ tới con trỏ & truyền con trỏ tới hàm trong C++
- doc Trả về con trỏ từ hàm trong C++