请详细说明如何在以下计划中评估(a+=3,5,a)
。
#include <stdio.h>
int main()
{
int a=1,b=2,c=3;
printf("%d\n",a+=(a+=3,5,a));
}
答案 0 :(得分:1)
在以下代码中,我们会评估b
和c
,并将最后一个值添加到a
并分配给d
。
#include <stdio.h>
int main(void)
{
int a = 1, b = 2, c = 3, d;
d = a + (b, c);
printf("%d\n", d);
return 0;
}
节目输出:4
但是问题中的表达式有未定义的行为,因为a
在没有序列点的情况下被多次更改。
答案 1 :(得分:1)
正在考虑的代码是,在进行现代化并给出一些缺失空格时:
#include <stdio.h>
int main(void)
{
int a = 1, b = 2, c = 3;
printf("%d\n", a += (a += 3, 5, a));
return 0;
}
我的初步反应是“Why are these constructs undefined behaviour重复”,尽管这主要是关于++
和--
运算符,这些运算符在这些问题中更常见。
第二眼看到(a += 3, 5, a)
中有一个逗号运算符,这些运算符强加了序列点。就其本身而言,这很多表达都很好。如果它在b += (a += 3, 5, a)
中使用,则没有问题。该问题的文字只询问(a += 3, 5, a)
。
当然,, 5
没有任何用处。当消除它时,使用(a += 3, a)
的唯一原因是在加法和a
之间加上一个序列点。但是,在任何情况下我都无法想到您可以合法地需要该序列点。
更复杂的问题是a += (a += 3, 5, a)
的LHS评估是否与RHS正确排序。它是未定义的行为,因为尽管RHS表达中存在序列点,但在整体表达的LHS和RHS的评估之间没有序列点。
请记住,复合赋值运算符+=
的行为或多或少表现为:
a += x;
a = a + x;
不同之处在于LHS上的表达式(本例中为a
)仅评估一次。在这种情况下,没有问题。如果代码更复杂,这个细节很重要:
array[index++].member[subindex++] += 23;
现在至关重要的是LHS只被评估一次!
问题中的代码是棘手的代码,因为它有未定义的行为,所以应该在生产代码中避免使用。
我想知道为什么b
和c
完全在问题中;他们是未使用的变量。这么少的代码太混乱了!
经验法则:在单个表达式中避免多个增量,减量和复合赋值运算符。
高级经验法则(仅限专家):不要将多个增量,减量或复合赋值运算符应用于单个表达式中的同一变量。
如果您足够了解何时可以安全地违反规则(?:
),那么您不一定需要遵循经验法则。在此之前,请避免过度使用这些运营商。
答案 2 :(得分:-1)
c中printf的执行是从右到左。
(a+=3,5,a)
, a = 4
然后a+=(a+=3,5,a)
将最后一个值,即 a添加到
Thatswhy a变成了8。
答案 3 :(得分:-1)
这里(a+=3,5,a)
给出输出4,因为你放了任何东西
值a不考虑a + = 3。
例如:int a=1;
a+=2,8,5;
这里a = 3的值;因为a+=2
是3。
之后a+=(a+=3,5,a)
评估如下。
这里赋值运算符总是将最右边的值赋给左操作数。所以
这里是指定的。所以这会导致a+=a;
因此,在a=4;
操作之后,(a+=3,5,a)
的值为{。
我将再举一个例子int a=2;
a+=(a+=2,2,a,10)
将输出为14.因为(a+=2,2,a,10)
操作后a = 4的值。
右边分配10,即a+=10;
这将给我们14。
我希望你的问题得到解答。如果你有疑问,请在下面发表评论。