没亲手做过编译器就是被人欺,从一道变态的i++题猜编译器的行为(表达式从左往右扫描,同一变量相互影响)

首先不要被人蒙了,如果是这样,根本编译不过:

int i=1;
int b=i+++++i;
printf("%d %d\n", b ,i);

Mingw报错:error: lvalue required as increment operand (好像是说,++缺左值,这里的++是上题的第三第四个加号)

VC2010报错:error C2105: ‘++‘ needs l-value

--------------------------------------------------------------------------

正确的面试题应该是这样:

int i=1;
int b=i++ + ++i;
printf("%d %d\n", b ,i);

我没做过编译器,只能从以往学过的知识猜:

前提,这个语句里有三个表达式,分别是 i++ (exp1), ++i (exp3), exp+exp3 = exp2

1. 记得以前if语句有多个条件的时候,开启优化开关,一旦第一个条件成立,后面的条件就有可能不评估了,这说明编译器对表达式是从左往右分析的。

2. exp1 = i++要在当前整个语句执行完毕以后才执行。如果这句语句有多个函数或者内含多个表达式,就应该等待这些表达式全部计算完毕,才执行++操作。

3. 这一行里表达式 i++ (exp1),,和 ++i (exp3),使用的是同一个i,因此如果在整个语句结束之前,其中一个表达式计算的值会影响另一个表达式的值。

综合上面分析:先执行++i (exp3),执行后i=2; 然后执行 b = exp1 + exp3 = i + i = 2 + 2 = 4; 最后执行exp1 = i++ = 2+1 = 3

结果:MingW和VC2010的结果都是4,3,被我都蒙对了。记住两点:表达式从左往右执行,多个表达式共用一个变量相互影响(而不是各个表达式被分割以后,进行封闭式计算。内存里始终只有一个i,而编译器也不应该自作主张加上锁,或者做多份内存拷贝,如果刻意想要的效果,应该是由程序员来做这个工作,编译器不应该越俎代庖)

时间: 2024-08-15 02:17:35

没亲手做过编译器就是被人欺,从一道变态的i++题猜编译器的行为(表达式从左往右扫描,同一变量相互影响)的相关文章

没做过编译器就是被人欺,从一道变态的i++题猜编译器的行为(表达式从左往右扫描,同一变量相互影响)

首先不要被人蒙了,如果是这样,根本编译不过: int i=1; int b=i+++++i; printf("%d %d\n", b ,i); Mingw报错:error: lvalue required as increment operand (好像是说,++缺左值,这里的++是上题的第三第四个加号) VC2010报错:error C2105: '++' needs l-value --------------------------------------------------

学好技术,做一个不浮躁的人,请记住以下几点

浮躁的人容易问:我到底该学什么----别问,学就对了: 浮躁的人容易问:Java有钱途吗:----建议你去抢银行: 浮躁的人容易说:我要中文版!我英文不行!----不行?学呀! 浮躁的人分两种:只观望而不学的人:只学而不坚持的人: 浮躁的人永远不是一个高手 1.不要看到别人的回复第一句话就说:给个代码吧!你应该想想为什么.当你自己想出来再参考别人的提示,你就知道自己和别人思路的差异. 2.初学者请不要看太多太多的书那会误人子弟的,先找本系统的学,很多人用了很久都是只对部分功能熟悉而已,不系统还是

产品专家Marty Cagan:不做只会编码的人

Marty Cagan是享有世界声誉的产品管理专家,曾担任Netscape副总裁.eBay产品管理及设计高级副总裁.近日,记者在"PM-China首届产品经理高峰论坛"上对他做了专访,请他分享自己的产品管理历程. 程序员的工作 <程序员>:据我所知,您先后毕业于加州大学和斯坦福大学.这两段经历有何不同? Marty Cagan:像这个行业的大多数人一样,我在加州大学修了计算机科学专业:后来我又去斯坦福大学修了一个类似于MBA的专业,那个专业的学费相当昂贵,学习的是商务方面的

C++编译器最烦人的分析机制

 下面这行代码声明了一个带double参数并返回int的函数: int f(double d); 下面这行做了同样的事情,参数d两边的括号是多余的,会被忽略: int f(double (d)); 下面这行声明了同样的函数,只是它省略了参数名称: int f(double); 这三种形式除了第二种,我们应该都很熟悉. 下面我们在看三个函数声明.第一个声明了一个函数g,它的参数是一个指向不带任何参数的函数的指针,该函数返回double值: int g(double (*pf)()); 有另外一

做一个内心安静的人,不骄不躁,且行且乐

做一个内心安静的人,不骄不躁,且行且乐 安静是一种天然的存在,年龄长久的提炼和沉寂,让内心更为充盈,是生命摆脱浮躁而逐渐趋于安静. 安静是从最深的绝望处寻找到的最美丽的惊喜,这是一种成熟人生的境界,一种充满乐趣的安静,怎么品味都有情趣. 一个人,若想在不同的人生阶段有所得,有所悟,有所成就,绝对离不开一个静字. 静,不是让你脱离现实,而是要在现实中有一种淡定的姿态,去看清自己的本质,只有看请自己的本质,才能清楚的提升自己. 浅薄的热闹,丰富的安静,后者会更让人倾心.静者不避闹市,躁者难立深山,充

产品专家Marty Cagan:不做仅仅会编码的人

Marty Cagan是享有世界声誉的产品管理专家,曾担任Netscape副总裁.eBay产品管理及设计高级副总裁. 近日,记者在"PM-China首届产品经理高峰论坛"上对他做了专訪,请他分享自己的产品管理历程. 程序猿的工作 <程序猿>:据我所知.您先后毕业于加州大学和斯坦福大学. 这两段经历有何不同? Marty Cagan:像这个行业的大多数人一样.我在加州大学修了计算机科学专业.后来我又去斯坦福大学修了一个类似于MBA的专业,那个专业的学费相当昂贵.学习的是商务方

做一个内心强大的人!

http://mp.weixin.qq.com/s?__biz=MzI3NzA2MTczNg==&mid=2656020409&idx=2&sn=848ed46f8e4d09122372d393f5bc40cc&scene=1&srcid=0828tz74LWf7sF2Nfm5zmySh#rd 做一个内心强大的人! 2016-08-28 陶礼到家 导读 真正内心强大的人,一定有一颗平静的内心,有一颗温柔的心肠,有一颗智慧的头脑.一定经历过狂风暴雨,体验过高山低谷,也

你那么喜欢看“干货”,是因为你根本没想做什么努力

前几天朋友问我,能不能分享一下我自己写作方面的干货或者经验.我特别害怕这样的问题,因为我并不是一个喜欢总结方法论的人.我只能跟你说,要不断的写,写作特别辛苦也需要特别勤奋,很多常人看不见的努力你必须下得到.但这样的说法通常不会让人满意,总觉得我在保留自己的迷茫,害怕别人超过自己而回答的模棱两口. 但事实上来讲,我周围的写作者是什么样的呢? 白天上班,晚上写作到半夜是常有的事儿;在外面用手机写,在机场等飞机也在写,不断的看书,疯狂的阅读.他们没多少人去关注什么干货或者技巧,就是疯狂的写而已.我的朋

做一个思维严谨的人

近期.在网易公开课上找了个哲学入门的课看了看,听懂多少不是重点,记住多少不是重点. 那么,重点是什么呢?学习一种思考问题的方式,更清楚的认识自己,技术的学习要远远易于认识自己. 以下我将给大家分享两个比較有意思的论证:灵魂的永恒和死亡是否对你有害这两个论证. 灵魂是否是永恒的呢? 先来看下苏格拉底的论证: 1.仅仅有合成的东西才会毁灭 2.仅仅有能改变的东西才是合成的 3.无形的东西不会改变 所以.4.无形的东西不能毁灭 而.5.灵魂是无形的 所以,6.灵魂是永恒的. 当初我听到有人证明了1+1