对于b = (++i) + (++i)为何是6的思考

先看一下有趣的段子:

下面都是我的猜想(耐心看完, 关于++i的在后面, 我需要一步一步引入依据才行):

#include <iostream>

// 探究括号表达式返回的是不是左值:

#define print(x) std::cout << (x) << std::endl;
#define init_x_y \
    int x{10}, y { 20 }

void fun1(void);
void fun2(void);
void fun3(void);
void fun4(void);

int main(void)
{
    fun1();
    fun2();
    fun3();
    fun4();

    return 0;
}

void fun1(void)
{
    // 即时加上括号, 仍然可以给变量x赋值, x本来是10, 赋值后变成20
    // 初步说明括号表达式返回的是左值
    init_x_y;
    (x) = y;
    print(x);
}

void fun2(void)
{
    // 我想对x递增100, 但由于括号表达式返回的是左值, 所以x被赋值为20
    // 再一次吻合括号返回左值的说法
    init_x_y;
    (x += 100) = y;
    print(x);
}

void fun3(void)
{
    // 假设括号返回的是左值, 则下面表达式应该类似于:
    // b = i + i
    // 然后第一次这个i由1变成2, 然后(++i)返回的结果是左值i而不是右值2
    // 第二次i由2变成3, 然后(++i)返回的结果是左值i而不是右值3
    // 最后执行两个(++i)返回的结果, 即b = i + i, 因为这个i已经变成了3
    // 所以这个b最终结果是6

    // 再一次验证了猜想: 括号表达式返回左值

    int i = 1;
    int b = (++i) + (++i);
    print(b);

    // 假设括号表达式返回的是左值, 则下面的表达式应该类似于:
    // x = 2 * y
    // 但下面的情况特殊, 因为不知道是从左边开始执行还是从右边开始
    // 假设1: 从左边开始:
    // 先执行(y *= 5), y变成10返回y
    // 然后执行(++y), y由10变成11, 返回y
    // 所以 x = 2 * y == 22
    // 假设2: 从右边开始:
    // 先执行(++y), y由2变成3
    // 然后执行(y *= 5), y由3变成15, 返回y
    // 最后 x = 2 * y == 30

    // 以上假设, 只要符合其中一种, 就很大概率上能够证明猜想:
    //      括号表达式返回左值确实成立

    int x = 0, y = 2;
    x = (y *= 5) + (++y);
    print(x);
    // 返回的结果是22, 能够作为有力的依据证明括号表达式返回左值确实成立
}

void fun4(void)
{
    // 但视乎(++i)的个数不止两个, 或者出现的不是(++i)而是(i++)的话, 我的猜想就不能成立
    // 按照上面的分析思路, 理应来说, 这个b应该是 b = 5 * i, i = 5, 所以b是25才对
    // 然而结果却出人意料的是15,
    // 我的猜想不能支持这一情况
    int i = 1;
    int b = 0;
    b = (++i) + (++i) + (++i) + (++i);
    print(b);

    // 这个例子难以有效的证明我的猜想不成立
    // 因为这个(x++)它有一个特点, 就是你不知道它是执行完
    // (x++) + (x++)这个之后, x再递增
    // 或者是执行其中一个后这个x再递增
    // 难以判断, 有可能是并列在一起运行, 给我的感觉就像是多线程那样出现资源抢占的问题
    // 即时结果不与我的猜想一致, 也难以作为有力的依据说我的猜想不成立!
    int x = 1;
    int y = 0;
    y = (x++) + (x++);
    print(y);
}

// 结论: 多于较短的式子来说, 可以优先采用我的猜想, 来分析程序
// 但对于比较长的语句, 或者出现(i++)的这种不确定性的式子, 不推荐采用我的这种猜想方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值