Thứ Bảy, 4 tháng 5, 2024

35. Lý thuyết con trỏ trong C++

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/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 <iostream>
 
using namespace std;


int main(){
    int number = 50;
    cout <<"Gia tri cua number la: " << number << endl;
    cout <<"Dia chi cua number la: " << &number << endl; // Lệnh in địa chỉ
    
    return 0;
}

 

Bấm Run để chạy chương trình


 

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 <iostream>
 
using namespace std;

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 <iostream>
 
using namespace std;

int main() {
    int number = 50;
    cout <<"Gia tri cua number la: " << number << endl;
    cout <<"Dia chi cua number la: " << &number << endl; // Lệnh in địa chỉ
    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. Đây là code:

#include <iostream>
 
using namespace std;

int main() {
    int number = 50;
   
int *p;
   
p = &number; // luu tru dia chi cua bien number
    cout <<"Gia tri cua number la: " << number << endl;
    cout <<"Dia chi cua number la: " << &number << endl; // Lệnh in địa chỉ
    return 0;
}


Kết quả




 

 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 <iostream>
 
using namespace std;

int main() {
    int number = 50;
    int *p;
    p = &number; // luu tru dia chi cua bien number
    cout <<"Gia tri cua number la: " << number << endl;
    cout <<"Dia chi cua number la: " << &number << endl; // Lệnh in địa chỉ
     cout <<"Gia trị cua number la: " << *p << endl;// Toán tử * trước tên con trỏ, giá trị của biến number
    cout <<"Dia chi cua biến number la: "<< p << endl; //Tên con trỏ, địa chỉ của biến number
    return 0;
}

 

Hai lệnh cout trên và hai lệnh cout 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ý thuyết con trỏ trong lập trình C++

 

 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