Bài 13: Con trỏ là gì? Cách sử dụng con trỏ trong lập trình C

Con trỏ là gì Cách sử dụng con trỏ trong lập trình C

Trong bài này chúng ta sẽ học các sử dụng con trỏ trong lập trình C. Đây là một kiến thức khá khó trong lập trình, yêu cầu các bạn phải hiểu về bộ nhớ và địa chỉ trong c.

Bài 13 Trong Học lập trình C từ A tới Z

Địa chỉ của biến

Mỗi biến khi khai báo sẽ được dành ra một hoặc nhiều ô nhớ trong bộ nhớ, để truy cập được ô nhớ này chúng ta cần địa chỉ của nó.

Điều này tương tự như bạn đăng kí hộ khẩu vậy khi đó Số XX Đường YY Quận ZZ chính là địa chỉ của nhà bạn.

Khi 1 người đến nhà bạn người ta có 2 cách để tìm

  • Tìm theo tên biến: Nhà anh A
  • Tìm theo địa chỉ: Địa chỉ Số XX Đường YY Quận ZZ

Địa chỉ là bất biến, nhưng nó có thể cho Anh B, Anh C, Anh D thuê lại địa chỉ đó. Và để truy cập địa chỉ của biến chúng ta sử dụng con trỏ.

Để xem địa chỉ của biến chúng ta sử dụng toán tử &, ví dụ: address = &nha_anh_a;

VD: In ra địa chỉ của biến

#include <stdio.h>

int main ()
{
   int  nha_anh_a;
   char nha_anh_b[25];
   printf("Dia chi cua nha anh A la: %x\n", &nha_anh_a  );
   printf("Dia chi cua nha anh B la: %x\n", &nha_anh_b  );
   return 0;
}

Kết quả

address pointer

Con trỏ là gì?

Một con trỏ – pointer là một biến mà trong đó giá trị của nó là địa chỉ của biến khác.

Thực chất con trỏ cũng là 1 biến. nó cũng được cấp phát 1 ô nhớ để lưu giá trị, nhưng điểm khác biệt là: giá trị của biến con trỏ là địa chỉ của biến khác

Các bạn chỉ cần nhớ rõ điều này, sẽ không bị rối não khi học con trỏ.

vi du con tro trong c

 

Cách khai báo con trỏ

Giống như các biến và hằng số, bạn phải khai báo con trỏ trước khi bạn có thể sử dụng nó để lưu trữ bất kì địa chỉ của biến nào. Dạng tổng quát của việc khai báo con trỏ như sau:

<kiu dliu> * <tên biến>;

VD: int *addr = &nha_anh_a; //khai báo trỏ tới địa chỉ của biến nhà anh A

Dấu * trước tên biến là ký hiệu báo cho trình biên dịch biết ta đang khai báo con trỏ.

VD:

Ta thấy rằng:
  • Địa chỉ nhà anh A = Gia trị con trỏ address_A. Tương ứng với lệnh khởi tạo int *address_A = &nha_anh_a;
  • Địa chỉ của con trỏ address_A lại là một địa chỉ khác nằm trong ô nhớ. Thế nên ta có thể sử dụng 1 con trỏ khác để trỏ về địa chỉ của con trỏ address_A.

Cách sử dụng con trỏ

Thay đổi giá trị biến bằng con trỏ

Như chúng ta đã học, để thay đổi giá trị của biến chúng ta sử dụng lệnh gán. VD: int var = 10;

Để thay đổi giá trị này có 2 cách:

  • Dùng lệnh gán: var = 20;
  • Hoặc dùng con trỏ: *ptr = 20;

Dấu * t trong trường hợp này ý nghĩa đó là: Gán giá trị vào địa chỉ mà con trỏ ptr đang trỏ tới.

Lưu ý: Các bạn phải phân biệt được dấu * trong trường hợp tạo ra con trỏ và dấu * trong trường hợp trỏ tới giá trị ô nhớ (địa chỉ) mà con trỏ đang lưu giữ nhé

con tro pointer

Trong bài này, chúng ta sẽ thay đối giá trị Nhà anh A bằng con trỏ address_A nhé

#include <stdio.h>

int main ()
{
    int nha_anh_a = 10;
    int *address_A = &nha_anh_a;

    printf("Dia chi cua nha anh A la: %x\n", &nha_anh_a  );
    printf("Gia tri cua nha anh A la: %d\n", nha_anh_a  );
    printf("Gia tri cua con tro address_A la: %x\n", address_A);

    *address_A  = 20;
    printf("\n");
    printf("Dia chi cua nha anh A la: %x\n", &nha_anh_a  );
    printf("Gia tri cua nha anh A la: %d\n", nha_anh_a  );
    printf("Gia tri cua con tro address_A la: %x\n", address_A);

    return 0;
}

Kết quả

address pointer 3

Ta thấy rằng, khi dùng lệnh *address_A = 20; thì giá trị của biến nha_anh_a thay đổi, còn giá trị của con trỏ address_A không thay đổi

Con trỏ của con trỏ hay con trỏ cấp 2

Khái niệm này nghe có vẻ lằng nhằng nhưng thực ra cũng rất đợn giản.
Như phần trước đã nói, con trỏ thực ra cũng là một biến, nó cũng có địa chỉ và giá trị. Thế nên nó cũng sẽ có thể được gọi từ con trỏ khác. Như sau:

VD:

int main ()
{
    int nha_anh_a = 10;
    int *address_A = &nha_anh_a;
    int **quan_ly = &address_A;

    printf("Dia chi cua nha anh A la: %x\n", &nha_anh_a  );
    printf("Gia tri cua nha anh A la: %d\n", nha_anh_a  );
    printf("Gia tri cua con tro address_A la: %x\n", address_A);

    **quan_ly  = 20;
    printf("\n");
    printf("Dia chi cua nha anh A la: %x\n", &nha_anh_a  );
    printf("Gia tri cua nha anh A la: %d\n", nha_anh_a  );
    printf("Gia tri cua con tro address_A la: %x\n", address_A);

    return 0;
}

Kết quả

con tro bac 2

Giải thích: Ta khai báo 1 con trỏ bậc 2 với dấu ** , lưu giữ giá trị của biến con trỏ address_A.

Sau đó tiến hành thay đổi giá trị của biến mà con trỏ address_A trỏ tới một cách gián tiếp bằng con trỏ cấp 2 quan_ly

con tro cap 2 2

Con trỏ NULL trong C

Có một cách thực hành tốt khi chúng ta gán giá trị NULL cho biến con trở trong trường hợp bạn không có địa chỉ chính xác để được gán. Điều này thường xảy ra trong quá trình khai báo. Một con trỏ được gán giá trị NULL được gọi là con trỏ null.

Con trỏ null là một hằng số với giá trị 0 được định nghĩa trong một vài thư viện chuẩn. Xem chương trình dưới đây:

#include <stdio.h>

int main ()
{
   int  *contro = NULL;
   printf("Gia tri cua contro la: %x\n", contro  );
   return 0;
}

Biên dịch và chạy chương trình C trên sẽ cho kết quả:

Gia tri cua contro la: 0

Kết

Con trỏ trong lập trình là một khái niệm nghe thì có vẻ phức tạp, nhưng hãy nghĩ về nó một cách đơn giản nhất. Bạn sẽ thấy nó cũng không rối não như những gì bạn tưởng tượng.
Và tất nhiên phải làm việc nhiều với con trỏ chúng ta mới hiểu rõ tường tận nhất về chúng

Nếu thấy có ích hãy chia sẻ bài viết và tham gia nhóm Nghiện Lập Trình để giao lưu và học hỏi nhé

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *