自加与自减运算

lz2163070 2008-02-14 01:46:57
算一下运行结果:
main()
{ int a,b;
a=3; b=(a++,a++,a++); printf("\n%d,%d",a,b);
a=3; b=(++a,++a,++a); printf("\n%d,%d",a,b);
a=3; b=(a++)+(a++)+(a++); printf("\n%d,%d",a,b);
a=3; b=(++a)+(++a)+(++a); printf("\n%d,%d",a,b);
}
请解释~~~主要是解释后3个!
...全文
235 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
zfp31415 2010-12-28
  • 打赏
  • 举报
回复
怎么这么复杂呢?居然会有这么多答案,哎!
白乔 2008-02-20
  • 打赏
  • 举报
回复
孔乙己现在还这么吃香?
wolfdog1111 2008-02-20
  • 打赏
  • 举报
回复
编译器不同结果就有可能不同,debug跟进看下好了。
myullian 2008-02-20
  • 打赏
  • 举报
回复
跟编译器有关吧
薄皮西瓜 2008-02-20
  • 打赏
  • 举报
回复

这个问题我觉得挺有意思的,C标准中未定义情况太多了,每种编译器对这种情况都有自己的方式。

相信大家都做过计算器的程序,对于一个表达式而言(b=(++a)+(++a)+(++a);),
会先将a,a,a以及(,++,)+,(,++,),+,(,++,),+分别保存在两个栈内(当初做的时候是用数组仿真的),
然后根据运算符的优先级进行计算。

这里想说的是对于表达式(++a)+(++a)+(++a)的值显然有15、16、18三种,
值为15的时候,先计算第一个(++a)= 4, 然后计算第二个(++a)= 5,然后计算第三个(++a)= 6
值为16的时候,先计算第一个(++a)即对a的值加1,然后计算第二个(++a)对a的值加1,然后计算a + a得出10,最后计算10+(++a)
值为18……

由此可以看出不同的编译器似乎对于表达式的计算上有不同的逻辑顺序。

类似这种未定义的情况有:
if ( 15 == fun())
b = fun1(fun2(),fun3())

对于这种情况QAC和PClint这两种代码检查工具都会进行提示的。
lee08 2008-02-20
  • 打赏
  • 举报
回复
这个我们老师曾经说过跟printf有关,printf里有两个参数,先输出后一个再输出前一个,所以第一个答案应该是6,5,后面的我就算不对了,答案真是丰富啊!
mukai520 2008-02-20
  • 打赏
  • 举报
回复
b=(a++,a++,a++); 这叫什么结构??? 我尝试了一下,貌似是只取最后一个值。
++a先增 a++后增
a=3; b=(a++,a++,a++); a先逐次加到6,然后去最后值 6
a=3; b=(a++)+(a++)+(a++); 3个a相加,然后逐次加到6
a=3; b=(++a)+(++a)+(++a); a先逐次加到6然后执行两个加号获得B的值
mukai520 2008-02-20
  • 打赏
  • 举报
回复
b=(a++,a++,a++); 。。。。“a”哪里惹你了??!!

呵呵,开始学C的恶心题,其实在你做程序员的前两年里这个屁用没有。
这个对,拿去给老师吧。
WIN-TC
6,5
6,6
6,9
6,18
bkill 2008-02-19
  • 打赏
  • 举报
回复
关于自加自减,ANSI的标准给各个系统留出了余地,它不是定义好的完美标准,所以依据每个系统的不同而定.
DarknessTM 2008-02-19
  • 打赏
  • 举报
回复
某些转牛角尖的家伙出的怪题罢了
疯石头 2008-02-18
  • 打赏
  • 举报
回复
a++与++a都是自加一 前者是运算后加 后者是运算前加 如a=3;b=a++;c=++a 最后结果b是3c是4
dragonfly2008 2008-02-14
  • 打赏
  • 举报
回复
同意楼上
看不懂的东西是不可取的
nobush 2008-02-14
  • 打赏
  • 举报
回复
C标准规定++a先加一后取值,a++先取值后加一。在表达式中嵌入这种自增表达式时何时加一标准没有规定,对于标注没有规定的行为编译器可以作出自己的解释,所以不同的编译器会有不同的结果。


所以 你可以用這樣的代碼:
b=(a++,a++,a++);
b=(++a,++a,++a);

而這樣的代碼是無意義的
b=(a++)+(a++)+(a++);
b=(++a)+(++a)+(++a);


參見 http://www.research.att.com/~bs/bs_faq2.html#evaluation-order
vb00001 2008-02-14
  • 打赏
  • 举报
回复
编译器不同,结果也会不同,下面针对C编译器。
b=(++a,++a,++a);

正编译再反编汇之后:

mov dword ptr [a],3 ;a=3
mov eax,dword ptr [a] ;eax=3
add eax,1 ;eax++
mov dword ptr [a],eax ;a=eax
mov ecx,dword ptr [a] ;ecx=a
add ecx,1 ;ecx++
mov dword ptr [a],ecx ;a=ecx
mov edx,dword ptr [a] ;edx=a
add edx,1 ;edx++
mov dword ptr [a],edx ;a=edx
mov eax,dword ptr [a] ;eax=a
mov dword ptr [b],eax ;b=eax

可以化成:

int a, b;
a++;
a++;
a++;
b = a;


其它的两个由大家来完成了。
michney 2008-02-14
  • 打赏
  • 举报
回复
这种代码写出来,有意义吗?
pujihong123 2008-02-14
  • 打赏
  • 举报
回复
#include<stdio.h>
int main(void)
{ int a,b;
a=3; b=(a++,a++,a++); printf("\n%d,%d",a,b);
a=3; b=(++a,++a,++a); printf("\n%d,%d",a,b);
a=3; b=(a++)+(a++)+(a++); printf("\n%d,%d",a,b);
a=3; b=(++a)+(++a)+(++a); printf("\n%d,%d",a,b);
}

在LCC-win32上的调试结果为:6,5
6,6
6,12
6,15
至于为什么是这个结果正在琢磨.
a013231 2008-02-14
  • 打赏
  • 举报
回复
那本书上有这种题,那本书可以扔掉了.
编译器相关,无固定结果.
arong1234 2008-02-14
  • 打赏
  • 举报
回复
狠正常(a++)+(a++)的值是不确定的,依赖编译器,所以你唯一能做的就是避免写出这种代码
C_Cly 2008-02-14
  • 打赏
  • 举报
回复
是个挺有趣的问题 我在WIN-TC和VC 6.0上编译了一下 结果如下
WIN-TC VC 6.0
6,5 6,5
6,6 6,6
6,9 6,9
6,18 6,16
我无法解释这个结果 希望高手解答一下
还有个疑问希望得到解答 就是为什么第一个不是6,6呢?
既然有逗号运算符 为什么不是将3个a++算完后 再取最后一个值呢?
msgsnd 2008-02-14
  • 打赏
  • 举报
回复
VC运行一下
否则要debug干啥
加载更多回复(4)

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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