请考虑以下声明.b中存储的值是多少?
int a=1;
int b = a+=1 ? a+=1 : 10;
Run Code Online (Sandbox Code Playgroud)
我得到了答案4.有人可以解释它是如何工作的.
pax*_*blo 14
它与优先权有关.如果您检查以下代码(a+=1为简单起见,最右边的更改):
#include <iostream>
int main (void) {
int a=1;
int b = a+=1 ? 7 : 10;
std::cout << b << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你会看到输出是8,而不是7或10.
那是因为声明:
int b = a+=1 ? 7 : 10;
Run Code Online (Sandbox Code Playgroud)
被解释为:
int b = (a += (1 ? 7 : 10));
Run Code Online (Sandbox Code Playgroud)
现在,将其应用于您的案例,我们得到:
int b = (a += (1 ? a += 1 : 10));
Run Code Online (Sandbox Code Playgroud)
并且,按执行顺序:
a += 1(因为1是真的)设置a为2.a += 2(2是上一步的结果)设置a为4.b = 4(4是上一步的结果).请记住,您不一定要依赖评估顺序.即使有一个序列点?(因此1在继续之前完全评估),最右边a += ...和最左边之间没有序列点a += ....并且在没有插入序列点的情况下修改单个变量两次是未定义的行为,这就是为什么gcc -Wall会给你非常有用的消息:
warning: operation on ‘a’ may be undefined
Run Code Online (Sandbox Code Playgroud)
它给你的这个事实4纯属巧合.它可以很容易地给你3,65535甚至格式化你的硬盘教你一课:-)
如其他答案中所述,由于C++的语法规则决定了必须如何解析复合表达式,因此这两个代码片段是等效的.
int a=1;
int b = a+=1 ? a+=1 : 10;
Run Code Online (Sandbox Code Playgroud)
和
int a=1;
int b = (a += (1 ? (a += 1) : 10));
Run Code Online (Sandbox Code Playgroud)
虽然在条件表达式中存在序列点,但它在第一个表达式(1)的求值与第二个和第三个表达式中的任何一个的求值评估之间(a += 1在这种情况下).在评估第二或第三表达式之后没有明确的额外序列点.
这意味着a在初始化程序中修改了两次,b没有插入序列点,因此代码具有未定义的行为.