条件运算符用法

时间:2011-01-08 04:23:40

标签: c++

请考虑以下声明。存储在b中的值是什么?

int a=1;
int b = a+=1 ? a+=1 : 10;

我得到答案为4.任何人都可以解释它是如何工作的。

3 个答案:

答案 0 :(得分:14)

它与优先权有关。如果您检查以下代码(为简单起见,最右侧a+=1已更改):

#include <iostream>

int main (void) {
    int a=1;
    int b = a+=1 ? 7 : 10;
    std::cout << b << std::endl;
    return 0;
}

您会看到输出为8,而不是710

那是因为声明:

    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 += 22是上一步的结果)将a设置为4
  • b = 44是上一步的结果)。

请记住,您不一定要依赖评估顺序。即使?处有一个序列点(以便在继续之前完全评估1),最右边的a += ...和最左边的a += ...之间也没有序列点。并且在没有插入序列点的情况下修改单个变量两次是未定义的行为,这就是gcc -Wall将为您提供非常有用的消息的原因:

warning: operation on ‘a’ may be undefined

它给你4的事实纯属巧合。它可以很容易地为您提供365535甚至格式化您的硬盘来教你一课: - )

答案 1 :(得分:6)

如其他答案中所述,由于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被修改了两次而没有插入序列点,因此代码具有未定义的行为

答案 2 :(得分:2)

装配分析:

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.同样a = 4。