简体   繁体   English

条件运算符用法

[英]conditional operator usage

Consider the following statement. 请考虑以下声明。 What will be the value stored in b? b中存储的值是多少?

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

I get the answer as 4. Can anyone explain how that works please. 我得到了答案4.有人可以解释它是如何工作的。

It has to do with precedence. 它与优先权有关。 If you examine the following code (with the rightmost a+=1 changed for simplicity): 如果您检查以下代码(为简单起见,最右边a+=1更改):

#include <iostream>

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

you will see that the output is 8 , not 7 or 10 . 你会看到输出是8 ,而不是710

That's because the statement: 那是因为声明:

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

is being interpreted as: 被解释为:

    int b = (a += (1 ? 7 : 10));

Now, applying that to your case, we get: 现在,将其应用于您的案例,我们得到:

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

and, in order of execution: 并且,按执行顺序:

  • the rightmost a += 1 (since 1 is true) sets a to 2 . 最右边的a += 1 (因为1为真)将a设置为2
  • the leftmost a += 2 ( 2 is the result of the previous step) sets a to 4 . 最左边的a += 22是上一步的结果)将a设置为4
  • b = 4 ( 4 is the result of the previous step). b = 44是上一步的结果)。

Just keep in mind that you can't necessarily rely on that order of evaluation. 请记住,您不一定要依赖评估顺序。 Even though there is a sequence point at the ? 即使有一个序列点? (so that 1 is evaluated fully before continuing), there is no sequence point between the rightmost a += ... and the leftmost a += ... . (以便在继续之前完全评估1 ),最右边的a += ...和最左边的a += ...之间没有序列点。 And modifying a single variable twice without an intervening sequence point is undefined behaviour, which is why gcc -Wall will give you the very useful message: 并且在没有插入序列点的情况下修改单个变量两次是未定义的行为,这就是gcc -Wall将为您提供非常有用的消息的原因:

warning: operation on ‘a’ may be undefined

That fact that it gives you 4 is pure coincidence. 它给你4事实纯属巧合。 It could just as easily give you 3 , 65535 or even format your hard disk to teach you a lesson :-) 它可以很容易地给你365535 ,甚至格式化你的硬盘给你一个教训:-)

As stated in the other answers these two code snippets are equivalent due to the grammar rules of C++ which determine how compound expressions must be parsed. 如其他答案中所述,由于C ++的语法规则决定了必须如何解析复合表达式,因此这两个代码片段是等效的。

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

and

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

Although there is a sequence point in a conditional-expression it is between the evaluation of the first expression ( 1 ) and the evaluation of whichever one of the second and third expressions is evaluated ( a += 1 in this case). 虽然在条件表达式中存在序列点,但它在第一个表达式( 1 )的求值与第二个和第三个表达式中的任何一个的求值的评估之间(在这种情况下, a += 1 )。 There is no explicit extra sequence point after the evaluation of the second or third expression. 在评估第二或第三表达式之后没有明确的额外序列点。

This means that a is modified twice in the initializer for b without an intervening sequence point so the code has undefined behavior . 这意味着ab的初始值设定项中被修改两次而没有插入序列点,因此代码具有未定义的行为

Assembly analysis: 装配分析:

int main() 
{
    int a=1;
    int b = a+=1 ? a+=1 : 10;
    return 0;
}

Assembly code generated (using MinGW) for the above code is shown below. 为上述代码生成的汇编代码(使用MinGW)如下所示。 The comments are mine, of course! 当然,评论是我的! Read the comments also! 阅读评论也!

 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) represent memory location of a , and at a distance 4 byte from it, that is, 8(%esp) represents b . 12(%esp)表示的存储器位置a ,并且在从它的距离4字节,即, 8(%esp)表示b At the end, the value at both these memory locations is 4. 最后,这两个内存位置的值都是4。

Hence, b = 4. Also a = 4. 因此,b = 4.At = 4。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM