Chào các bạn !
Mình thấy có nhiều bạn đang không rõ về vấn đề này. Là một tay ngang, mình sẽ giải thích những gì mình biết về nó. Hy vọng giúp ích các bạn. Nếu có thiếu sót hay sai, các bạn chia sẻ thêm.
Lets go !
-
Việc đầu tiên các bạn nên hiểu về cách máy tính lưu dữ liệu trên RAM.
Bộ nhớ RAM của máy tính được cấu tạo từ rất nhiều ô nhớ. Mỗi ô nhớ này lưu được 8bit dữ liệu, tức là 1 byte. bộ nhớ RAM 1G sẽ có 1 tỷ ô nhớ này. Vị trí các ô nhớ hoàn toàn xác định và cố định và được phân biệt, truy xuất thông qua địa chỉ của nó. -
Mảng.
Mảng là một số biến cùng loại được sắp xếp cạnh nhau liên tục trên bộ nhớ RAM. Các phần tử trong mảng sẽ được phân biệt với nhau bởi chỉ số của phần tử đó.
Khi ta khai báo 1 mảng :
unsigned int arr[n];
Máy tính sẽ xác định số ô nhớ cần thiết và cấp số ô nhớ đó trên RAM trong vùng RAM chưa được sử dụng cho chương trình ( ở đây là 4*n ô nhớ vì mỗi biến int là chiếm 4 ô nhớ - 4byte) . Các ô nhớ này liên tiếp nhau và do đó địa chỉ của nó cũng liên tiếp nhau. Vị trí các ô nhớ này ở đâu trên RAM thì chương trình hoàn toàn kiểm soát được.
Vị trí (địa chỉ ) của mảng này ở đâu là cố định, không thể thay đổi được trừ khi tạo mảng mới.
- Con trỏ.
Khi nói về con trỏ thường chúng ta cảm thấy nó hư hư thực thực. Vậy nó là gì ?
Nó là biến lưu địa chỉ của ô nhớ trên RAM. Khi chúng ta có được địa chỉ của một ô nhớ chúng ta sẽ làm việc được với dữ liệu của ô nhớ đó.
Khi chúng ta khai báo :
unsigned int *ptr = new unsigned int[n];
Máy tính sẽ cấp cho chương trình 4*n ô nhớ trên RAM và báo cho chương trình biết vị trí của nó ở đâu, chính là giá trị của con trỏ ptr. Con trỏ ptr sẽ lưu vị trí của mảng.
Khi ta khai báo :
unsigned int Arr[n];
unsigned int *ptr = &Arr;
Thì máy tính sẽ lấy vị trí (địa chỉ) của mảng Arr lưu vào biến con trỏ ptr. Và khi chúng ta có được vị trí của mảng trên RAM thông qua con trỏ thì chúng ta có thể làm việc với mảng mà con trỏ đang trỏ tới.
Đến đây các bạn có thể hình dung mảng giống như 1 folder trên máy tính, có có chứa trong đó 1 hoặc nhiều file.
Còn con trỏ là cái shortcut của folder đó. Bạn có thể chỉnh cho cái shortcut đó chỉ đến folder khác.
- Điểm khác biệt của con trỏ và mảng.
Mảng : Được cấp phát trên vùng RAM chưa sử dụng, số phần tử cố định, địa chỉ trên RAM cố định (trừ khi khai báo mảng mới), không được phép truy xuất ngoài phạm vi mảng.
Khi chúng ta khai báo mảng 10 phần tử, chúng ta chỉ truy xuất được trong phạm vi đó, tức là từ phần tử 0 đến 9. Ngoài khoảng này, chương trình báo lỗi out of index.
Con trỏ : Có thể trỏ tới bất kì vị trí nào trên RAM, không có phần tử, địa chỉ trên RAM cố định, địa chỉ trỏ tới có thể thay đổi sau khi khai báo.
Chúng ta có thể thay đổi địa chỉ mà con trỏ đang trỏ tới một cách dễ dàng như sau :
unsigned int Arr1[n];
unsigned char Arr[m];
unsigned int *ptr = &Arr1[0]; // con trỏ đang trỏ tới Arr1[0]
ptr=(unsigned char*)&Arr2[0]; // lúc này nó lại trỏ tới Arr2[0];
ptr=1234; // lúc này nó lại trỏ tới ô nhớ có địa chỉ 1234 trên RAM.
- Chú ý khi dùng con trỏ.
Mặc dù con trỏ có nhiều ưu điểm như ta có thể trỏ tới địa chỉ bất kì trên RAM và làm việc với dữ liệu có địa chỉ được trỏ tới (khi hack game chẳng hạn là ta phải dùng con trỏ để trỏ tới vùng dữ liệu của game) hoặc trong một số trường hợp chúng ta sẽ có được tốc độ cao hơn trong xử lý nhưng bạn sẽ thấy một số ngôn ngữ không cho dùng con trỏ và sẽ báo unsafe - không an toàn. Vậy tại sao ?
Do con trỏ có thể trỏ tới bất kì chỗ nào trên RAM nên nó có thể thay đổi dữ liệu của chương trình khác và gây cho máy tính làm việc không bình thường.
-> Con trỏ là nguy hiểm nếu không kiểm soát được.
____ End ____