+1

Con trỏ trong C/C++

Bản chất của con trỏ

Con trỏ là một loại biến đặc biệt mà chỉ có ở họ ngôn ngữ C/C++.
Mỗi biến trong một chương trình đều có 2 thuộc tính cơ bản: địa chỉ và giá trị. Địa chỉ 1 dãy kí tự được viết ở hệ Hexa nhằm giúp chương trình kiểm soát biến. Giá trị là thông tin của biến.
Còn con trỏ là một loại biến đặc biệt, nó chứa tới 3 thuộc tính: địa chỉ , giá trị và miền giá trị
Con trỏ là một biến mà giá trị của nó là địa chỉ của một biến khác.
Nghĩa là sao? Biến thông thường sẽ như ví dụ sau:

int n = 10;
char c='H';

Giá trị của biến n là 10, giá trị của biến c là 'H'. Còn con trỏ, giá trị của nó có dạng như thế nào?
Ví dụ , ta khởi tạo 1 biến int a=1;, kết quả sẽ như sau:


Trong đó, & là toán tử để lấy địa chỉ của một biến.

Bây giờ, ta khởi tạo một biến con trỏ aPtr và gán giá trị cho nó là biến a, kết quả như sau:

Trong đó, toán tử * là toán tử để lấy giá trị của một biến.
Bạn có để ý rằng, miền giá trị của con trỏ aPtr chính là địa chỉ của biến a không?
Khi ta gán địa chỉ của một biến cho một con trỏ, tức là ta đã cho phép con trỏ dùng chung ô nhớ của biến đó. Và lúc đó mọi thay đổi trên biến sẽ dẫn đến thay đổi trên con trỏ và ngược lại. Giống như lúc đo có một sợi dây liên kết giữa chúng vậy.
Với phép khởi tạo và gán int *aPtr = &a; trên, ta nói: con trỏ aPtr đang trỏ đến biến a;

Sử dụng con trỏ

Thông thường, sau khi khai báo một con trỏ, ta phải gán cho nó một địa chỉ của biến nào đó thì mới sử dụng được. Khi ấy con trỏ mới bắt đầu có hiệu lực, nếu không thì chỉ làm cảnh thôi😅
Sau khi gán địa chỉ của biến khác cho con trỏ, nó sẽ dùng ké ô nhớ của biến kia (có thể truy xuất dữ liệu, tăng, giảm giá trị biến,..). Giống như khi bạn và người yêu bạn về chung một nhà ấy, đi chơi thì cùng đi, ăn thì cùng ăn...😂
Note: có thể gán con trỏ cho con trỏ, khi ấy 1 sợi dây liên kết giữa chúng hình thành.
Một câu hỏi rất được quan tâm là: vậy thì ta cứ phải gán cho con trỏ một địa chỉ thì mới dùng được à, mà cứ đi dùng ké nhà người khác mãi sao🙄? Có cách nào khác để sử dụng cũng như khẳng định vị thế cho con trỏ không?
Và câu trả lời là...Có. Lúc này, ta cấp phát bộ nhớ động cho nó. Bằng cách này, con trỏ sẽ được khởi tạo một vùng nhớ sẵn, thay vì phải đi dùng ké.

  • Con trỏ cấp phát động
    Cú pháp khai báo con trỏ cấp phát động như sau:
    <kiểu DL> <tên con trỏ> = new <kiểu DL>;
    Ví dụ: int *con_tro = new int;

    Lưu ý: Đây là cách khai báo trong C++, trong C sẽ khai báo khác với các hàm realloc, calloc, malloc và phức tạp hơn một chút.
    Note: cách khai báo này rất hay được áp dụng cho mảng.
    Cú pháp: <kiểu DL> *<tên con trỏ> = new <kiểu DL>;

    Hãy xem ví dụ sau:

Cách này cực kì có ích khi ta muốn tối ưu hóa hiệu suât của máy tính. Ta chỉ cung cấp số lượng ô nhớ đúng bằng số lượng ta cần. Như hình trên, ta chỉ định cấp phát n ô nhớ.
Cần biết rằng 1 mảng chính là một dãy các phần tử cùng kiểu và được quản lí bởi 1 con trỏ. Địa chỉ của phần tử đầu tiên trong mảng chính là địa chỉ của mảng đó.

Kết

Tóm lại, con trỏ là một biến mà giá trị của nó là địa chỉ của một biến khác. Ta dùng nó để nâng cao hiệu quả sử dụng bộ nhớ và sử dụng một cách linh hoạt. Vậy là chúng ta hiểu kha khá bản chất của con trỏ rồi. Đây cũng là phần kiến thức mà khá trừu tượng, nhưng dần dần rồi bạn sẽ làm chủ được nó, cố lên! Có một nguồn học ngôn ngữ C/C++ khá hay, bạn có thể tham khảo tại đây:
Nguồn 1
Nguồn 2
Mong được các bạn đóng góp, bổ sung ý kiến!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.