C语言表达式(++i)+(++i)+(++i)结果多少?
答案:6 悬赏:20 手机版
解决时间 2021-04-28 09:28
- 提问者网友:战魂
- 2021-04-27 08:36
C语言表达式(++i)+(++i)+(++i)结果多少?
最佳答案
- 五星知识达人网友:荒野風
- 2021-04-27 09:29
呵呵,有意思.
在VC中应该这样理解:
做类似(++n)运算是直接在内存中完成的,相当于是用汇编里的自加运算,直接修改内存中n的值. 因此,做第一次(++i)后,i=4,做第二个(++i)后,i=5;此时才做第一次括号外的加法,并把结果保存在临时变量中temp=10;而此时内存中的i已经是5了. 然后在做一次(++i),即i=6;
此时i与临时变量temp相加,就是最终结果k=16.
不信,你可再加一个(++i),此时,i=7;结果k为23.
所以,这样完全可以推出它的运算机制.
在VC中应该这样理解:
做类似(++n)运算是直接在内存中完成的,相当于是用汇编里的自加运算,直接修改内存中n的值. 因此,做第一次(++i)后,i=4,做第二个(++i)后,i=5;此时才做第一次括号外的加法,并把结果保存在临时变量中temp=10;而此时内存中的i已经是5了. 然后在做一次(++i),即i=6;
此时i与临时变量temp相加,就是最终结果k=16.
不信,你可再加一个(++i),此时,i=7;结果k为23.
所以,这样完全可以推出它的运算机制.
全部回答
- 1楼网友:酒安江南
- 2021-04-27 14:46
答案为18吧?如果是18。我有个解释是:
有两点大家一定要弄明白:
一、(++i) 的编译(计算)过程是,取出变量 i 所代表的内存单元里存的值,把这个值加上 1 ,然后又放回去。具体编译过程是怎样的暂时不用管它。
二、k = a + b 的编译(计算)过程是,取出变量 a 所代表的内存单元里存的值和变量 b 所代表的内存单元里的值,两个值相加,把结果传送给 k 【或者是说把结果放到 k 所代表的内存单元里去】
这里(假设i=3)
编译器在看到 k = (++i) 时,过程是先把 i 完成自加,此时i的值就是4,【或者说,i 所代表的内存单元里存的值是 4】。
表达式此时虽然变成了 k = (i) 了,但实际上并不是准备要把 4 传送给 k ,而是 k = (*&i) ;意思是取 i 所代表的内存单元的值放到 k 所代表的内存单元里去。
【重点就是在这里,编译器只是准备把变量i所代表的内存空间里存的值传送给表达式左边而不是传送 数字4 ,这个涉及到数据存取问题,这里理解了就好说了】
此时编译器看到表达式右边已经没有继续计算的步骤了,它就可以完成 k = (*&i) 这一步了。此时 i 所在内存单元里存的值正好是 4 ,所以传送给 k 的值也就是 4 了。这是最简单的情况。
下面,换成 k = (++i)+(++i)
编译器看到 k = (++i)+(++i) 时,第一步:算左边的 ++i,【i 所代表的内存单元里的值就变成了 4】,然后表达式就成了 k = (i) + (++i) 【实际上是 k = (*&i) + (++i)】;
第二步:编译器看到后面还有一个加号,它就只好继续往下走,在看到加号这样的2目运算符时 ,它就必须马上找到 加号 另一边的表达式 并求出其值。此时编译器在加号右边又看到了(++i),他就只好再算一次(++i),所以,取出 i 的值是第一步中算完的 i 的值【4】,把这个值加 1 ,结果就是把【5】放回了 i 所代表的内存单元里去了。【注意, 此时 i 所代表的内存单元里的值就是 5】,此时表达式变成了 k = (i) + (i) 。【实际是 k = (*&i)+(*&i)】
第三步:编译器看到加号两边的表达式都算完了,就可以完成加的操作了,所以开始计算 (i)+(i) 【实际是 (*&i) + (*&i)】,由于 i 的值现在是 5 ,所以就是 5 + 5 ,而不是 4 + 5 。整个结果是 10 。
最后:编译器看到右边再没有需要计算的了,就完成最后的操作: 传送 (等号)右边的值 给(等号)左边。所以最好 k = 10 。 k 的值是【10】
所以分析 k = (++i)+(++i)+(++i) ,最后就是 k = (*&i)+(*&i)+(*&i) ;而大家也知道 最后的 i 值是经过三次自加的结果【6】,这样一来,K 最后的值就是 k = 6 + 6 + 6 了。结果是 【18】。
这就是我的分析,楼主说结果是 16 .我也就不知道是怎么回事了。
有两点大家一定要弄明白:
一、(++i) 的编译(计算)过程是,取出变量 i 所代表的内存单元里存的值,把这个值加上 1 ,然后又放回去。具体编译过程是怎样的暂时不用管它。
二、k = a + b 的编译(计算)过程是,取出变量 a 所代表的内存单元里存的值和变量 b 所代表的内存单元里的值,两个值相加,把结果传送给 k 【或者是说把结果放到 k 所代表的内存单元里去】
这里(假设i=3)
编译器在看到 k = (++i) 时,过程是先把 i 完成自加,此时i的值就是4,【或者说,i 所代表的内存单元里存的值是 4】。
表达式此时虽然变成了 k = (i) 了,但实际上并不是准备要把 4 传送给 k ,而是 k = (*&i) ;意思是取 i 所代表的内存单元的值放到 k 所代表的内存单元里去。
【重点就是在这里,编译器只是准备把变量i所代表的内存空间里存的值传送给表达式左边而不是传送 数字4 ,这个涉及到数据存取问题,这里理解了就好说了】
此时编译器看到表达式右边已经没有继续计算的步骤了,它就可以完成 k = (*&i) 这一步了。此时 i 所在内存单元里存的值正好是 4 ,所以传送给 k 的值也就是 4 了。这是最简单的情况。
下面,换成 k = (++i)+(++i)
编译器看到 k = (++i)+(++i) 时,第一步:算左边的 ++i,【i 所代表的内存单元里的值就变成了 4】,然后表达式就成了 k = (i) + (++i) 【实际上是 k = (*&i) + (++i)】;
第二步:编译器看到后面还有一个加号,它就只好继续往下走,在看到加号这样的2目运算符时 ,它就必须马上找到 加号 另一边的表达式 并求出其值。此时编译器在加号右边又看到了(++i),他就只好再算一次(++i),所以,取出 i 的值是第一步中算完的 i 的值【4】,把这个值加 1 ,结果就是把【5】放回了 i 所代表的内存单元里去了。【注意, 此时 i 所代表的内存单元里的值就是 5】,此时表达式变成了 k = (i) + (i) 。【实际是 k = (*&i)+(*&i)】
第三步:编译器看到加号两边的表达式都算完了,就可以完成加的操作了,所以开始计算 (i)+(i) 【实际是 (*&i) + (*&i)】,由于 i 的值现在是 5 ,所以就是 5 + 5 ,而不是 4 + 5 。整个结果是 10 。
最后:编译器看到右边再没有需要计算的了,就完成最后的操作: 传送 (等号)右边的值 给(等号)左边。所以最好 k = 10 。 k 的值是【10】
所以分析 k = (++i)+(++i)+(++i) ,最后就是 k = (*&i)+(*&i)+(*&i) ;而大家也知道 最后的 i 值是经过三次自加的结果【6】,这样一来,K 最后的值就是 k = 6 + 6 + 6 了。结果是 【18】。
这就是我的分析,楼主说结果是 16 .我也就不知道是怎么回事了。
- 2楼网友:未来江山和你
- 2021-04-27 13:19
C语言里:
++这个运算符是右结合的运算
你这道题目中++在变量左边就要先运算++
所以++i是4 之后又有++i所以是5 然后又是++i所以是6
最后是k=6+6+6 得到18
但是环境不同就不一样 在C#中这道题是15 完成表达式的顺序不一样
所以这类问题真是...
++这个运算符是右结合的运算
你这道题目中++在变量左边就要先运算++
所以++i是4 之后又有++i所以是5 然后又是++i所以是6
最后是k=6+6+6 得到18
但是环境不同就不一样 在C#中这道题是15 完成表达式的顺序不一样
所以这类问题真是...
- 3楼网友:往事埋风中
- 2021-04-27 11:57
先加再赋值 加法运算是由左向右
++i也就是4 然后赋值给中间的 然后++i也就是5
而i在第二轮运算后已经等于5了 然后将i值赋给前后
1次运算只能赋值1次 所以中间的i蒋5赋给前后2个
后面i++ 最后是5+5+6
++i也就是4 然后赋值给中间的 然后++i也就是5
而i在第二轮运算后已经等于5了 然后将i值赋给前后
1次运算只能赋值1次 所以中间的i蒋5赋给前后2个
后面i++ 最后是5+5+6
- 4楼网友:忘川信使
- 2021-04-27 11:15
在VC中,执行顺序如下
(++i) ;//(++i) = 4,i=4
(++i) ;//(++i) = 5,i=5
+ ;i + i = 10,此时加号两边都是5
(++i) ;//(++i) = 6,i=6
+ ;10 + 6 = 16
(++i) ;//(++i) = 4,i=4
(++i) ;//(++i) = 5,i=5
+ ;i + i = 10,此时加号两边都是5
(++i) ;//(++i) = 6,i=6
+ ;10 + 6 = 16
- 5楼网友:末日狂欢
- 2021-04-27 11:04
不同的编译器组合方法不同,tc2.0下为18;
i=i+1; 为4
i=i+1; 为5
i=i+1; 为6
k=i+i+i 为6+6+6=18
VC 下的确为16。
鄙视教材中一而再,再而三的出现这样的垃圾问题。
不提倡这种写法。不同的环境中结果不一样。可移植性差,依赖编译器的组合方法。
C语言里面明确指出:在两个顺序点之间两次改变同一个变量的任何尝试得到的结果都是不确定的!
如这里
int i=10;
printf("%d,%d,%d\n",++i,--i,-i++);
的两个顺序点分别是int i=10;的分号,和包围printf的参数的括号,C语言只保证位于两个顺序点之间的表达式求值产生副作用在第二个顺序点之前生成,但不保证两个顺序点之间所有表达式的求值顺序。你这里++i,--i,-i++三个表达式企图在两个顺序点前一个分号和()之间三次改变同一个变量i的值,所以结果注定是不确定的。至于为什么C语言要规定相邻顺序点之间的表达式以任意顺序求值,是为了给编译器更多的自由空间,让底层运算操作能由编译器调度安排从而使运算更有效地执行。
i=i+1; 为4
i=i+1; 为5
i=i+1; 为6
k=i+i+i 为6+6+6=18
VC 下的确为16。
鄙视教材中一而再,再而三的出现这样的垃圾问题。
不提倡这种写法。不同的环境中结果不一样。可移植性差,依赖编译器的组合方法。
C语言里面明确指出:在两个顺序点之间两次改变同一个变量的任何尝试得到的结果都是不确定的!
如这里
int i=10;
printf("%d,%d,%d\n",++i,--i,-i++);
的两个顺序点分别是int i=10;的分号,和包围printf的参数的括号,C语言只保证位于两个顺序点之间的表达式求值产生副作用在第二个顺序点之前生成,但不保证两个顺序点之间所有表达式的求值顺序。你这里++i,--i,-i++三个表达式企图在两个顺序点前一个分号和()之间三次改变同一个变量i的值,所以结果注定是不确定的。至于为什么C语言要规定相邻顺序点之间的表达式以任意顺序求值,是为了给编译器更多的自由空间,让底层运算操作能由编译器调度安排从而使运算更有效地执行。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯