作者rainphiz ( )
看板TransCSI
标题Re: [问题] i值结果
时间Wed Apr 1 08:36:53 2009
※ 引述《RJking (RJ-king)》之铭言:
: ※ 引述《walks (蹦蹦跳跳)》之铭言:
: : 1.: i = 1 ;
: : 2.: ++i+=i++;
: 老实说这个答案好像不同compiler会不一样,因为对语句解释的不同
: 大概讲一下RJ牌人脑compiler的答案跟流程
: 1.: i = 1 ; //将i指定为1
: 2.: ++i+=i++ ; //先做++i(i变成2),然後做i+=i(i指定成i+i,i变成4)
: //然後做i++(i变成5)
: 所以i的值最後是5
: 还有就是VS2005跟VS2008跟DEV C++会直接跟你说"++i+=i++"这行语法错误
: 如果题目直接注明一定有答案或是你怕老师认为一定会有答案,你可以考虑用我的答案
: 我对第二行的解释只是单纯基於运算子优先顺序而已...
在 C 中这是违法的,而在 C++ 中这是合法的。
所以以上运算式用 g++ 是可以 compile 过的,而 gcc 不行。
简单来说,
在 C++ 中, ++i 会将 i 值递增後,回传 i 这个 [变数]
而在 C, ++i 在 i 递增後回传的是 i 这个变数的 [值]
而无论在 C/C++
i++ 回传的都是都是 i 的 [值]。
但放在等号左边的必须为一 lvalue,也就是可被解析出该物件的位址
因此,i 这个 [变数] 可以当作 lvalue,因为 i 是一个有位址的物件
但 i 的 [值] 却不行,因为它并非是一个物件
因此,在 C++ 中,
++i = i++; 会过
i++ = i++; 不会过
在 C 中,
上面两式均不会通过编译。
我们也可经由上面知道,
*(&i) = 0; 这样的指定式在 C/C++ 中均不会通过编译,
因为 *(&i) 回传的是 i 的 [值] 而不是 i 这个 [变数物件]。
: 这可以算是Undefined behavior吧...
: http://en.wikipedia.org/wiki/Undefined_behavior
是的,因为 i 的值在 sequence points 中被更改了两次,
不过我想老师应该只是要考运算子优先序的观念,答案应该就是 5 吧。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.133.2.239
1F:→ RJking:我DEV C++是用g++ compile的...VS2005跟VS2008也是以C++来 04/01 11:39
2F:→ RJking:跑的...阿就不会过... 04/01 11:40
3F:推 avogau:会不会是你其他地方写错了 04/01 12:30
4F:→ avogau:我用 code::blocks 可以过 04/01 12:30
5F:→ avogau:code::blocks是用g++3.4.5 04/01 12:31
6F:→ avogau:还是你的副档名是用 .c 04/01 12:31
7F:推 zptdaniel:这题不是undefined behavior吗? 04/01 13:17
8F:→ zptdaniel:答题不就直接说未定义行为,不同的编辑器会有不同的答案? 04/01 13:17
9F:→ zptdaniel:C_and_CPP里面讨论过很多次的样子,可以去翻翻看文章. 04/01 13:18
10F:→ zptdaniel:不过确实*.c会不能执行。*.cpp可以执行且值为5. 04/01 13:23
11F:→ zptdaniel:所以还是看题目是哪种语言吧@@ 04/01 13:23
12F:→ RJking:副档名当然是.cpp DEV C++跟VS2005、VS2008预设都存.cpp 04/01 19:43
13F:推 RJking:OK看来是没有写进function的错...VS2005、VS2008、DEV C++ 04/01 19:58
14F:→ RJking:跟code::blocks都跑出5,证明RJ牌人脑compiler是对的XD 04/01 19:59