它只是發生在我身上,我不知道如何初始化一個指針從非指針值的指針在C++一個聲明:初始化指針,指針使用碳多重地址運營商或C++
int a = 1;
int** ppa = &&a; //Does not compile
int** ppa = &(&a); //Does not compile
int* pa = &a; //Works but is a
int** ppa = &pa; //Two step solution
我錯過了什麼,這兩個陳述是唯一的方法嗎?
它只是發生在我身上,我不知道如何初始化一個指針從非指針值的指針在C++一個聲明:初始化指針,指針使用碳多重地址運營商或C++
int a = 1;
int** ppa = &&a; //Does not compile
int** ppa = &(&a); //Does not compile
int* pa = &a; //Works but is a
int** ppa = &pa; //Two step solution
我錯過了什麼,這兩個陳述是唯一的方法嗎?
如果你想有一個指針的指針,要指出必須某處內存所在的指針,所以我覺得不可能有一個「一步到位的解決方案」,因爲你需要一個你可以指向的指針變量。
(注:這句話是不是意味着是一個語言試用使用一句話:-)「點」,儘可能多)當你做對以下
您無法獲得臨時指針。 &a
產生r值。它不允許有實際的地址。
這是100%正確的,但我接受了Philip的回答,因爲它解釋了爲什麼是這樣的原因,而不是僅僅指出標準。 – 2010-09-30 05:31:52
你想要一個指針(稱爲PP
)到一個指針(稱爲P
)?
然後P
必須實際存在。這意味着你必須聲明它。
當然,編譯器會在&&a
上失敗 - 因爲你不能獲取地址的地址。你可以取指針的地址 - 但你必須首先聲明指針。
這樣:
int a = 1;
int *P = &a;
int **PP = &P;
解析器在'&& a'上失敗並不是因爲你不能獲取地址的地址,而是因爲&&是一個在聲明中此時無效的單個標記。 'int ** ppa = x &&a;'可能是一個適當類型的'x'和一個適當重載的'&&'(邪惡!)的有效初始化,但它不會是地址的地址。 – 2010-09-28 08:04:29
:
char a;
char* b = &a;
char** c = &b;
首先現在存在於堆棧上。它顯然有一個內存地址(即它的堆棧位置),這是你分配給b的地址。 b現在也存在於棧中,然後你可以將它的內存地址傳遞給c。但是,您不能在沒有中間堆棧的情況下獲取值的地址,因爲如果沒有明確創建它,它就不存在。
其他很多都是正確的:你指向指針的指針必須指向某個東西。然而,在C99可以使用compound literals欺騙:
int a = 1;
int **ppa = &(int *){ &a };
複合文字只是基本未命名的對象,並具有相同的存儲規則視爲正常對象。 (但是你不能用static
關鍵字給函數作用域複合文字靜態存儲持續時間)。你甚至可以將其嵌套這樣你就可以在前面的例子改寫爲單行:
int **ppa = &(int *) { &(int) { 1 } };
這很可能是未定義的行爲,並可能在應用程序首次使用指針時崩潰。複合文字是一個臨時文字,編譯器可以重複使用這個空格,所以'* ppa'在第二行的執行過程中指向'&a',但可能指向其他任何東西。 – 2010-09-28 08:04:45
@David Rodriguez:不,你錯了。複合文字將具有與'a'和'ppa'相同的存儲持續時間:當在函數外面時是靜態的,否則在關閉塊的持續時間內是自動的。見C99 6.5.2.5(6)。 – schot 2010-09-28 08:09:33
你是完全正確的。我應該在跳進評論之前檢查標準......如果您在任何時候修改了答案,評論和我將把-1變成+1,它現在不允許我改變它。無論如何,根據你想要用指針做什麼,它和中間變量解決方案一樣危險。 – 2010-09-28 08:22:32
C++ 03 [Section 5.3.1
]說
一元&操作的結果是一個指針,其操作數。操作數應該是左值或合格的ID。在第一種情況下,如果表達式的類型是「T」的結果的類型是「指針T.」
在&&a
,&
操作者不能被應用到的&a
因爲結果的結果不是lvalue
。
又讀this線程
的地址是一個數字。它只有一個地址,如果它保存在一個變量中,即一個指針。所以
int *i1 = &a;
是有道理的,但
int **i2 = &&a;
是沒有意義的。然而,
int **i2 = &i1;
確實有意義。合理?
你的術語是錯誤的。運算符的地址*會產生一個指針,請參見[ISO03,5.3.1 expr.unary.op§2]。通常會調用指針*值*「地址」和指針*變量*「指針」,但嚴格來說,這是錯誤的。 – fredoverflow 2010-09-28 10:26:16
我使用的術語是常用的。標準意義上的指針的值是任何意義上的地址,而這在任何意義上都是一個數字。把我說的另一種方式,&不產生*變量,*因此它不會產生任何地址可以採取。 – EJP 2010-09-28 10:33:55
當您執行類似&&a;
這樣的操作時,問題是您要求提供「地址a
」的地址。
這沒有意義。我們可以得到a
的地址就好了,但是這並不能給我們一個我們可以接受的地址。它只是給了我們一個指針值。在該值存儲在某個地方之前,我們不能接受它的地址。
如果您有諸如2+2
的代碼,結果也沒有地址。它只是價值4,但它還沒有存儲在任何地方,所以我們不能接受地址。一旦我們將它存儲到一個int
變量中,我們就可以獲取該變量的地址。
基本上,問題是值和變量之間的差異。值只是一個數字(或一個字符或其他數據)。變量是存儲值的地方。一個變量有一個地址,但一個值沒有。
在C++中 - 說,它是rvalues和左值之間的差異。一個右值本質上是一個臨時值,它通常是從另一個操作返回的值(例如您的案例中的&
運算符),但它尚未存儲在任何地方。
一旦你將它存儲到一個變量,你會得到一個左值,左值有一個你可以採取的地址。
所以是的,你需要兩個單獨的陳述。首先你得到地址,然後你在某處存儲該地址。然後你可以把這個「某處」的地址。
您的術語是錯誤的。運算符的地址*會產生一個指針,請參見[ISO03,5.3.1 expr.unary.op§2]。通常會調用指針*值*「地址」和指針*變量*「指針」,但嚴格來說,這是錯誤的。 – fredoverflow 2010-09-28 10:25:26
@Fred:夠公平的。我懷疑我會因此而陷入困境。 ;)這會教我嘗試重新定義C++語義:p – jalf 2010-09-28 10:28:28
修正了一下。希望我得到最具誤導性的位。 – jalf 2010-09-28 10:30:12
爲什麼你認爲在這種情況下你需要一個指針指針? – SingleNegationElimination 2010-09-28 07:55:25
[指針指向C指針的工作原理]可能的重複(http://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c) – 2010-09-28 07:56:56
@Jens Gustedt,this不是重複的。鏈接的問題總體上是關於指針的。這個問題是關於具體情況。 – 2010-09-28 08:05:49