当前位置:  开发笔记 > 编程语言 > 正文

括号和赋值运算符顺序

如何解决《括号和赋值运算符顺序》经验,为你挑选了2个好方法。

我正在编写c表达式解析器并发现我不理解的行为:

#include 
#include 

int main()
{
    std::string string1;
    std::string string2 = std::string((string1 = std::string("first")) + " " + (string1 = std::string("second")));

    std::cout << string1 << std::endl;
    std::cout << string2 << std::endl;

    int int1;
    int int2 = (int1 = 1) + (int1 = 2);

    std::cout << int1 << std::endl;
    std::cout << int2 << std::endl;

    std::cin.get();

    return 0;
}

输出:

first
first first
2
4

我曾预料到:

second
first second
2
3

在C#中运行相同的程序时,我得到了预期的输出.你能解释一下那里发生了什么吗?

C#代码:https://gist.github.com/Kukkimonsuta/59543cfc4f7f73b8bebd



1> dasblinkenli..:

此代码在C++中具有未定义的行为,因为单个表达式会对同一个变量产生多个副作用(即两个赋值string1).这同样适用于int1变量.

在您的情况下,编译器将按照与您预期相反的顺序应用这两个副作用.即使它按照您预期的顺序应用它们,该程序仍然无效.

在C#中运行相同的程序时,我得到了预期的输出.

与C++不同,C#并没有给编译器开发人员留下太多的决定.这些表达式的评估顺序以及在C++中产生未定义行为的许多其他表达式都由语言标准很好地定义.


OP还提到了C#,因此值得在C#中添加,评估顺序在语言规范中明确定义.C#中的类似代码将始终给出相同的预期结果.

2> AlexD..:

这是C和C++中未定义的行为.变量int1在同一语句中被多次修改.

见序列点:

一个经常被引用的例子是C表达式i=i++,它显然都指定了i它的先前值和增量i....在C和C++中,评估这样的表达式会产生不确定的行为.

和脚注:

C99规范的第6.5#2条:" 在上一个和下一个序列点之间,一个对象的表达式的评估最多只能修改一次它的存储值.此外,只能访问先前的值来确定值.存储. "


除此之外,假设我们有不同的变量,结果仍然无法保证.与C#相反, C++没有指定表达式部分的计算顺序.

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有