则该函数或表达式有副作用

在第三行中,x和y是递增/递减之前,他们的评价,所以他们的新值打印由cout。在第五行,一个原始值的临时副本(x = 6,y = 4)发送给cout,然后原来的x和y是递增的。这就是为什么从后缀式操作符的结果没有改变到下一行。


规则:在增量和后减量后有利于预增加和预减量。前缀版本不仅更加高效,你就不太可能遇到奇怪的问题。


副作用


如果某个函数或表达式修改某个状态(例如内存中的任何存储信息),输入或输出,或者调用具有副作用的函数,则该函数或表达式有副作用。


大多数情况下,副作用是有用的:

1
2
3
x = 5;
++x;
std::cout << x;

上面例子中的赋值操作符具有永久改变x值的副作用。即使语句完成执行后,x的值也将为5。++运算符具有增加X X的输出具有修改控制台的副作用副作用。


然而,副作用也会导致意想不到的结果:

int add(int x, int y)
{
    return x + y;
}
 
int main()
{
    int x = 5;
    int value = add(x, ++x); // is this 5 + 6, or 6 + 6?  It depends on what order your compiler evaluates the function arguments in
 
    std::cout << value; // value could be 11 or 12, depending on how the above line evaluates!
    return 0;
}
C++没有定义在函数的参数进行评估。如果先对左参数进行求值,则这将成为一个添加(5, 6)的调用,等于11。如果首先对正确的参数进行求值,则这将成为添加(6, 6)的调用,等于12!请注意,这只是一个问题,因为一个参数的函数()有副作用。

1
2
3
4
5
6
7
8
int main()
{
    int x = 1;
    x = x++;
    std::cout << x;
 
    return 0;
}



下面是另一个流行的例子:


这个程序打印什么值?答案是:它是未定义的。


如果+ +是在分配应用于X,答案是1(后缀运算符++递增x从1到2,但其值为1,使表达变得x = 1)。


如果+ +是赋值后应用于X,答案会是2(这个值为x = x,然后后缀运算符++应用,增加x从1到2)。


还有其他的情况下,C++并不指定某些东西的计算顺序不同,所以编译器会做出不同的假设。甚至当C++不清楚事情应该怎样评价,一些编译器实现涉及的变量具有副作用的不当行为。这些问题通常可以通过确保任何应用于副作用的变量在给定语句中使用不止一次来避免。


规则:不要在给定语句中使用多于一次应用于其的副作用的变量。如果这样做,结果可能是未定义的。


请不要问为什么违反上述规则的程序产生的结果似乎没有意义。这就是当你写的程序有“未定义的行为”时会发生的情况。


有关未定义行为的更多信息,请重新阅读第1.3课的“未定义行为”部分——首先查看变量、初始化和赋值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值