当前位置:编程学习 > C/C++ >>

这个C语言程序看不懂啊

main() {int i=5,j=5,p,q; p=(i++)+(i++)+(i++); q=(++j)+(++j)+(++j); printf("%d,%d,%d,%d\n",p,q,i,j); } 运行后是15,22,8,8 我自己算的是15,24,8,8 q值我算出来是24,怎么也得不出22,但Dev c++不会出错吧
追问:我自己编译了下,发现j在三次自增后的值分别是 6 7 8  但是 q确是 6 14 22
---------
怎么看q值每一步的变化呀
答案:这个题目涉及一个“序列点”的问题。
p=(i++)+(i++)+(i++);
对于表达式中的三个(i++),我们分别用编号表示:
e1 = i++;
e2 = i++;
e3 = i++;
于是 p = e1 + e2 + e3;,C只规定在=起作用时,右边的表达式必须求值结束,即e1+e2+e3的结果必须算出来。
根据加法运算法则,我们知道会先算e4 = e1 + e2,再算p  = e4 + e3。
但是e1,e2,e3这三个表达式各自的求值顺序并没有确切的规定,也就是这三个表达式各自的计算顺序是不确定的,依赖于编译器的实现。
考虑到e1=i++实际上等价于下面两个表达式
e11 = i;
i = i + 1;
整个p = e1 + e2 + e3;等价于
1. e1' = i;
2. i = i + 1;
3. e2' = i;
4. i = i + 1;
5. e3' = i;
6. i = i + 1;
7. p = e1' + e2' + e3';
对于上面7个式子,只能确定(7)是最后执行,(1)在(2)前执行,(3)在(4)前执行,(5)在(6)前执行。
但是(1)、(3)、(5)和(2)、(4)、(6)之间执行的顺序是不确定的。
可能是(1)(3)(5)(2)(4)(6),这种情况下p = 15。
也可能是(1)(2)(3)(4)(5)(6),这种情况下p等于17。
因此对于p=(i++)+(i++)+(i++);实际上是语法正确,但属于语义不确定的情况。
不同的编译器计算结果可能不一样,同样的编译器在不同的编译模式下(DEBUG或RELEASE)也可能不一样。
对于q=(++j)+(++j)+(++j);,分析过程也是一样的。
等价于:
(1) j = j + 1;
(2) e1 = j;
(3) j = j + 1;
(4) e2 = j;
(5) j = j + 1;
(6) e3 = j
(7) p = e1 + e2 + e3
同样(7)最后执行,(1)先于(2),(3)先于(4),(5)先于(6),其他不确定。
当按(1)(3)(5)(2)(4)(6)(7)执行时就是24。
当按(1)(2)(3)(5)(4)(6)(7)执行时就是22。
具体的执行顺序依赖于编译器。
因此上面的两个表达式实际都是不确定的,自己写代码的时候最好不要有这种写法。
关于“序列点”更多的内容,你可以在MSDN里面搜一下“sequence point”。
其他:这个问题,我也遇见过~好纠结的
q=(++j)+(++j)+(++j) 好像 挺复杂,它在不同的编译器下值是不同的 我自己编译了下,发现j在三次自增后的值分别是 6 7 8  但是 q确是 6 14 22 

不明白为何他加了两次8    . 我算的也是24,在vs2008中编译输出的为15,24,8, 8,但是gcc编译输出的是15, 22, 8, 8 纠缠这样的题目真的没有什么意义,编译器不同结果页不一样。现在的面试基本上都不会考这样的题目了,毫无技术含量和基础知识可言。 

上一个:陕西省计算机二级C语言成绩咋查,啥时公布?在哪能查到,急呀你!!!!!!
下一个:如何使用c在文件内查找一个字符串?

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,