[英]conditional operator usage
请考虑以下声明。 b中存储的值是多少?
int a=1;
int b = a+=1 ? a+=1 : 10;
我得到了答案4.有人可以解释它是如何工作的。
它与优先权有关。 如果您检查以下代码(为简单起见,最右边a+=1
更改):
#include <iostream>
int main (void) {
int a=1;
int b = a+=1 ? 7 : 10;
std::cout << b << std::endl;
return 0;
}
你会看到输出是8
,而不是7
或10
。
那是因为声明:
int b = a+=1 ? 7 : 10;
被解释为:
int b = (a += (1 ? 7 : 10));
现在,将其应用于您的案例,我们得到:
int b = (a += (1 ? a += 1 : 10));
并且,按执行顺序:
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
它给你4
事实纯属巧合。 它可以很容易地给你3
, 65535
,甚至格式化你的硬盘给你一个教训:-)
如其他答案中所述,由于C ++的语法规则决定了必须如何解析复合表达式,因此这两个代码片段是等效的。
int a=1;
int b = a+=1 ? a+=1 : 10;
和
int a=1;
int b = (a += (1 ? (a += 1) : 10));
虽然在条件表达式中存在序列点,但它在第一个表达式( 1
)的求值与第二个和第三个表达式中的任何一个的求值的评估之间(在这种情况下, a += 1
)。 在评估第二或第三表达式之后没有明确的额外序列点。
这意味着a
在b
的初始值设定项中被修改两次而没有插入序列点,因此代码具有未定义的行为 。
装配分析:
int main()
{
int a=1;
int b = a+=1 ? a+=1 : 10;
return 0;
}
为上述代码生成的汇编代码(使用MinGW)如下所示。 当然,评论是我的! 阅读评论也!
call ___main //entering into main()
movl $1, 12(%esp) //int a = 1; means 12(%esp) represents a;
incl 12(%esp) //a+=1 ; a becomes 2
movl 12(%esp), %eax //loading 'a' onto a register(eax); eax becomes 2
addl %eax, %eax //adding the register to itself; eax becomes 4
movl %eax, 12(%esp) //updating 'a' with the value of eax; 'a' becomes 4
movl 12(%esp), %eax //this step could be optimized away; anyway it loads value of 'a' onto the register(eax); eax becomes 4, in fact even earlier it was 4 too! needless step!
movl %eax, 8(%esp) //loading the value of eax at another memory location which is 8(%esp); this location represents b;
movl $0, %eax //making eax zero! the return value of main()!
leave //now main() says, please leave me!
12(%esp)
表示的存储器位置a
,并且在从它的距离4字节,即, 8(%esp)
表示b
。 最后,这两个内存位置的值都是4。
因此,b = 4.At = 4。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.