Con trỏ của con trỏ trong C++ | Laptrinhcanban.com

Con trỏ của con trỏ trong C++

Cùng tìm hiểu về con trỏ của con trỏ trong C++. Bạn sẽ biết con trỏ của con trỏ là gì, các gán con trỏ cho con trỏ, cũng như cách sử dụng con trỏ của con trỏ trong C++ sau bài học này.

Con trỏ của con trỏ trong C++

Con trỏ của con trỏ trong C++ là một biến được dùng để lưu trữ địa chỉ của một con trỏ khác trong bộ nhớ máy tính.

Trong bài con trỏ trong C++ chúng ta đã biết con trỏ là một biến được dùng để lưu trữ địa chỉ của một biến trong bộ nhớ máy tính. Chính vì con trỏ cũng là một biến, nên bản thân biến con trỏ cũng được gán một địa chỉ ở đâu đó trong bộ nhớ. Và bạn cũng có thể tạo một con trỏ khác để lưu trữ địa chỉ của biến con trỏ này. Đây được gọi là con trỏ của con trỏ trong C++.

Con trỏ của con trỏ trong C++

Bằng cách sử dụng con trỏ của con trỏ, chúng ta có thể tiến hành các tham chiếu gián tiếp kép tới giá trị của một biến thông qua địa chỉ của nó trong chương trình.

Lại nữa, vì con trỏ của con trỏ cũng là một biến, nên chúng ta cũng hoàn toàn có thể tạo ra các con trỏ khác để chứa địa chỉ của nó, ví dụ như con trỏ của con trỏ của con trỏ, hoặc phức tạp hơn như con trỏ của con trỏ của con trỏ của con trỏ chẳng hạn.

Mặc dù về lý thuyết thì chúng ta có thể tạo ra các con trỏ dạng như vậy, nhưng chúng sẽ khiến chương trình khá là rối rắm, nên thực tế chúng ta chỉ sử dụng tới con trỏ của con trỏ trong chương trình C++ mà thôi.

Gán con trỏ cho con trỏ trong C++

Khai báo con trỏ của con trỏ trong C++

Để có thể gán con trỏ cho con trỏ, trước hết chúng ta cần phải khai báo con trỏ đã.
Chúng ta sử dụng hai dấu hoa thị ** và đặt nó trước tên biến để khai báo một con trỏ của con trỏ trong C++, với cú pháp sau đây:

type **p;

Trong đó type là kiểu dữ liệu, và p là tên của con trỏ cho con trỏ. Lưu ý là kiểu dữ liệu của con trỏ, và của con trỏ gán địa chỉ vào nó phải là giống nhau.

Ví dụ cụ thể:

int **p1;
char **p2;

Gán con trỏ cho con trỏ trong C++

Sau khi khai báo một con trỏ của con trỏ, chúng ta có thể gán địa chỉ của một con trỏ khác cho nó tương tự như khi gán địa chỉ của một biến cho con trỏ.

Cú pháp sử dụng ở đây sẽ là:

p1 = &p2

Trong đó p2 là con trỏ sẽ gán cho con trỏ p1.

Ví dụ cụ thể, chúng ta khai báo một con trỏ, sau đó gán địa chỉ của nó vào một con trỏ khác trong C++ như sau:

#include <iostream>
using namespace std;

int main() {
int x = 10;
int *p1 = &x;

cout << "x = "<< x<<endl;
cout << "p1= "<< p1 <<endl;

int **p2;
p2 = &p1;

cout << "p2= "<< p2;

return 0;
}

Kết quả:

x = 10
p1= 0x118bff654
p2= 0x118bff648

Khởi tạo con trỏ của con trỏ trong C++

Chúng ta cũng có thể tiến hành đồng thời cả khai báo lẫn gán giá trị ban đầu cho con trỏ, bằng cách khởi tạo con trỏ của con trỏ trong C++.

Chúng ta có thể viết lại ví dụ ở trên bằng cách khởi tạo như sau:

#include <iostream>
using namespace std;

int main() {
int x = 10;
int *p1 = &x;

cout << "x = "<< x<<endl;
cout << "p1= "<< p1 <<endl;

int **p2 = &p1;

cout << "p2= "<< p2;

return 0;
}

Sử dụng con trỏ của con trỏ trong C++

Con trỏ của con trỏ trong C++ cũng là một con trỏ, do đó cách sử dụng của nó cũng tương tự như với con trỏ bình thường trong chương trình.

Ví dụ, chúng ta có thể lấy giá trị tại địa chỉ gán trong nó, hoặc là dịch chuyển địa chỉ được gán trên bộ nhớ như các ví dụ sau:

Ví dụ 1: lấy giá trị tại địa chỉ gán trong con trỏ của con trỏ trong C++

#include <iostream>
using namespace std;

int main() {
int x = 10;
int *p1 = &x;
int **p2 = &p1;

cout << "p1 = " << p1 << endl;
cout << "địa chỉ của p1 = " << &p1 << endl;

cout << "p2 = " << p2 << endl;

return 0;
}

Kết quả:

p1              =  0x7fff257d6624
địa chỉ của p1 = 0x7fff257d6628
p2 = 0x7fff257d6628

Có thể thấy rõ, sau khi gán địa chỉ của con trỏ p1 cho con trỏ p2, thì địa chỉ của con trỏ p1 sẽ trở thành giá trị của con trỏ p2.

Ví dụ 2: dịch chuyển địa chỉ được gán trên bộ nhớ

#include <iostream>
using namespace std;

int main() {
int x = 10;
int *p1 = &x;
int **p2 = &p1;

cout << "p2 before= " << p2 << endl;

p2 += 1;
cout << "p2 after = " << p2 << endl;

return 0;
}

Kết quả:

p2 before=  0x7ffeea36cb20
p2 after = 0x7ffeea36cb28

Tương tự như con trỏ, thì khi cộng thêm 1 vào con trỏ của con trỏ trong C++ thì địa chỉ lưu trong nó sẽ được dịch chuyển một số byte tương ứng với kiểu dữ liệu của nó. Với ví dụ trên thì do kiểu int có kích thước 4 byte nên khi p2 tăng 1 đơn vị thì địa chỉ lưu trong nó cũng sẽ tăng 4 byte.

Tổng kết

Trên đây Kiyoshi cùng bạn tìm hiểu về con trỏ của con trỏ trong C++ rồi. Để nắm rõ nội dung bài học hơn, bạn hãy thực hành viết lại các ví dụ của ngày hôm nay nhé.

Và hãy cùng tìm hiểu những kiến thức sâu hơn về C++ trong các bài học tiếp theo.

Viết bởi Kiyoshi. Đã đăng ký bản quyền tác giả tại Creativecommons và DMCA

Bài viết liên quan

HOME>> >>

Profile
きよしです!笑

Tác giả : Kiyoshi (Chis Thanh)

Kiyoshi là một cựu du học sinh tại Nhật Bản. Sau khi tốt nghiệp đại học Toyama năm 2017, Kiyoshi hiện đang làm BrSE tại Tokyo, Nhật Bản.