Pointer là gì

Chào các bạn học tập viên đã theo dõi khóa huấn luyện và đào tạo lập trình trực đường ngôn từ C++.

Bạn đang xem: Pointer là gì

Trong chương này, họ đã cùng nhau mày mò về định nghĩa con trỏ (Pointer) - một đặc trưng của ngôn ngữ lập trình C/C++.

Trước lúc vào bài học này, bọn họ cùng mọi người trong nhà xem xét lại một vài tư tưởng tương quan cho vùng ghi nhớ, hệ trọng của biến chuyển, tsi mê chiếu…

Variable

Variable (tốt còn được gọi là biến) là 1 trong những ô nhớ lẻ tẻ hoặc một vùng lưu giữ được hệ điều hành và quản lý cấp phát đến lịch trình C++ nhằm mục tiêu để tàng trữ quý giá vào bên phía trong vùng lưu giữ kia. Để tróc nã xuất mang lại cực hiếm nhưng mà phát triển thành sẽ sở hữu, công tác đề xuất tìm về vùng nhớ (địa chỉ) của biến hóa để hiểu quý giá bên phía trong vùng nhớ kia, tương tự như bạn có nhu cầu rước món đồ bên trong chiếc vỏ hộp, bạn nên biết mẫu vỏ hộp được đặt ở đâu.

Lúc làm việc với những biến hóa thường thì, bọn họ không đề nghị quyên tâm cho liên hệ vùng ghi nhớ của đổi thay. lúc nên truy vấn xuất quý hiếm của đổi thay, chúng ta chỉ cần Điện thoại tư vấn định danh (giỏi hay Điện thoại tư vấn là tên biến).

Ví dụ:

int money;Lúc cái lệnh này được CPU triển khai, một vùng lưu giữ tất cả kích thước 4 bytes sẽ được cấp phép. Lấy ví dụ phát triển thành money này được để ở ô nhớ 1224 (trong can dự ảo của dòng sản phẩm tính).

*

Bất cứ đọng khi nào lịch trình thấy chúng ta sử dụng biến hóa money trong câu lệnh, lịch trình hiểu đúng bản chất yêu cầu tìm về ô lưu giữ 1224 để lấy quý hiếm kia ra.

Virtual memory & Physical memory

Việc truy vấn xuất dữ liệu trên bộ lưu trữ máy tính xách tay rất cần được trải qua một số trong những bước trung gian, người tiêu dùng tất yêu thẳng truy xuất vào các ô lưu giữ trên các trang bị tàng trữ. Chúng ta chỉ có thể trỏ đến vùng lưu giữ ảo (virtual memory) bên trên máy tính, còn bài toán truy nã xuất mang lại bộ nhớ thứ lý (physical memory) trường đoản cú bộ nhớ ảo đề xuất được thực hiện do máy Hartware có tên là Memory management unit (MMU) với một chương trình xác định liên quan bộ nhớ điện thoại tư vấn là Virtual address space.


*

1.png?raw=true1045×566

Virtual memory làm đậy giấu sự phân mhình ảnh của bộ nhớ đồ vật lý, khiến cho họ tất cả xúc cảm đã làm việc cùng với các vùng ghi nhớ tiếp tục. Trong hình trên, trường đoản cú phía Virtual memory cho đến Physical memory nằm trong về phần làm chủ của hệ điều hành, lập trình viên với người tiêu dùng họ không thể can thiệp trực sau đó trong quá trình máy tính xách tay đang vận động.

Variable address & address-of operator

Địa chỉ của trở nên mà chúng ta thấy được thiệt ra chỉ với phần nhiều quý hiếm đã có được viết số đồ vật từ đặt lên trên Virtual memory. Để rước được thúc đẩy ảo của vươn lên là trong công tác, họ áp dụng toán tử ‘&’ đặt trước thương hiệu đổi thay.

int x = 5;std::cout Trên máy vi tính của chính mình, hiệu quả của đoạn công tác bên trên được in ấn ra nhỏng sau:

50027FEA0Dòng thứ nhất là kết quả của bài toán truy tìm xuất giá trị của vươn lên là trải qua định danh (tên biến). Dòng vật dụng nhị là công dụng của việc truy vấn xuất mang lại hệ trọng ảo của đổi thay.

Tyêu thích chiếu (Reference)

Mục đích của tham chiếu trong C++ là tạo ra một biến đổi khác gồm cùng đẳng cấp dữ liệu nhưng thực hiện bình thường vùng lưu giữ với vươn lên là được tsay mê chiếu mang đến.

int i1 = 10;int &i_ref = i1; //reference to i1, not means address of i1cout Kết quả bọn họ được:

0xBFEB475C0xBFEB475Cdo vậy, mọi hành vi biến hóa quý giá của i_ref hầu hết tác động trực tiếp đến i1.

Lưu ý: Biến tmê say chiếu sẽ sở hữu được liên quan cố định sau khi khởi chế tạo ra. Chúng ta cấp thiết tmê say chiếu lại đợt tiếp nhữa.

Dereference operator

Toán thù tử trỏ mang đến (dereference operator) hay còn gọi là indirection operator (toán thù tử điều hành quản lý loại gián tiếp) được kí hiệu bằng lốt sao " * " cho phép họ lấy ra giá trị của vùng lưu giữ có thúc đẩy ví dụ.

Ví dụ:

int n = 5;cout Dòng lệnh cout trước tiên khá dễ hiểu, nó thực hiện in ra giá trị của biến chuyển n bằng cách điện thoại tư vấn định danh n, còn sót lại phần truy hỏi xuất mang lại liên hệ ảo của đổi mới n vẫn do công tác đảm nhận.

Dòng lệnh cout lắp thêm nhị ko sử dụng để lấy ra quý giá bên phía trong vùng nhớ nhưng mà phát triển thành n vẫn nắm giữ, mà nó lấy ra can dự ảo của đổi mới n.

Dòng lệnh cout sản phẩm ba họ áp dụng toán tử trỏ cho " * " đặt trước toán tử address-of. Khi đó, (&n) sẽ mang ra tác động ảo của trở nên n, cùng toán thù tử * sẽ tróc nã xuất quý hiếm bên trong can hệ kia.

Kết trái của đoạn chương trình bên trên là:

50xBFD181AC5Ngoài việc truy tìm xuất quý hiếm vào vùng nhớ của một địa chỉ rõ ràng, toán tử trỏ mang đến (dereference operator) còn có thể dùng để làm đổi khác cực hiếm phía bên trong vùng lưu giữ kia.

int n = 5;cout Kết quả đoạn lịch trình này là:

510vì vậy, dereference operator được cho phép bọn họ thao tác làm việc thẳng bên trên Virtual memory cơ mà không đề nghị trải qua định danh (tên biến).


*

Mặc mặc dù dereference operator tất cả kí hiệu như thể multiplication operator, nhưng các bạn có thể riêng biệt được do dereference operator là toán thù tử một ngôi, trong khi kia, multiplication operator là toán tử nhì ngôi.

Khác với tham chiếu (reference), toán thù tử trỏ mang đến (dereference operator) ko tạo thành một tên phát triển thành không giống, mà lại nó truy hỏi xuất trực kế tiếp vùng lưu giữ bao gồm địa chỉ rõ ràng bên trên Virtual memory.

Con trỏ (Pointer)

Với phần đông tư tưởng bản thân trình diễn làm việc trên (một số trong những quan niệm các bạn đã có được học), hiện thời chúng ta có thể kể tới nhỏ trỏ (pointer).

Một bé trỏ (a pointer) là một đổi thay được dùng làm tàng trữ thúc đẩy của đổi thay khác.

Khác với tmê say chiếu, bé trỏ là 1 trong thay đổi có can dự hòa bình so với vùng lưu giữ nhưng nó trỏ mang đến, nhưng quý hiếm bên trong vùng lưu giữ của con trỏ đó là liên quan của biến đổi (hoặc can dự ảo) mà nó trỏ tới.


*

Trong ví dụ bên trên, một con trỏ sau khi knhì báo đã có cấp phép vùng lưu giữ ở địa chỉ 3255, với nó trỏ đến tác động 1224, do đó, cực hiếm bên phía trong vùng nhớ của bé trỏ là 1224.

Xem thêm: Iphone Pre-Owned Là Gì ? Có Nên Mua Iphone Cpo Không? Có Ai Mua Hàng Apple Certified Pre

Khai báo con trỏ

Cũng giống như biến hóa thông thường, biến chuyển nhỏ trỏ cần được khai báo trước lúc thực hiện. Con trỏ tận hưởng cú pháp knhì báo bắt đầu hơn một ít đối với thay đổi thông thường.

*;Khác với phát triển thành thông thường, họ đề nghị đặt thêm lốt sao thân mẫu mã dữ liệu cùng thương hiệu biến của con trỏ.

Ví dụ:

int *iPtr;float *fPtr;double *dPtr;int *iPtr1, *iPtr2;Lưu ý: Dấu sao trong knhị báo con trỏ không hẳn là toán tử trỏ mang đến (dereference operator), nó chỉ là cú pháp được ngôn ngữ C/C++ phương tiện.

Cách khai báo dễ khiến cho nhầm lẫn

Ngôn ngữ C/C++ thưởng thức đặt vết sao thân hình dáng dữ liệu và thương hiệu nhỏ trỏ nhưng lại không buộc phải phải kê nó sát với giao diện tài liệu tốt gần cùng với tên bé trỏ. Do kia, các cách knhị báo dưới đây các được đến phép:

int *iPtr1; //We recommended you use this way to declare pointersint* iPtr2;Nhưng mình lời khuyên chúng ta sử dụng phương pháp khai báo đặt lốt sao ngay lập tức trước thương hiệu nhỏ trỏ vị giải pháp đồ vật nhì có thể gây lầm lẫn.

int* iPtr1, iPtr2;Với bí quyết knhì báo này, iPtr1 là 1 trong con trỏ mẫu mã int, trong khi đó, iPtr2 là một trong trở thành kiểu int. Để đã có được hai con trỏ, họ cần knhì báo nlỗi sau:

int *iPtr1, *iPtr2;Kích thước của con trỏ trong bộ nhớCác bạn cùng chạy thử đoạn chương trình dưới đây:

cout Đoạn chương trình trên cho ra tác dụng nhỏng sau:

*

Tại hành lang cửa số đồ họa của Visual studio 2015, chúng ta gửi sang trọng Debug bên trên nền tảng gốc rễ 64 bits.


*

Nhấn F5 lại đợt nữa với xem lại kết quả:

*

do đó, bọn họ thấy rằng Khi chạy xe trên nền tảng gốc rễ hệ điều hành 32 bits nhỏ trỏ sẽ có size 4 bytes, Lúc điều khiển xe trên căn nguyên hệ quản lý 64 bits bé trỏ sẽ sở hữu được size 8 bytes.

Kiểu tài liệu của bé trỏ chuyển đổi không còn ảnh hưởng tác động cho form size bộ nhớ của nhỏ trỏ. Bởi vì chưng cực hiếm thực thụ của bé trỏ là hình dáng số nguyên ổn ko vết (unsigned int), vào căn cơ hệ quản lý điều hành 32 bits, quý giá cơ mà nhỏ trỏ lưu trữ đang là unsigned __int32, và trong gốc rễ hệ quản lý điều hành 64 bits, giá trị của con trỏ tàng trữ tất cả hình dáng unsigned __int64.

Kiểu dữ liệu của nhỏ trỏ không biểu đạt quý hiếm tác động được lưu trữ phía bên trong con trỏ, nhưng vẻ bên ngoài dữ liệu của nhỏ trỏ dùng để làm xác định mẫu mã dữ liệu của biến đổi mà lại nó trỏ đến trên bộ lưu trữ ảo.

Vậy vì sao lại bắt buộc 4 bytes cho 1 con trỏ vào hệ điều hành quản lý 32 bits, với đề xuất 8 bytes cho 1 con trỏ vào hệ điều hành và quản lý 64 bits?

Dưới đấy là lên tiếng Virtual memory trên máy tính của mình:

*

Dung lượng bộ nhớ ảo bây giờ của sản phẩm bản thân là 1960MB, tương đương cùng với 2055208960 bytes. Trong lúc ấy, con trỏ trong nền tảng gốc rễ hệ quản lý điều hành 32 bits có form size 4 bytes, cực hiếm liên can lớn số 1 nhưng mà bé trỏ 4 bytes hoàn toàn có thể tàng trữ được là 4294967295, vì thế nó đủ nhằm tàng trữ bất kì tương tác của vươn lên là nào được cấp phát trên bộ lưu trữ ảo.

Gán quý hiếm đến bé trỏ

Giá trị cơ mà đổi mới bé trỏ lưu trữ là liên tưởng của đổi mới không giống gồm thuộc đẳng cấp tài liệu với đổi thay con trỏ.

int *ptr;int value = 5;ptr = &value;Do kia, họ phải thực hiện address-of operator để đưa ra can dự ảo của đổi thay rồi bắt đầu gán mang đến nhỏ trỏ được. Hiện giờ, biến ptr sẽ tàng trữ liên hệ ảo của vươn lên là value.

*

Chúng ta nói theo cách khác rằng con trỏ ptr vẫn nắm giữ liên hệ của trở thành value, cũng nói cách khác bé trỏ ptr trỏ mang đến biến chuyển value.

Đoạn công tác sau đang in ra cửa hàng của đổi thay value với cực hiếm được lưu lại do con trỏ ptr sau khi trỏ cho phát triển thành value:

int main(){int value = 5;int *ptr = &value;cout Kết trái thu được bên trên màn hình hiển thị console:

0012FF7C0012FF7CLý vày mà họ gán được ảnh hưởng của vươn lên là value cho nhỏ trỏ giao diện int (int *) bởi vì address-of operator của một đổi mới giao diện int trả về quý hiếm thứ hạng con trỏ giao diện int (int *).

Thử xem xét đoạn chương trình sau:

#include using namespace std;int main(){int value = 5;cout Kết trái in ra màn hình của tân oán tử mang tương tác ngơi nghỉ bên trên là:

*

Do đó, bạn có thể gán &value đến bé trỏ loại int (int *).

Trong khi, lúc có nhị con trỏ cùng loại thì bạn cũng có thể gán thẳng nhưng mà ko bắt buộc sử dụng address-of operator.

int main(){int value = 5;int *ptr1, *ptr2;ptr1 = &value; //ptr1 point to valueptr2 = ptr1; //assign value of ptr1 to lớn ptr2cout Lúc này, ptr1 cùng ptr2 thuộc giữ lại liên quan của vươn lên là value.

*

Khác cùng với tham mê chiếu (reference), một con trỏ rất có thể trỏ mang lại liên tưởng không giống vào bộ nhớ ảo sau thời điểm đã làm được gán quý giá. Tmê say chiếu (reference) tất yêu biến đổi địa chỉ sau lần tmê mệt chiếu thứ nhất.

Ví dụ:

int main(){int *ptr;int arr<5> = 1, 2, 3, 4, 5 ;for(int i = 0; i Kết quả của đoạn chương trình này là:

*

Con trỏ ptr đã trỏ mang đến thứu tự 5 phần tử của mảng arr. Nếu các bạn để ý đang thấy 5 địa chỉ này liên tục nhau bên trên bộ nhớ ảo. Mình vẫn trình diễn vấn đề này trong những bài học kinh nghiệm sau.

Các phxay gán chưa hợp lệ Lúc sử dụng con trỏ

Phép gán của nhỏ trỏ chỉ thực hiện được khi giao diện dữ liệu của nhỏ trỏ cân xứng kiểu dữ liệu của trở thành mà nó đang trỏ tới. Do kia, các phxay gán bên dưới đấy là chưa hợp lệ:

int iValue = 0;float fValue = 0.0;int *i_ptr = fValue; //wrong! int pointer cannot point khổng lồ the address of a double variablefloat *f_ptr = iValue; //wrong! float pointer cannot point to lớn the address of an int variableMặc dù giá trị nhưng mà con trỏ tàng trữ bao gồm kiểu unsigned int, tuy nhiên bọn họ tất yêu gán thẳng một quý giá ảnh hưởng đến nhỏ trỏ được.

int *ptr = 1245052; //wrong!Giá trị 1245052 không tồn tại liên can ví dụ, trong những khi đó, bé trỏ chỉ thừa nhận quý giá là địa chỉ nên phép gán bên trên là không nên. Mặc cho dù cực hiếm được đưa về dạng cơ số thập lục phân nhằm hài hòa cùng với định dạng quý hiếm cơ mà bé trỏ in ra, vấn đề đó cũng ko được được cho phép.

int *ptr = 0012FF7C; //wrong!Chỉ có giá trị hình trạng bé trỏ (đạt được nhờ vào toán thù tử address-of, hoặc từ một biến đổi bé trỏ cùng vẻ bên ngoài khác) new hoàn toàn có thể gán được mang lại đổi thay bé trỏ.

Truy xuất quý hiếm bên trong vùng nhớ cơ mà nhỏ trỏ trỏ đến

Khi họ bao gồm một con trỏ đã được trỏ mang đến liên tưởng làm sao đó vào bộ lưu trữ ảo, chúng ta cũng có thể tầm nã xuất cực hiếm ở địa chỉ đó bằng dereference operator. Dereference operator vẫn Đánh Giá nội dung địa chỉ được trỏ mang đến.

int *ptr; //declare an int pointerint value = 5;ptr = &value; //ptr point khổng lồ valuecout Kết quả của đoạn lịch trình bên trên nhỏng sau:

*

Tân oán tử trỏ mang lại (dereference operator) được dùng làm truy cập thẳng vào vùng lưu giữ gồm tương tác cụ thể trên bộ lưu trữ ảo (virtual memory), vì chưng trở thành con trỏ ptr đang nắm giữ can hệ của phát triển thành value nên lúc đặt toán thù tử trỏ cho (dereference operator) trước con trỏ ptr, nó sẽ truy xuất cực hiếm ở địa chỉ nhưng nhỏ trỏ ptr đang dữ.

Xem thêm: Mbr Và Gpt Là Gì, 2 Cách Chuyển Đổi Định Dạng Ổ Cứng Về Legacy-Mbr

ptr có thứ hạng tài liệu bé trỏ int (int *), ptr chỉ hoàn toàn có thể trỏ cho trở nên loại int. Lúc này, compiler hiểu đúng bản chất yêu cầu so với 4 bytes (đúng bởi size thứ hạng int) trên bộ lưu trữ ảo tại khu vực mà lại ptr đang tàng trữ.


Chuyên mục: Công Nghệ