正如標題所說,我在一些C講義中找到了這樣一個句子。算術賦值運算符 - 左側僅評估一次
我不能發明任何證明這句話的例子。
在我看來,每一次賦值操作都會被評估一次,因爲當我們希望對它進行多次評估時,我們會將其放入一個循環中。那麼我錯過了什麼?
我已經搜索,但在這裏找不到答案。
正如標題所說,我在一些C講義中找到了這樣一個句子。算術賦值運算符 - 左側僅評估一次
我不能發明任何證明這句話的例子。
在我看來,每一次賦值操作都會被評估一次,因爲當我們希望對它進行多次評估時,我們會將其放入一個循環中。那麼我錯過了什麼?
我已經搜索,但在這裏找不到答案。
Ç說:
(C99,6.5.16.2p3)僅在該左值形式E1 OP = E2從簡單賦值表達式E1 = E1 OP(E2)的不同的「A化合物分配E1只評估一次。「
下面是爲什麼它的問題的一些例子:
實施例1:
a[i++] += 1;
相同:
a[i] = a[i] + 1; i++;
由於+=
左操作數是評估一次。
如果不是計算一次這將是一樣的:
a[i++] = a[i++] + 1;
這當然是不同的(和未定義的行爲BTW)。
實施例2:
*foo() += 1;
foo
假設這裏返回一個指向標量類型的對象,併產生副作用(例如它打印在終端上的字符串)。使用複合賦值運算符時,它只會打印一次而不是兩次。
實施例3:
REG |= 0x01;
REG
假設這裏是一個IO寄存器(像#define REG (*(volatile uint8_t *) 0x42)
)和每讀取該特定IO寄存器觸發硬件事件。該寄存器只能用複合賦值操作符讀取一次,而不能兩次。
編輯:以下@R.評論我刪除線的例子3.我想大多數編譯器不會在這個表達式執行讀:REG = 31
或兩個與該表達式如下:REG = REG | 0x01
。
示例3不正確。無論您是分別使用'| ='或'|'和'=',寄存器都將被精確讀取一次,並且只寫入一次。這是因爲左值引用的對象不是作爲評估'='運算符的一部分讀取的。也許你想到的是''=''可能會在'|'和'='單獨執行時執行單指令讀 - 修改 - 寫週期,但我認爲這個假設是錯誤的; volatile並不要求,並且可能不會(在嚴格閱讀對volatile的要求下)甚至允許它。 –
@R。例3我可能太快了,因爲它不符合現實世界的例子。實際上,大多數編譯器可能不會像'REG = 31'這樣的簡單賦值來進行讀操作(例如http://gcc.gnu中的'vobj1')。org/wiki/VolatileAccessComparison)。但我認爲編譯器可以執行它。我無法看到C語言標準的觀點與此語句有所不同:'REG;'該值也未被使用,但大多數編譯器執行讀取操作。 – ouah
@R。順便謝謝你的評論,我編輯了我的答案。 – ouah
你的問題很不明確,措辭也不太好,但我懷疑你的筆記提到的是,組合的算術+賦值運算符允許你做某些事情而不用寫(並因此評估)左值的表達式比一次。例如,
*p++ += *q++; /* p is incremented once, as desired */
*p++ = *p++ + *q++; /* undefined behavior */
這尤其重要,當你在宏來使用這些,例如:
#define ACCUM(d,s) (d)+=(s) /* good */
#define ACCUM(d,s) (d)=(d)+(s) /* dangerous */
不要有什麼編譯方便,但這裏是一個有趣的花絮:
var1 += var++
將VAR1的值更改爲var1 + var
var1 += ++var
將VAR1的值更改爲var1 + (var + 1)
我認爲這是問題中的理解(或不是問題);問題是什麼意味着這個任務的LHS被評估一次 - 爲什麼(或什麼時候)這個關鍵? –
哦,我的錯誤我想我完全錯過了這個問題的觀點。 –
有一些化合物分配操作在下例如+ =, - =,* =,/ =,%=
例如, i + = 1它將i的值增加1,如i ++。
我認爲這是在問題中理解;問題是什麼意味着這個任務的LHS被評估一次 - 爲什麼(或什麼時候)這個關鍵? –
我已經熟悉你寫的東西,而不是我在這裏問的情況。無論如何感謝活動;) –
通常+=
操作員通過以下方式介紹:
x += y;
x = x+y; // does the same
但是,該說明試圖告訴你,這其實不準確,爲=
左側,+=
可能是任何表達。正如其他人所說,這可能導致未定義的行爲,但這不是問題的核心。
例如:
char* f() {
static char value = 'a';
printf("%c\n",value);
return &value;
}
void g() {
*f() = 'b'; // assigns 'b' which was 'a'
*f() += 2; // changes 'b' to 'd'
*f() = 'b';
*f() = *f() + 2; // changes 'b' to 'd'
}
的區別在於f
在最後一行,同時它在第二執行一次執行兩次。
+1不錯的說明示例。 –
有複合賦值運算符的數目。例如。 +=,-=,*=,/=,%=
爲a+=b
將give a=a+b
瞭解更多詳情請點擊this
的例子嗎?我不明白.. –
沒有任何實際解釋問題的任務,與例如相反。 'x + = 6' –
請參見[C++中| =運算符的含義](http://stackoverflow.com/questions/4217762/what-does-the-operator-mean-in-c/4217772#4217772)雖然它是針對C++的,但它的確解釋了對運營商的LHS進行一次評估意味着什麼。除了提及運算符重載(僅限於C++),註釋適用於C和'+ ='(和'| ='和其他賦值運算符)。 –