int x[100];
void *p;
x[0] = 0x12345678;
x[1] = 0xfacecafe;
x[3] = 0xdeadbeef;
p = x;
((int *) p) ++ ;
printf("The value = 0x%08x", *(int*)p);
編譯上述生成所需錯誤與++運算符的用戶線上的左值。
int x[100];
void *p;
x[0] = 0x12345678;
x[1] = 0xfacecafe;
x[3] = 0xdeadbeef;
p = x;
((int *) p) ++ ;
printf("The value = 0x%08x", *(int*)p);
編譯上述生成所需錯誤與++運算符的用戶線上的左值。
演職人員會創建一個類型爲int *
的臨時指針。您不能增加臨時數據,因爲它不表示存儲結果。
在C和C++ standardese,(int *)p
爲右值,這大致是指可以在一個賦值的右手側僅發生的表達式。
p
另一方面是左值,這意味着它可以有效地出現在任務的左側。只有左值可以增加。
你可以得到
p = (int*)p + 1;
預期的結果對復引用指針p
,這是一個左值使用遞增運算符,也可以工作:
(*(int**)&p)++;
然而,後者不是便攜式,因爲(void*)p
可能不具有與(int*)p
相同的表示形式。
Rvalue表達式((int *) p)
創建臨時類型int*
,其上運算符++
無法應用。
++
需要一個左值作爲其操作數。
由於@FredOverflow提到lvalues
和rvalues
與賦值很少有關。
數組仍然是不可分配的左值,因爲它們是不可修改的。 std::string("Prasoon")
是一個右值表達式,它仍然可以出現在賦值運算符的左側,因爲我們可以在臨時對象上調用成員函數(在這種情況下爲operator =
)。
沒有標量臨時值:)評估右值'((int *)p)'的結果只是一個值。 – fredoverflow 2011-03-20 08:28:25
@FredOverflow:我不認爲聲明「沒有標量臨時表」是100%正確的。關於'const int&ref = int()',你有什麼要說的?它不是創建一個標量臨時? – 2011-03-20 09:27:43
'int()'與'0'相同,但是你有一點:綁定到一個const引用可以隱式地創建一個標量臨時值。這個怎麼樣:「沒有*表達式*其結果是一個標量臨時的。」 – fredoverflow 2011-03-20 10:15:45
表達式((int *) p)
將存儲在變量p
中的指針看作是一個指向int的指針。如果你想治療變量本身作爲一個指向int變量(然後增加它),使用引用鑄造:
((int *&) p) ++ ;
感謝larsmans爲指向正確的方向。
我冒昧地深入挖掘了這一點。因此,爲了將來參考,根據C99標準(http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf)的6.5.2.4和6.5.4節:
6.5.2。4個後綴增量和減量運算
約束
或遞減操作員應 合格的或不合格的真實或 指針類型,併爲一個修改的左值 ..
..
後綴增量的操作數 6.5.4鑄造操作員
..
..
[腳註] 89)鑄造 不產生左值。因此,鑄造 到合格類型具有相同 作爲鑄造到不合格 版本的類型。
注意:這僅適用於C. C++可能會以不同方式處理強制類型轉換。
在C++中,左值和右值與賦值很少有關。 'array_name'是一個不能出現在賦值左邊的左值,'std :: string(「hello」)'是一個右值,可以。 – fredoverflow 2011-03-20 08:11:18
@FredOverflow:是的。順便說一句,我添加了一個解決這些問題的答案:) – 2011-03-20 08:21:05