概述
先看一下有趣的段子:
下面都是我的猜想(耐心看完, 关于++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++)的这种不确定性的式子, 不推荐采用我的这种猜想方式
最后
以上就是长情花瓣为你收集整理的对于b = (++i) + (++i)为何是6的思考的全部内容,希望文章能够帮你解决对于b = (++i) + (++i)为何是6的思考所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复