2010-10-06 29 views
6

Đi đoạn mã này:Làm thế nào để con trỏ đến con trỏ và địa chỉ của nhà điều hành làm việc?

int a; 
int *pointer = &a; 

int **b = &(&(*pointer)); 

Sẽ tập trên b đến địa chỉ của pointer hay không?

Lý do tôi hỏi là vì *pointer cung cấp giá trị a và tham chiếu đó là địa chỉ a. Địa chỉ này có được coi là địa chỉ của a hay không cũng được coi là pointer.

Điều này có hợp lý không? Tôi có thể làm:

&(*pointer) = a; 
+0

'b = & pointer' là cách chính xác để lấy địa chỉ của con trỏ tới' a'. –

Trả lời

7

số Trong C, bạn chỉ có thể có được một con trỏ đến một khu vực lưu trữ (có nghĩa là một biến, một phần tử mảng, hoặc con trỏ khác; họ gọi là những "l-giá trị"), không cho bất kỳ biểu hiện nào. Bạn không thể nhận được một con trỏ tới một biểu thức không có vùng lưu trữ được xác định (như một phần bổ sung hoặc kết quả của một cuộc gọi hàm). Tuy nhiên, cần lưu ý rằng C++ làm rối các quy tắc này với các tham chiếu, nhưng vì mục đích rõ ràng, tôi sẽ bỏ nó ra.

Con trỏ không phải là phép thuật: cuối cùng, chúng chỉ là số nguyên. Vì vậy, khi bạn nhận được con trỏ của một con trỏ, nó giống như bạn đã nhận được con trỏ của một số nguyên. Nó không có hậu quả nhiều hơn nữa. Ví dụ:

Ví dụ: nếu bạn nhận con trỏ đến a trong mã của mình, bạn chỉ cần sao chép địa chỉ này trong một biến khác. Không có gì ngăn bạn thay đổi biến số đã nói:

int a; 
int* p = &a; 
p = NULL; 

Và thực hiện việc này, bạn a sẽ vẫn không thay đổi gì. Tất cả những gì bạn có thể thay đổi về a là giá trị của nó. Địa chỉ của nó là bất biến. Bất cứ điều gì khác sẽ ngụ ý rằng &a = NULL (hoặc bất kỳ giá trị con trỏ khác) sẽ làm việc, mà không.

+0

Thankyou, tôi hiểu cách con trỏ hoạt động. Tôi chỉ muốn xác nhận rằng & (* con trỏ) là một giá trị. –

+0

@Alexander Rafferty Trên thực tế, GCC sẽ cho phép bạn làm điều đó. Tuy nhiên nó sẽ phát ra một cảnh báo không dùng nữa nói rằng '& (* pointer)' không thực sự là một giá trị l và nó sẽ ngừng hoạt động ở đâu đó trong tương lai, vì vậy bạn không nên làm điều đó. Clang sẽ phát ra một lỗi nghiêm trọng. Tôi không biết những gì Visual Studio sẽ nói, nhưng nó có thể sẽ phát ra một lỗi cứng quá. – zneak

+0

"Nếu bạn không thể làm điều đó, thì bạn không thể có được một con trỏ đến nó." là sai. Mảng và biến const là một vài ngoại lệ. –

1

Bạn không thể lấy địa chỉ của một cái gì đó hai lần, vì vậy mã trên có thể sẽ không biên dịch (bạn đã thử điều đó chưa? Điều gì đã xảy ra?).

+0

Khi tôi thử nó, gcc nói 'warning: argument to '&' không thực sự là một lvalue; đây sẽ là một lỗi cứng trong tương lai' nhưng '** b' cho giá trị' a'. –

+0

@jleedev: Nó phải là một lỗi biên dịch. –

+0

@jleedev: Có vẻ như bạn có phiên bản gcc khá cũ. Bạn đang dùng gì? –

3

int **b = &(&(*pointer));

Điều này không hoặc không nên biên dịch.

Bạn chỉ có thể lấy địa chỉ của một giá trị l. (Xem dưới đây để xem mô tả)

C++ 03 S5.3.1-2:

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualifiedid. In the first case, if the type of the expression is “T,” the type of the result is “pointer to T.” In particular, the address of an object of type “cv T” is “pointer to cv T,” with the same cv-qualifiers. For a qualified-id, if the member is a static member of type “T”, the type of the result is plain “pointer to T.” If the member is a nonstatic member of class C of type T, the type of the result is “pointer to member of class C of type


...and the reference of that is the address of a...

Ngoài ra bạn đang sử dụng tài liệu tham khảo hạn sai ở đây. & là một biểu tượng được sử dụng cho nhiều thứ khác nhau. một trong những điều đó là khai báo các tham chiếu, một điều không liên quan là địa chỉ của toán tử đơn nhất. Sau này không được gọi là tham chiếu.


Does this make sense? Could I do: &(*pointer) = a;

Một địa chỉ của một biến, và do đó &(*pointer) hoặc tương đương &a là r-giá trị.

Bạn không thể chỉ định bất kỳ thứ gì cho r-avlue.Bỏ qua những thứ như const bạn có thể xem xét một giá trị r một cái gì đó phải xuất hiện ở phía bên tay phải. Giá trị l giống như bên tay trái nhưng thực sự nó có nghĩa là nó có thể được lưu trữ trong một vị trí lưu trữ (sự khác biệt là vì một đối tượng const chẳng hạn không thể xuất hiện ở phía bên trái nhưng nó vẫn được coi là một l- giá trị).

0

Trong biểu hiện của bạn:

* ptr là một giá trị trái & (* ptr) là một rvalue

& (& (* ptr)) là một biểu hiện vô hình thành như bạn đang cố gắng để có địa chỉ của một rvalue không được phép trong C++.

Hơn nữa,

& (* pointer) = a;

không đúng định dạng, vì loại biểu thức lhs là 'int *' trong đó loại biểu thức rh là 'int'. C++ không cho phép chuyển đổi 'int' thành 'int *'

0

Would the above set b to the address of pointer or not?

Không, nó sẽ không. &(*pointer) là địa chỉ của a, chỉ là một số (giá trị r) và bạn không thể lấy địa chỉ hoặc gán cho giá trị r. Vì vậy, cả hai &(&(*pointer))&(*pointer) = a sẽ không biên dịch.

Địa chỉ pointer chỉ đơn giản là &pointer, vì vậy, sẽ hoạt động là int **b = &pointer;.

0

1.No, và điều đó làm cho lỗi biên dịch tại int **b = &(&(*pointer));
2.Set b đến địa chỉ của con trỏ: int **b = &pointer;
3. &(*pointer) = a; -> NO bạn không thể. &something là hằng số không thể thay đổi, phải là *pointer = a; hoặc pointer = &a;

Các vấn đề liên quan