正如标题所说,我在一些 C 讲义中找到了这样一个句子。
我无法发明任何证明这句话的例子。
在我看来,每个赋值操作都会被评估一次,因为当我们希望它被多次评估时,我们会进入一个循环。那我错过了什么?
我已经搜索但在 SO 上找不到答案。
正如标题所说,我在一些 C 讲义中找到了这样一个句子。
我无法发明任何证明这句话的例子。
在我看来,每个赋值操作都会被评估一次,因为当我们希望它被多次评估时,我们会进入一个循环。那我错过了什么?
我已经搜索但在 SO 上找不到答案。
C 说:
(C99,6.5.16.2p3)“形式为 E1 op= E2 的复合赋值与简单赋值表达式 E1 = E1 op (E2) 的不同之处仅在于左值 E1 仅计算一次。”
以下是一些为什么重要的例子:
示例 1:
a[i++] += 1;
是相同的:
a[i] = a[i] + 1; i++;
因为 的左操作数+=
被评估一次。
如果它没有被评估一次,它将与以下内容相同:
a[i++] = a[i++] + 1;
这当然是不同的(顺便说一句未定义的行为)。
示例 2:
*foo() += 1;
假设foo
这里返回一个指向标量类型对象的指针并产生副作用(例如,它在终端上打印一个字符串)。使用复合赋值运算符,它将只打印一次字符串,而不是两次。
示例 3:
REG |= 0x01;
假设REG
这里是一个 IO 寄存器(类似于 #define REG (*(volatile uint8_t *) 0x42)
),并且每次读取这个特定的 IO 寄存器都会触发一个硬件事件。使用复合赋值运算符将只读取一次寄存器,而不是两次。
编辑:跟随@R。评论我打了这个例子3。我认为大多数编译器不会在这个表达式中执行一次读取:REG = 31
或使用这个表达式进行两次读取:REG = REG | 0x01
。
通常+=
操作符的引入方式如下:
x += y;
x = x+y; // does the same
=
但是,注释试图告诉您这实际上是不准确的,因为and的左侧+=
可能是任何表达式。正如其他人所说,这可能导致不确定的行为,但这不是问题的核心。
例如:
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
在最后一行执行两次,而在第二行执行一次。
您的问题非常不清楚且措辞不佳,但我怀疑您的注释所指的是算术+赋值运算符的组合允许您在不多次编写(并因此评估)左值表达式的情况下执行某些操作。例如,
*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)
C 中有一些复合赋值操作,例如+=,-=, *=,/=,%=
例如i += 1它像i++一样将 i 的值增加1 。
有许多复合赋值运算符。例如。+=,-=,*=,/=,%=
a+=b
更多give a=a+b
详情请点击这里