STARTING
CONTROL STATEMENT
FUNCTION
ARRAY & POINTER
OOP
STL
ITERATORS
OTHER FEATURES
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Cách sử dụng con trỏ trong C++

Các bạn thân mến! Ở các bài về hàm, mảng trong C++ mình đã giới thiệu ở các bài trước cũng có đề cập đến con trỏ. Trong bài học hôm nay chúng ta sẽ cùng tìm hiểu về con trỏ (pointer) trong C++ là gì nhé.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

1. Con trỏ trong C++ là gì?

Trong C++ con trỏ (pointer) là một biến mà giá trị của nó là địa chỉ của một biến khác. Chúng ta cùng xem hình minh họa dưới đây:

pointer png

Cú pháp

Con trỏ trong C++ cũng giống như biến hoặc hằng khác, chúng ta muốn sử dụng nó thì phải khai báo trước khi sử dụng. Cú pháp khai báo con trỏ trong C++ như sau:

Bài viết này được đăng tại [free tuts .net]

Cú pháp
KieuDuLieu *TenBien;

Trong đó KieuDuLieu là kiểu dữ liệu hợp lệ trong C++ như int, double, float, char... còn TenBien là tên của biến con trỏ, các bạn có thể đặt tùy ý miễn sao không trùng với từ khóa của C++.

Ví dụ một số khai báo con trỏ trong C++ như sau:

Ví dụ
int    *a;    
double *b;
float  *c; 
char   *d;

Sử dụng con trỏ

Trong C++ có hổ trợ các toán tử sau:

  • &: Dùng để lấy địa chỉ của một biến
  • *: Dùng để lấy giá trị của một địa chỉ

Các bạn mới bắt đầu học lập trình nghe có vẻ khó hiểu đúng không? Chúng ta cùng xem tiếp các ví dụ phía sau để hiểu rõ hơn về con trỏ trong C++ nhé.

Ví dụ

Ví dụ 1: Chúng ta cùng xem một ví dụ đơn giản về việc sử dụng con trỏ trong C++ như sau:

Ví dụ
#include <iostream>  
using namespace std;  
int main() {  
    int a = 10;    
    int *p;      
    p = &a; //con tro p tro den bien a    
    cout << "Dia chi cua bien a la: " << &a << endl;    
    cout << "Gia tri cua con tro p la: " << p << endl;
    cout << "Dia chi cua con tro p la: " << &p << endl;
    cout << "Gia tri cua bien a: " << a << endl; 
    cout << "Gia tri cua bien a (*p): " << *p << endl;    
   return 0;  
}

Và kết quả sau khi thực thi đoạn code trên như sau:

pointer ex JPG

Mình xin giải thích kết quả trên một tý nhé. Chúng ta thấy chương trình chúng ta có 2 biến đó là a, và biến con trỏ p. Chúng ta trỏ con trỏ p đến biến a bằng cú pháp p = &a, như vậy giá trị của biến con trỏ p là địa chỉ của biến a, và p vẫn là một biến khác ở trong bộ nhớ nó cũng có địa chỉ riêng, để truy xuất giá trị biến a chúng ta có thể truy xuất thông qua con trỏ p đó là *p.

Như vậy đến ví dụ này các bạn chắc đã hiểu cách sử dụng của 2 toán tử đó là & và * rồi nhé.

Ví dụ 2: Hoán đổi giá trị của 2 biến không sử dụng biến tạm thứ 3

Chúng ta thường giải quyết bài toán hoán đổi giá trị của 2 biến bằng cách sử dụng biến tạm thứ 3, trong ví dụ sau đây chúng ta sử dụng con trỏ sẽ không cần đến biến tạm thứ 3.

Ví dụ
#include <iostream>  
using namespace std;  
int main() {
    int a = 5;
    int b = 20;
    int *pa;
    int *pb;
    pa = &a; //con tro pa tro den bien a
    pb = &b; //con tro pb tro ben bien b
     
    cout << "Truoc khi hoan doi: *pa = " << *pa << ", *pb = " << *pb <<  endl;
    cout << "Truoc khi hoan doi:   a = " << a << ",   b = " << b <<  endl;
    
    *pa = *pa + *pb;
    *pb = *pa - *pb;
    *pa = *pa - *pb;

    cout << "Sau khi hoan doi: *pa = " << *pa << ", *pb = " << *pb << endl;
    cout << "Sau khi hoan doi:   a = " << a << ",   b = " << b << endl;
    return 0;  
}   

Và kết quả sau khi thực thi đoạn code trên:

pointer ex1 JPG

2. Con trỏ NULL trong C++

Trong C++ con trỏ được gán giá trị bằng NULL, ta gọi nó là con trỏ NULL. Mục đích của việc sử dụng con trỏ null là khi chúng ta không biết chính xác địa chỉ mà con trỏ sẽ trỏ đến.

Con trỏ null có giá trị là 0 được định nghĩa hầu hết các thư viện chuẩn, bao gồm iostream. Chúng ta cùng xem ví dụ sau

Ví dụ
#include <iostream>  
using namespace std;
int main () {
   int  *p = NULL;
   cout << "Gia tri cua con tro p la: " << p;
   return 0;
}

Và kết quả sau khi thực thi đoạn code trên:

pointer ex2 JPG

Hầu hết các hệ điều hành, các chương trình không được phép truy cập bộ nhớ tại địa chỉ 0 vì bộ nhớ đó được dành cho hệ điều hành.

Tuy nhiên, bộ nhớ có địa chỉ là 0 có ý nghĩa đặc biệt vì nó báo hiệu rằng con trỏ không có ý định trỏ đến một vị trí bộ nhớ có thể truy cập. Theo quy ước, con trỏ có địa chỉ 0 tức là không trỏ đến gì cả.

Trong C++ cho phép chúng ta kiểm tra con trỏ là null hay không như sau:

Ví dụ
#include <iostream>  
using namespace std;
int main () {
   int  *p = NULL;
   if(p) {
       cout << "con tro khong null" << endl;
   }    
   if(!p)  {
       cout << "con tro null" << endl;
   } 
   return 0;
}

3. Con trỏ trỏ tới con trỏ khác trong C++

Thông thường giá trị của con trỏ là địa chỉ của một biến khác, còn con trỏ trỏ tới con trỏ trong C++ đó là giá trị của con trỏ là địa chỉ của một con trỏ khác.

pointer to pointer JPG

Cú pháp

Cú pháp khai báo của con trỏ trỏ tới con trỏ trong C++ như sau:

KieuDuLieu **TenConTro;

Trong đó dấu * có thể thêm nhiều hơn 2 tùy vào con trỏ của bạn. (Ví dụ khai báo **pb tức là con trỏ trỏ **pb tới con trỏ *pa, ***pc tức con trỏ ***pc trỏ tới con trỏ **pb, con trỏ **pb trỏ tới con trỏ *pa)

Ví dụ

Chúng ta cùng xem một ví dụ đơn giản về con trỏ trỏ tới con trỏ trong C++ như sau:

Ví dụ
#include <iostream>
 
using namespace std;
 
int main () {
   int  a;
   int  *p1;
   int  **p2;
   int ***p3;
   a = 2;
   p1 = &a;
   p2 = &p1;
   p3 = &p2;
   cout << "Gia tri cua bien a: " << a << endl;
   cout << "Gia tri cua bien a tai con tro p1: " << *p1 << endl;
   cout << "Gia tri cua bien a tai con tro p2: " << **p2 << endl;
   cout << "Gia tri cua bien a tai con tro p3: " << ***p3 << endl;
   return 0;
}

Và kết quả sau khi thực thi đoạn code trên như sau:

pointer to pointer ex1 JPG

4. Kết luận

Như vậy con trỏ trong C++ không quá khó đúng không nào các bạn. Chỉ cần chúng ta nghĩ đơn giản đó là bản chất của con trỏ cũng như các biến thông thường khác trong C++, chẳng qua giá trị của nó là địa chỉ của biến khác. Chúng ta có thể truy cập giá trị của biến mà con trỏ trỏ đến bằng cách sử dụng toán tử *.

Thật ra còn rất nhiều vấn đề liên quan đến con trỏ trong C++ nữa, tuy nhiên bài học hôm nay chúng ta chỉ đề cập các vấn đề đã nêu trên thôi nhé. Mình nghĩ như vậy là khá nhiều so với các bạn mới bắt đầu rồi. Mình kết thúc bài học này ở đây nhé. Cám ơn các bạn đã đọc bài viết.

Cùng chuyên mục:

Các hàm xử lý thời gian (time.h) trong C

Các hàm xử lý thời gian (time.h) trong C

Các hàm xử lý chuỗi (string.h) trong C/C++

Các hàm xử lý chuỗi (string.h) trong C/C++

Thread Pools và Parallel Algorithms trong C++

Thread Pools và Parallel Algorithms trong C++

Tạo và quản lý các Multithreading trong C++

Tạo và quản lý các Multithreading trong C++

Xử lý ngoại lệ khi làm việc với Memory Allocation trong C++

Xử lý ngoại lệ khi làm việc với Memory Allocation trong C++

Try, Catch, và Throw của Exception Handling trong C++

Try, Catch, và Throw của Exception Handling trong C++

Cách sử dụng Lambda Expressions trong C++

Cách sử dụng Lambda Expressions trong C++

Sử dụng weak_ptr trong C++

Sử dụng weak_ptr trong C++

Sử dụng shared_ptr trong C++

Sử dụng shared_ptr trong C++

Sử dụng unique_ptr trong C++

Sử dụng unique_ptr trong C++

Tổng quan về Smart Pointers trong C++

Tổng quan về Smart Pointers trong C++

Sử dụng Iterators trong STL của C++

Sử dụng Iterators trong STL của C++

[Iterator] Sử dụng Vector trong C++

[Iterator] Sử dụng Vector trong C++

[Iterator] Sử dụng trong List trong C++

[Iterator] Sử dụng trong List trong C++

[STL] Sử dụng Vector trong C++

[STL] Sử dụng Vector trong C++

Tổng quan về Iterators trong C++

Tổng quan về Iterators trong C++

[STL] Các hàm thường dùng của lớp Vector trong C++

[STL] Các hàm thường dùng của lớp Vector trong C++

[STL] Các hàm thông dụng của Map trong C++

[STL] Các hàm thông dụng của Map trong C++

[STL] Danh sách các hàm Algorithm thường dùng trong C++

[STL] Danh sách các hàm Algorithm thường dùng trong C++

[STL] Cách tìm kiếm và xóa phần tử của một container trong C++

[STL] Cách tìm kiếm và xóa phần tử của một container trong C++

Top