[C] Variable Pointer (Con trỏ biến) - P1

Ngô Văn Tuân

Gà con
Staff member
Một cách ngắn gọn: Pointer là một biến lưu địa chỉ của biến khác.

Dài hơn một chút: Pointer là một biến gần giống như biến thông thường ta khai báo khi ta mới học C nhưng điểm khác biệt lớn nhất là ở ứng dụng của pointer, ở giá trị mà nó lưu trữ: là địa chỉ của một biến khác trong bộ nhớ.

1. Khai báo biến con trỏ.
<Kiểu dữ liệu mà của biến được con trỏ trỏ tới> *<tên biến>;​
VD:
C:
int *var0;    // Khai báo biến con trỏ có tên là var0 sẽ lưu địa chỉ của một biến có kiểu dữ liệu là int;
double *var1; // Khai báo biến con trỏ có tên là var1 sẽ lưu địa chỉ của một biến có kiểu dữ liệu là double;
Lưu ý: Để khai báo nhiều biến con trỏ trên một hàng, ta phải đặt dấu * trước mỗi biến.
VD:
C:
int *a, *b, *c, d;
Trong ví dụ trên, a, b, c là biến con trỏ sẽ lưu địa chỉ của một biến có kiểu dữ liệu là int còn d là một biến có kiểu dữ liệu là int.

2. Sử dụng con trỏ:
Để sử dụng con trỏ cần có các toán tử sau:
* : toán tử lấy giá trị tại địa chỉ lưu trong con trỏ​
& : toán tử lấy địa chỉ của biến.​
Kinh tụng: sao(*) giá trị, và(&) địa chỉ
Đọc comment trong ví dụ sau để hiều về cách sử dụng các toán tử trên.
C:
#include <stdio.h>
#include <stdint.h>

int main(){
    uint8_t var0 = 10;         // Khai báo biến var0
    uint8_t *var1;             // Khai báo biến con trỏ var1 trỏ tới biến có kiểu dữ liệu là uint8_t
                               // Dấu * ở đây chỉ là ký hiệu cho biết rằng var1 là biến con trỏ
    var1 = &var0;              // Gán giá trị biến var1 là địa chỉ của biến var0
    uint8_t var2 = *var1;      // Khai báo và gán giá trị biến var2 bằng giá trị được lưu tại địa chỉ chứa trong biến var1

    printf("var2 = %d", var2);

    return 0;
}
var2 = 10

3. Ứng dụng con trỏ:
Ứng dụng lớn nhất của con trỏ là dùng để truyền tham chiếu. Để hiểu rõ hơn, ta đến với ví dụ sau.
Lưu ý: Trong ví dụ, mục đích của hàm swap là để hoán đổi giá trị giữa hai biến var0var1.
C:
#include <stdio.h>
#include <stdint.h>

void swap(int a, int b){
    int temp = a;
    a = b;
    b = temp;
}

void swap_ptr(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(){
    int var0 = 10;
    int var1 = 20;

    swap(var0, var1);
    printf("Pass by value: var0=%d var1=%d\n", var0, var1);

    swap_ptr(&var0, &var1);
    printf("Pass by reference: var0=%d var1=%d\n", var0, var1);

    return 0;
}
Các bạn dự đoán output trước khi spoil nhé :big grin:.
Pass by value: var0=10 var1=20
Pass by reference: var0=20 var1=10
Giải thích:
  • Khi ta gọi hàm swap(var0, var1); thì giá trị của var0 sẽ được copy và lưu vào biến cục bộ a, giá trị của var1 sẽ được copy và lưu vào biến cục bộ b của hàm void swap(int a, int b). Do đó khi ta thay đổi giá trị của hai biến cục bộ a,b hoàn toàn không ảnh hưởng đến giá trị của hai biến var0var1. Kiểu truyền tham số như vậy gọi là truyền tham trị (giá trị của biến được truyền vào).
  • Khi ta gọi hàm swap_ptr(&var0, &var1); ta đã truyền vào địa chỉ của hai biến var0var1 (nhờ toán tử &), địa chỉ của var0 sẽ được copy và lưu vào biến cục bộ a, địa chỉ của var1 sẽ được copy và lưu vào biến cục bộ b của hàm void swap_ptr(int *a, int *b). Lúc nàya, b là hai biến con trỏ lưu địa chỉ của hai biến var0var1. Kiểu truyền tham số này gọi là truyền tham chiếu (không phải truyền giá trị của biến mà truyền một địa chỉ để tham chiếu tới biến).
    • int temp = *a; Biến temp được khởi tạo và lưu giá trị chứa ở địa chỉ lưu trong biến a (chính là giá trị của biến var0).
    • *a = *b; Giá trị ở ô nhớ có địa chỉ là b (var1)được copy qua ô nhớ có địa chỉ là a (var0).
    • *b = temp; Giá trị temp được lưu vào ô nhớ có địa chỉ là b (var1).

Bài tiếp: [C] Variable Pointer (Con trỏ biến) - P2
 
Top