Con trỏ tới con trỏ trong C++

Con Tro Toi Con Tro Trong C



Bài viết này nói về khái niệm con trỏ tới con trỏ trong C++. Con trỏ tới con trỏ trỏ hoặc lưu trữ địa chỉ của một con trỏ khác và cho phép tự thao tác với con trỏ. Sử dụng khái niệm này, chúng ta có thể dễ dàng sửa đổi một con trỏ từ một vị trí khác trong bộ nhớ. Con trỏ kép có lợi trong bộ nhớ được cấp phát động hoặc mảng đa chiều để thao tác các phần tử của mảng. Chúng ta sẽ thảo luận về con trỏ này để làm việc và cách sử dụng con trỏ trong C++ với các ví dụ thích hợp.

Tình huống 1:  Biểu diễn bộ nhớ của con trỏ tới con trỏ

Trong trường hợp này, việc khai báo con trỏ kép tương tự như khai báo con trỏ với dấu hoa thị bổ sung (*) trước tên con trỏ. Chúng ta có thể dễ dàng biểu diễn vị trí bộ nhớ của con trỏ kép trong C++. Đoạn mã của con trỏ tới con trỏ được đưa ra như sau:







#include
sử dụng không gian tên std;
int chính ( )
{
chữ số int  = năm mươi ;
int * ptrr;
ptrr = & chữ số;
int ** ptrr1;
ptrr1 = & ptrr;
cout << 'Địa chỉ bộ nhớ con trỏ là: \N ' ;
cout << 'ptrr (con trỏ):' << ptrr << ' \N ' ;
cout << '*ptrr1 (con trỏ kép): ' <<* ptrr1 << ' \N ' ;
cout << ' Giá trị lưu trữ trong con trỏ là: \N ' ;
cout << '*ptrr = ' <<* ptrr << cuối cùng;
cout << '**ptrr1 (con trỏ tới con trỏ) =' <<** ptrr1 << cuối cùng;
trở lại 0 ;
}


Trong hàm chính, chúng ta lấy một biến có địa chỉ bộ nhớ cần được lưu trữ trong một con trỏ. Bây giờ, chúng ta khởi tạo biến “chữ số”. Sau đó, chúng ta khai báo con trỏ “ptrr” lưu địa chỉ bộ nhớ “chữ số”. Bây giờ, chúng ta khai báo con trỏ kép có tên là “**ptrr1” lưu trữ địa chỉ của con trỏ “*ptrr”. Ở cuối mã, chúng tôi hiển thị bộ nhớ và giá trị của con trỏ và con trỏ kép trên màn hình bảng điều khiển. Đầu ra của mã này được đề cập như sau:




Địa chỉ bộ nhớ của con trỏ “ptrr” là “0x6ffe04” và con trỏ “*ptrr1” cũng lưu địa chỉ bộ nhớ của con trỏ “ptrr”. Giá trị được lưu trữ bên trong con trỏ là “50”. Về cơ bản, địa chỉ của con trỏ kép luôn giống với địa chỉ bộ nhớ của con trỏ.



Tình huống 2:  Con trỏ tới con trỏ làm tham số hàm

Trong kịch bản này, chúng ta sẽ tìm hiểu cách chuyển con trỏ kép trong bất kỳ hàm nào dưới dạng tham số để thực hiện cấp phát bộ nhớ tạm thời cho bất kỳ biến nào. Đoạn mã của tham số hàm với con trỏ kép được đề cập như sau:





#include
void getMemoryAddress ( int ** double_ptr ) {
thời tiết của bạn = 200 ;
* double_ptr = & nhiệt độ;
}

int chính ( ) {
int * ptr_1;
int ** double_ptr;
double_ptr = & ptr_1;
lấy địa chỉ bộ nhớ ( double_ptr ) ;
std::cout << 'Giá trị của **double_ptr là : ' << ** double_ptr << std::endl;
trở lại 0 ;
}


Ở đây, chúng ta sẽ tìm hiểu cách hoạt động của khái niệm con trỏ tới con trỏ trong C++. Hãy nhớ rằng một con trỏ được khai báo trong chương trình để hoạt động với một con trỏ kép. Vì vậy, chúng tôi xây dựng hàm “getMemoryAddress”. Chúng ta thiết kế hàm này để khi truyền tham số, nó sẽ tự động lấy địa chỉ bộ nhớ của con trỏ kép.

Trong hàm, chúng ta lấy biến “tempp” và con trỏ kép “**double_ptr”. Chúng ta chuyển địa chỉ của biến được chỉ định là “tempp” cho con trỏ kép và các giá trị con trỏ kép làm đối số của hàm. Chương trình hiển thị kết quả của mã chức năng chính trên màn hình bảng điều khiển, vì vậy tất cả những thứ có trong chức năng chính đều có thể thực thi được. Chúng ta lấy con trỏ “ptr_1” và con trỏ kép là “double_ptr” trong hàm chính. Chúng ta chuyển địa chỉ của con trỏ tới con trỏ kép.



Bây giờ, chúng ta chuyển biến con trỏ kép trong hàm ghi đè và chuyển con trỏ tới biến con trỏ trong câu lệnh luồng đầu ra “cout” để hiển thị kết quả của con trỏ kép.

Khi trình biên dịch đạt đến hàm ghi đè, trình kiểm tra trình biên dịch trong đó hàm này được xác định sẽ thực thi mã bên trong hàm và trả kết quả về hàm chính.

Đầu ra của mã này được đính kèm như sau:


Kết quả: Giá trị của con trỏ kép là 200.

Tình huống 3:  Sử dụng mảng 2D với con trỏ tới con trỏ

Trong ví dụ này, chúng ta sẽ xử lý mảng 2D có con trỏ kép. Chúng ta lấy một mảng và truyền địa chỉ của mảng vào con trỏ. Mã hoàn chỉnh của kịch bản này được cung cấp như sau:

int chính ( ) {
const int hàng = 3 ;
const int cols = 2 ;
int ** ma trận = int mới * [ hàng ] ;
( int tôi = 0 ; Tôi < hàng; ++tôi ) {
ma trận [ Tôi ] = int mới [ cols ] ;
}
( int tôi = 0 ; Tôi < hàng; ++tôi ) {
( int j = 0 ; j < cols; ++j ) {
ma trận [ Tôi ] [ j ] = tôi * cols + j;
}
}
( int tôi = 0 ; Tôi < hàng; ++tôi ) {
( int j = 0 ; j < cols; ++j ) {
cout << ma trận [ Tôi ] [ j ] << ' ' ;
}
cout << cuối cùng;
}
( int tôi = 0 ; Tôi < hàng; ++tôi ) {
xóa bỏ [ ] ma trận [ Tôi ] ;
}
xóa bỏ [ ] ma trận;
trở lại 0 ;
}


Như chúng ta đã biết, chúng ta có nhiều hàng và nhiều cột trong mảng 2D. Trong hàm main, chúng ta khởi tạo các hàng và cột có “const int”. Sau đó, chúng tôi phân bổ không gian bộ nhớ cho các hàng và không gian bộ nhớ cho các cột dọc theo mỗi hàng. Chúng ta chuyển giá trị số hàng dưới dạng một con trỏ trong con trỏ kép của ma trận dưới dạng “**matrix”. Trong con trỏ kép này, vòng lặp số hàng được thực thi hoặc đúng. Sau đó, một vòng lặp bên trong khác được thực thi cho đến khi điều kiện trở thành sai.

Sau khi cấp phát bộ nhớ, chúng ta gán lại một giá trị trong một mảng: vòng lặp bên ngoài cho các hàng và vòng lặp bên trong cho các cột của mảng 2D. Trong vòng lặp bên trong, giá trị của hàng và cột được gán cho con trỏ kép và thực hiện một phép toán số học cần thiết. Chúng tôi hiển thị các giá trị của mảng 2D như số hàng và cột được phân bổ trong bộ nhớ. Số lượng hàng và cột luôn trỏ đến con trỏ kép lưu trữ giá trị hàng và cột. Cuối cùng, chúng ta xóa bộ nhớ và phân bổ mảng này khỏi bộ nhớ trong C++.

Đầu ra của mảng 2D với một con trỏ kép được đính kèm như sau:

Tình huống 4:  Hoán đổi con trỏ bằng cách sử dụng con trỏ thành con trỏ

Ở đây, chúng ta sẽ tìm hiểu cách hoán đổi con trỏ trong C++ bằng cách khai báo con trỏ kép. Đoạn mã của kịch bản này được đính kèm như sau:

#include
trao đổi vô hiệu ( int ** ptrr_1, bạn ** ptrr_2 ) {
int * temp_var = * ptrr_1;
* ptrr_1 = * ptrr_2;
* ptrr_2 = temp_var;
}
int chính ( ) {
int x = mười lăm , y = 25 ;
int * ptrA = & x, * ptrrB = & Và;
std::cout << 'Trước khi trao đổi: *ptrrA là =' << * pttrA << ', *ptrrB là = ' << * ptrrB << std::endl;
tráo đổi ( & ptrA, & ptrrB ) ;
std::cout << 'Sau khi hoán đổi: *ptrrA  là =' << * pttrA << ', *ptrrB  là= ' << * ptrrB << std::endl;
trở lại 0 ;
}


Đầu tiên, chúng ta xây dựng hàm hoán đổi, chuyển cả hai con trỏ làm đối số của hàm. Trong hàm hoán đổi, chúng ta lấy con trỏ “temp” và chuyển giá trị của “pointer1” vào “temp” trong một thời gian. Sau đó, chúng ta chuyển giá trị của “pointer2” cho “pointer1”. Cuối cùng, chúng ta chuyển giá trị của con trỏ “temp” cho “pointer2”.

Trong hàm chính, chúng ta cần hai con trỏ mà chúng ta chuyển hoặc ghi đè trong hàm “hoán đổi”. Chúng ta chuyển địa chỉ của các biến cho các con trỏ đã cho. Sau đó, giá trị của con trỏ trước và sau khi hoán đổi con trỏ sẽ được hiển thị.

Đầu ra của mã này được đính kèm như sau:


Như chúng ta có thể thấy, các giá trị của con trỏ được hoán đổi thành công bằng cách sử dụng con trỏ kép trong C++.

Phần kết luận

Chúng ta đã kết luận rằng con trỏ tới con trỏ luôn lưu trữ địa chỉ bộ nhớ của bất kỳ con trỏ nào trong C++. Chúng ta có thể sử dụng con trỏ kép để tạm thời sử dụng vị trí bộ nhớ của bất kỳ con trỏ nào vào bất kỳ lúc nào. Đây là một cách rất hiệu quả để thao tác gián tiếp địa chỉ bộ nhớ và tiếp cận dữ liệu.