0965303260
TP. Hồ Chí Minh

[C]. Con Trỏ Cấp 2

Biến con trỏ cũng là một biến và cũng cần có địa chỉ, để lưu được địa chỉ của biến con trỏ bạn cần con trỏ cấp 2 hay con trỏ tới con trỏ.

NỘI DUNG : 

  • Con Trỏ Cấp 2
  • Hàm Và Con Trỏ Cấp 2
  • Video Tutorial

con trỏ

1. Con Trỏ Cấp 2

Biến con trỏ cũng có địa chỉ riêng của nó, và nếu bạn muốn lưu giữ địa chỉ này thì bạn cần sử dụng con trỏ tới con trỏ. 

Tương tự nếu bạn muốn lưu địa chỉ của con trỏ cấp 2 thì bạn cần con trỏ cấp 3, muốn lưu địa chỉ của con trỏ cấp 3 thì cần con trỏ cấp 4...

Số lượng dấu * trước tên biến sẽ thể hiện con trỏ là cấp 1, 2 , hay 3. Ví dụ *ptr là con trỏ cấp 1, **ptr là con con trỏ cấp 2 và ***ptr là con trỏ cấp 3

con trỏ cấp 2

Ví dụ 1 : Con trỏ cấp 2 

#include "stdio.h"

int main(){
    int N = 28;
    int *ptr1 = &N;
    // con trỏ cấp 2 ptr2 lưu địa chỉ con trỏ ptr1
    int **ptr2 = &ptr1; 
    printf("Dia chi cua N : %d\n", &N);
    printf("Gia tri cua ptr1 : %d\n", ptr1);
    printf("Dia chi cua ptr1 : %d\n", &ptr1);
    printf("Gia tri cua ptr2 : %d\n", ptr2);
    printf("Giai tham chieu ptr2 : %d\n", *ptr2);
    printf("Giai tham chieu 2 lan ptr2 : %d\n", **ptr2);
    return 0;
}

Output : 

Dia chi cua N : 6487572
Gia tri cua ptr1 : 6487572
Dia chi cua ptr1 : 6487576
Gia tri cua ptr2 : 6487576
Giai tham chieu ptr2 : 6487572
Giai tham chieu 2 lan ptr2 : 28

Chú ý code chạy trên máy của bạn sẽ có thể có output khác. 

Giải thích : 

Con trỏ ptr1 lưu địa chỉ của N là 6487572 hay giá trị của ptr1 là 6487572. 

Con trỏ ptr2 trỏ tới ptr1 nên giá trị của ptr2 chính là địa chỉ của ptr1 là 6487576

Giải tham chiếu ptr2 sẽ giúp bạn truy xuất giá trị của biến mà ptr2 đang trỏ tới, mà ptr2 đang trỏ tới 1 nên giá trị khi giải tham chiếu ptr2 sẽ là ptr1 hay địa chỉ của N

Giải tham chiếu 2 lần sẽ giúp bạn truy xuất giá trị của N, giải tham chiếu lần 1 ta đang truy xuất tới ptr1, giải tham chiếu 2 lần sẽ truy xuất tới N

Ví dụ 2 : Con trỏ cấp 3

con trỏ cấp 3

#include "stdio.h"

int main(){
    int N = 28;
    int *ptr1 = &N;
    // con trỏ cấp 2 ptr2 lưu địa chỉ con trỏ ptr1
    int **ptr2 = &ptr1; 
    int ***ptr3 = &ptr2;
    printf("Dia chi cua N : %d\n", &N);
    printf("Dia chi cua ptr1 : %d\n", &ptr1);
    printf("Dia chi cua ptr2 : %d\n", &ptr2);
    printf("Gia tri cua ptr1 : %d\n", ptr1);
    printf("Gia tri cua ptr2 : %d\n", ptr2);
    printf("Gia tri cua ptr3 : %d\n", ptr3);
    printf("Giai tham chieu ptr3 : %d\n", *ptr3);
    printf("Giai tham chieu 2 lan ptr3 : %d\n", **ptr3);
    printf("Giai tham chieu 3 lan ptr3 : %d\n", ***ptr3);
    return 0;
}

Output : 

Dia chi cua N : 6487564
Dia chi cua ptr1 : 6487568
Dia chi cua ptr2 : 6487576
Gia tri cua ptr1 : 6487564
Gia tri cua ptr2 : 6487568
Gia tri cua ptr3 : 6487576
Giai tham chieu ptr3 : 6487568
Giai tham chieu 2 lan ptr3 : 6487564
Giai tham chieu 3 lan ptr3 : 28


2. Hàm Và Con Trỏ Cấp 2

Để thay đổi giá trị của biến thông thường bằng hàm ta dùng con trỏ, vậy để thay đổi biến con trỏ ta cần cùng tới con trỏ cấp 2. Tương tự bạn muốn thay đổi giá trị của con trỏ cấp 2 thông qua hàm ta cần xây dựng tham số là con trỏ cấp 3.

Nhiều bạn nhầm tưởng để thay đổi giá trị của biến thông qua hàm chỉ cần sử dụng con trỏ, điều này chỉ đúng khi bạn muốn thay đổi giá trị của biến thông thường, còn thay đổi con trỏ thì không thể chỉ dùng con trỏ.

Ví dụ 1 : Thay đổi giá trị của con trỏ thông qua hàm

#include "stdio.h"

void change(int *x, int *y){
    x = y;
}
int main(){
    int N = 28, M = 56;
    int *ptr1 = &N;
    int *ptr2 = &M;
    printf("Truoc khi goi ham : \n");
    printf("Gia tri cua ptr1 : %d\n", ptr1);
    printf("Gia tri cua ptr2 : %d\n", ptr2);
    change(ptr1, ptr2);
    printf("Sau khi goi ham : \n");
    printf("Gia tri cua ptr1 : %d\n", ptr1);
    printf("Gia tri cua ptr2 : %d\n", ptr2);
    return 0;
}

Output : 

Truoc khi goi ham : 
Gia tri cua ptr1 : 6487560
Gia tri cua ptr2 : 6487564
Sau khi goi ham : 
Gia tri cua ptr1 : 6487560
Gia tri cua ptr2 : 6487564

Giải thích : 

Hàm change nhận 2 tham số là ptr1 và ptr2, khi đó giá trị của con trỏ x = ptr1 và y = ptr2, trong hàm change gán con trỏ y cho con trỏ x. Nhưng vấn đề ở đây là ptr1 với x khác nhau và ptr2 với y khác nhau, chỉ đơn thuần ta gán giá trị của ptr1 và ptr2 cho x và y, do đó x y có thay đổi gì thì không ảnh hưởng tới ptr1 và ptr2. Do đó sau khi hàm change kết thúc thì không có gì thay đổi đối với ptr1 và ptr2.

Nếu bạn muốn thay đổi ptr1 thì bạn cần tìm nhờ hàm change tìm tới địa chỉ của ptr1 để thay thế, và khi đó thì ta cần con trỏ cấp 2 làm tham số cho hàm change.

Ví dụ 2 : Thay đổi con trỏ cấp 1 thông qua hàm bằng con trỏ cấp 2

#include "stdio.h"

void change(int **x, int *y){
    *x = y;
}
int main(){
    int N = 28, M = 56;
    int *ptr1 = &N;
    int *ptr2 = &M;
    printf("Truoc khi goi ham : \n");
    printf("Gia tri cua ptr1 : %d\n", ptr1);
    printf("Gia tri cua ptr2 : %d\n", ptr2);
    change(&ptr1, ptr2);
    printf("Sau khi goi ham : \n");
    printf("Gia tri cua ptr1 : %d\n", ptr1);
    printf("Gia tri cua ptr2 : %d\n", ptr2);
    return 0;
}

Output : 

Truoc khi goi ham : 
Gia tri cua ptr1 : 6487576
Gia tri cua ptr2 : 6487580
Sau khi goi ham : 
Gia tri cua ptr1 : 6487580
Gia tri cua ptr2 : 6487580


Xem thêm bài giảng về Con Trỏ của mình : 

9kaUEMbXEk4