关于自增自减的一个问题求指教

水手怕水 2013-10-14 03:35:07

为什么这里P的值是24?我自己的理解是b最后的值是8,所以就是8+8+8=24;继续:

在VC6.0中这里的值又是22了,我的理解是可能编译环不同,这里计算方式为6+7+8=21;问题是这里居然是22,
我在书上看到这里p是自增了1,我又把这个问题理解为++(6+7+8);这样理解到底对不对?
还有一个问题,


这里最后一行不应该是输出8,9吗?怎么反了?
请大神指点;
以为自己看了几本书C语言算是知道一点点语法了,没想到在上课的时候老师讲到这里才发现自己对自增自减都不清楚,真是惭愧啊!
...全文
273 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
水手怕水 2013-11-23
  • 打赏
  • 举报
回复
引用 6 楼 z1179675084 的回复:
我给你好好说说关于第一个q = 15,这基本是没有问题的,所有编译器结果都应该相同,但是为什么是这么个结果呢?在C语言里面存在顺序点!至于什么是顺序点你百度一下,我就不浪费时间了,在这个语句中顺序点是”;“但赋值发生在顺序点之前,其副作用已经产生,所以结果是5 + 5 + 5,你可以写个程序验证

int a = 5;
a = (a++) + (a++) + (a++);
printf("%d",a);
这个结果是18,为什么?同上5+5+5 = 15;之后遇到”;“遇到顺序点时所有的赋值都会反馈回去,所以这里15要加3次,结果是18. 再看你的p = 24还是22,这个结果还真是不确定的,C里面没有给出其计算顺序,看做编译器的人了。 22 = 7 + 7 + 8; 24 = 8 + 8 + 8; 不要问我为什么这么算,问问做编译器的人吧。我个人觉得不要纠缠这东西,没有任何意义,只有大学老师才拿些这玩意来显示他很有水平,其实他自己都不一定真的懂! 最后一个,为什么顺序是反的,其实从你自己的结果来看就很明白了,其实不光是你这里的printf函数是反的,其他函数也是的,瞧瞧下面这个!

#include <stdio.h>
void print(int i,int j)
{
	printf("%d\n",i);
	printf("%d\n",j);
}
int main()
{

	int a = 5;
	print(a++,a++);
	return 0;
}
这里也是和顺序点相关的,但是这里需要注意一下,楼上很多都说printf结果和编译器有关,确实有关系(函数参数的求职顺序依赖于编译器的实现),但是你的那个结果和我的这个例子它是由顺序点决定的,不管编译器是哪种,结果都一样,希望别搞混了。 写了这么多了,我就再多费几句话说说什么是顺序点吧! 顺序点是指在执行过程中修改变量值的最晚时刻,在程序到达顺序点的时候,之前所做的一切操作必须反映到后续的访问中。顺序点存在于: 每个完整表达式结束时; && || ?: 以及逗号表达式的每个云端对象之后 函数调用中对所有实际参数的求值完成之后(进入函数体之前)。
不好意思,现在才看到,虽然看的云里雾里,不过写了这么多,感谢!!
max_min_ 2013-10-15
  • 打赏
  • 举报
回复
总结:就是尽量不要写这样的代码,太水,误导了自己,后期也比较难维护! 如果实在要写,就分多个语句来完成!
lin5161678 2013-10-15
  • 打赏
  • 举报
回复
引用 6 楼 z1179675084 的回复:
我给你好好说说关于第一个q = 15,这基本是没有问题的,所有编译器结果都应该相同,
既然能说错序列点 既然知道副作用 怎么还会有 所有编译器结果都是 15 这种奇怪的想法 别说能举出反例 http://ideone.com/jkGwfP 就在找不到反例 能确定是未定义行为就别指望结果有意义
赵4老师 2013-10-15
  • 打赏
  • 举报
回复
zhao 2013-10-15
  • 打赏
  • 举报
回复
我给你好好说说关于第一个q = 15,这基本是没有问题的,所有编译器结果都应该相同,但是为什么是这么个结果呢?在C语言里面存在顺序点!至于什么是顺序点你百度一下,我就不浪费时间了,在这个语句中顺序点是”;“但赋值发生在顺序点之前,其副作用已经产生,所以结果是5 + 5 + 5,你可以写个程序验证

int a = 5;
a = (a++) + (a++) + (a++);
printf("%d",a);
这个结果是18,为什么?同上5+5+5 = 15;之后遇到”;“遇到顺序点时所有的赋值都会反馈回去,所以这里15要加3次,结果是18. 再看你的p = 24还是22,这个结果还真是不确定的,C里面没有给出其计算顺序,看做编译器的人了。 22 = 7 + 7 + 8; 24 = 8 + 8 + 8; 不要问我为什么这么算,问问做编译器的人吧。我个人觉得不要纠缠这东西,没有任何意义,只有大学老师才拿些这玩意来显示他很有水平,其实他自己都不一定真的懂! 最后一个,为什么顺序是反的,其实从你自己的结果来看就很明白了,其实不光是你这里的printf函数是反的,其他函数也是的,瞧瞧下面这个!

#include <stdio.h>
void print(int i,int j)
{
	printf("%d\n",i);
	printf("%d\n",j);
}
int main()
{

	int a = 5;
	print(a++,a++);
	return 0;
}
这里也是和顺序点相关的,但是这里需要注意一下,楼上很多都说printf结果和编译器有关,确实有关系(函数参数的求职顺序依赖于编译器的实现),但是你的那个结果和我的这个例子它是由顺序点决定的,不管编译器是哪种,结果都一样,希望别搞混了。 写了这么多了,我就再多费几句话说说什么是顺序点吧! 顺序点是指在执行过程中修改变量值的最晚时刻,在程序到达顺序点的时候,之前所做的一切操作必须反映到后续的访问中。顺序点存在于: 每个完整表达式结束时; && || ?: 以及逗号表达式的每个云端对象之后 函数调用中对所有实际参数的求值完成之后(进入函数体之前)。
  • 打赏
  • 举报
回复
编译环境不同造成的,
lm_whales 2013-10-15
  • 打赏
  • 举报
回复
1)这个是标准,规定的,未定义行为,结果有编译器厂商决定,想咋搞就咋搞。 2)编译器,可以从左向右计算,也可以从右向左计算,也可以从两头向中间计算。 想在那里获得结果,就在那里获得结果,甚至 VC的不同版本,结果都不一样。 有那功夫,你就自己去分析吧。 没工夫就别管他。
lm_whales 2013-10-15
  • 打赏
  • 举报
回复
函数调用也许和顺序点有关。 不过实际上,许多编译器,按照参数的入栈顺序,计算参数的值。 然而 ++,--确实,有很大的不确定性: int a = 5; print(a++,a++); VC6 结束才行动,输出 5,5 VC9 一边输出一边行动,输出6,5 VC10 结束才行动,输出 5,5
buyong 2013-10-15
  • 打赏
  • 举报
回复
不要把有限的生命浪费在这种结果不确定的代码上。
水手怕水 2013-10-14
  • 打赏
  • 举报
回复
看的云里雾里,不过还是谢了~
引用 楼主 a1385341 的回复:
为什么这里P的值是24?我自己的理解是b最后的值是8,所以就是8+8+8=24;继续: 在VC6.0中这里的值又是22了,我的理解是可能编译环不同,这里计算方式为6+7+8=21;问题是这里居然是22, 我在书上看到这里p是自增了1,我又把这个问题理解为++(6+7+8);这样理解到底对不对? 还有一个问题, 这里最后一行不应该是输出8,9吗?怎么反了? 请大神指点; 以为自己看了几本书C语言算是知道一点点语法了,没想到在上课的时候老师讲到这里才发现自己对自增自减都不清楚,真是惭愧啊!
图灵狗 2013-10-14
  • 打赏
  • 举报
回复
参考http://bbs.csdn.net/topics/370153775
引用 楼主 a1385341 的回复:
为什么这里P的值是24?我自己的理解是b最后的值是8,所以就是8+8+8=24;继续: 在VC6.0中这里的值又是22了,我的理解是可能编译环不同,这里计算方式为6+7+8=21;问题是这里居然是22, 我在书上看到这里p是自增了1,我又把这个问题理解为++(6+7+8);这样理解到底对不对? 还有一个问题, 这里最后一行不应该是输出8,9吗?怎么反了? 请大神指点; 以为自己看了几本书C语言算是知道一点点语法了,没想到在上课的时候老师讲到这里才发现自己对自增自减都不清楚,真是惭愧啊!

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧