用C++处理输出表达式

Processing Output expression in C++

本文关键字:表达式 输出 处理 C++      更新时间:2023-10-16

我有下面的简单程序,它初始化三个变量的值,然后以表达式的形式给出输出。

#include<iostream>
#include<conio.h>
using namespace std;
int main()
{
   volatile int a = 10, b = 20, c = 30;
    cout << a+b+c << " " << (c=c*2) << " "<< (b =b*2);
    getch();
    return 0;
}

以上代码的输出是

 110 60 40

但是a=10,b=20c=30,所以a+b+c应该是10+20+30 = 60

这是因为函数的参数是从右到左处理的,但却是从左到右打印的。

在C++中,函数参数的求值顺序是未定义的。也就是说,在的声明中

std::cout << a+b+c << " " << (c=c*2) << " "<< (b =b*2);

根据首先计算的子表达式,会得到不同的结果。编译器可以选择从左到右对输出运算符的参数求值,但也可以按不同的顺序(例如从右到左)对其求值,然后执行适当的函数调用。

此代码的输出未定义。

在C++中,如果分配变量,则只允许在同一语句中使用以计算新值。任何其他用途都具有未定义的效果。(注意,您计算c是为了打印(第1个print子句),也是为了计算新的c(c=c*2)。

后一种用途是批准的,前一种则不是。

大多数编译器会将c的第一次使用计算为赋值前的值或赋值后的值,但事实上,他们甚至没有义务让它与任何相关的值进行求值。即使是相关的,也可能不是它在逻辑上保持的值,例如,如果赋值是(c=2*c+5),你也可以很容易地找到映射到c*=2,c+=5的值,并且第一个print子句可能会得到中间状态,而不是开始或结束状态。

b也存在同样的问题。编译器在处理这一问题时甚至不能被认为是一致的,因为它们的操作可能合理地取决于寄存器分配,而寄存器分配取决于本地代码。