Thứ Sáu, 12 tháng 4, 2024

33.Lý thuyết con trỏ

Con trỏ (Pointer) là một kiến thức quan trọng, độc đáo và khiến chúng ta nghĩ tới ngay khi nói về ngôn ngữ lập trình C.

Biến con trỏ

Con trỏ hay biến con trỏ cũng là một biến thông thường nhưng giá trị mà nó lưu lại là địa chỉ của 1 biến khác.

Ví dụ biến kiểu int N trong chương trình sẽ có địa chỉ nhất định trong bộ nhớ, để lưu trữ giá trị địa chỉ này ta cần biến con trỏ kiểu int 

Để hiểu về địa chỉ ta có ví dụ sau, đây là code bạn nhập vào IDE Online để chạy


#include<stdio.h>  
 
int main() {
    int number = 50;
    printf("Gia tri cua number la %d\n", number);
    printf("Dia chi cua number la %p", &number); // Lệnh in địa chỉ lưu ý sử dụng %p
    return 0;
}
Bấm Run để chạy chương trình

Lý thuyết con trỏ trong lập trình C




Khi khai báo biến con trỏ ta thêm dấu * vào trước tên biến.

Mỗi biến trong chương trình đều được cấp phát vùng nhớ để lưu trữ giá trị của nó, ví dụ biến int sẽ được cấp phát 4 byte liên tiếp để lưu trữ và lấy địa chỉ của byte đầu tiên làm địa chỉ cho biến.

Để in ra địa chỉ của biến bạn dùng toán tử &, ví dụ &N sẽ cho bạn địa chỉ của biến N. Bạn cần phải sử dụng '%p' để hiện thị địa chỉ của một biến.


Quay lại con trỏ, vì con trỏ cũng là một biến nên ta cũng khai báo như khai báo với biến.


Cú pháp khai báo : Kiểu_Dữ_Liệu *Tên_Biến_Con_Trỏ;

Đây là ví dụ khai báo một số con trỏ với các kiểu dữ liệu khác nhau:

#include <stdio.h>

int main(){
    //Dấu * thể hiện ptr là con trỏ
    int *ptr; // con trỏ kiểu int
    //Dấu * có thể đặt cạnh tên biến hoặc cạnh kiểu dữ liệu
    long long* ptr2; // con trỏ kiểu long long
    char *ptr3; //Con trỏ kiểu char
    return 0;
}
 

 

Bạn có thể nhập vào IDE Online để chạy thử

 


 

Vẫn sử dụng code ở trên. 

#include<stdio.h>  
 
int main() {
    int number = 50;
    printf("Gia tri cua number la %d\n", number);
    printf("Dia chi cua number la %p", &number); // Lệnh in địa chỉ lưu ý sử dụng %p
    return 0;
}

Ta cần khai báo thêm một biến con trỏ là 

int *p; 

Tiếp theo, cũng như mọi biến thông thường, ta cần "gán" giá trị cho biến con trỏ *p, đó là địa chỉ của biến number

 p = &number; // luu tru dia chi cua bien number

Trước khi tiếp tục, ta sẽ chạy thử chương trình.


Mọi thứ vẫn ổn. Nhưng có lẽ bạn đang cảm thấy rối tung cả lên!

Chúng ta hệ thống lại lần nữa:

  • Biến bất kỳ thì có giá trị, ví dụ biến int number có giá trị là 50
  • Mỗi biến khi  khai báo sẽ có địa chỉ trong bộ nhớ, ví dụ 0x7ffd0df48.
  • Chúng ta có thể lấy địa chỉ bộ nhớ của biến bằng toán tử &
  • Con trỏ là một biến, giá trị là địa chỉ của biến khác, ví dụ 0x7ffd0df48.
  • Khai báo biến con trỏ bằng dấu *
  • Sử dụng tên của con trỏ để lấy địa chỉ bộ nhớ một biến khác.
  • Sử dụng toán tử * trước tên con trỏ để lấy giá trị của biến đó.

Thêm 2 lệnh in sau vào chương trình, chạy thử, bạn sẽ thấy rõ hơn. 

#include<stdio.h>  
 
int main() {
    int number = 50;
    int *p;
    p = &number; // luu tru dia chi cua bien number
   
printf("Gia tri cua number la %d\n", number); // Lệnh in giá trị biến
    printf("Dia chi cua number la %p\n", &number); // Lệnh in địa chỉ lưu ý sử dụng %p
    printf("Gia trị cua number la %d\n", *p);// Toán tử * trước tên con trỏ, giá trị của biến number
    printf("Dia chi cua biến number la %p\n", p); //Tên con trỏ, địa chỉ của biến number

    return 0;
}
 

Hai lệnh printf trên và hai lệnh printf dưới sẽ có cùng kết quả. Hai cái đầu sử dụng biến, hai cái sau sử dụng con trỏ.


 

Lưu ý là bạn cần phân biệt dấu * khi khai báo con trỏ ptr và dấu * khi giải tham chiếu con trỏ ptr. Dấu * khi khai báo thể hiện ptr là một con trỏ còn dấu * trước ptr ở những câu lệnh sau là toán tử giải tham chiếu.

Phần tiếp theo

Phần trước




Không có nhận xét nào:

Đăng nhận xét