簡體   English   中英

為什么在C中不允許表達式c =(a + b)++?

[英]Why is the expression c=(a+b)++ not allowed in C?

我試圖運行一部分代碼,不得不增加組合表達式a+b 在嘗試這樣做時,我寫了這個聲明

c=(a+b)++

在此聲明中收到以下錯誤 -
“表達必須是可修改的值”

為什么我收到此錯誤以及為什么遞增C中不允許的表達式的值?

在C中, ++的操作數必須是左值 - 內存中的一個位置。 ab都是左值 - 但它們的總和不是,它是一個右值

postincrement運算符只能應用於l值,即可以出現在賦值運算符左側的東西,最常見的是變量。

x++出現在表達式中時,它被評估為x ,之后x被增加。 例如a = 2; b = 2 * (a++); a = 2; b = 2 * (a++); 相當於a = 2; b = 2 * a; a = a + 1; a = 2; b = 2 * a; a = a + 1;

您的示例無法編譯,因為無法為a+b分配值。 更明確的是c=(a+b)++將等同於c = (a + b); (a + b) = (a + b) + 1; c = (a + b); (a + b) = (a + b) + 1; ,這毫無意義。

因為++運算符需要引用(l值),而不是值(r值)。

i++會將i增加1並在增加之前返回i的值。

(a + b)++不能增加(a + b)值,因為(a + b)實際上不是一個參考(在內存中,更新a + b值的位置)。

C11 6.5.3.1p1

  1. 前綴增量或減量運算符的操作數應具有原子,限定或非限定的實數或指針類型,並且應為可修改的左值。

這意味着,如果我們有一個構造something ++ ,那么something

  • 必須是實數:積分或浮點數,但不能是復數
  • 或者可以是指針類型(但由於沒有算術定義,因此無法執行void指針)
  • 它也可以是_Atomicvolatile
  • 但它必須是左值 ,即指定由增量修改的對象
  • 並且左值必須是可修改的(例如,它不能是const限定的)

表達方式

a + b

不是左值表達式,它不指定對象。 這是一個算術表達式; 並且算術表達式的值不是左值。 雖然可以向該值添加1,但表達式的值不是要修改的對象。


但是,給定

int a, *b, c[5][6];
struct FOO { char *bar; } foo, *fooz;
double *funnyfunc(int x);

所有這些表達式都是可修改的標量左值:

a
*(b + 5)
c[1][4]
foo.bar
fooz->bar
funnyfunc(5)[42]

你可以向他們申請++


還有一個問題

c = (a + b) ++

后增量表達式的值是增量的值,即即使a + b是可修改的, c也不會有值a + b + 1而是a + b ; 並且a + b將改變其存儲值以用於后續評估。

關於增量的含義存在混淆。 在您的問題中,您應該在表達式a + b添加一個,可以將其描述為計算ab的總和並遞增1 在C中,增量運算符++具有非常特定的語義:它將標量變量的值作為副作用遞增,並根據它是放在所述變量之前還是之后來計算增量值或原始值。 關於對象的類型以及在同一表達式中的其他地方使用相同對象,還應用了進一步的限制。

對於您的問題,解決方案是使用加法運算符添加1a + b + 1

一個容易記住的陳述是

LValue - 左值

LValue必須是一個容器。 換句話說,一個可以存儲內容的內存位置,並且不限於這樣做 。變量是C中唯一可用的容器。

在示例(a + b)++

(a + b)評估某個值,而不一定是一個可以再次用於操作的容器。

比如考慮一下

const int a=10; 
a = 5;

類似的錯誤將在這里升起,即使a在這里是一個容器,它是沒有用的,因為它是一個constant ,並沒有其他的操作,這是不允許的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM