LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
123
返回列表 发新帖
楼主: sfiloveyou

请教一道编程题?

[复制链接]
发表于 2004-12-3 02:46:04 | 显示全部楼层
最初由 orphen 发表
计算是从左往右计算参数
赋值语句是从右往左[PHP]Shadow root # cat aa.c
main()
{
int a=5,k;
k=(a++)+(++a)+(++a)+(++a);
printf("k=%d,a=%d\n",k,a);
}
Shadow root # ./aa
k=27,a=9
[/PHP]
发表于 2004-12-3 03:39:00 | 显示全部楼层
现在想来,这样的问题最好回避,确实是不同的编译器处理方式不同。
比如象:
a=5;
k=(a--)+(++a)*(++a)+(a++);
printf("%d%d",a,k);
这类问题,我在TC2上的实验结果非常简单,跟我帖的那片文章的描述不符。其实就是编译器先扫描一行句子,确定i,然后统一用这个 i 计算表达式。而在GCC上好像就是文章说的那样。

而如果把 (a--)+(++a)*(++a)+(a++)放到printf()里,TC则是边扫描边分别取不同的i相加。在GCC里可能又不一样了。这样的问题还是尽量避免的好,考试的话死记住各编译器的规则就行了,确实不是很有价值,都由编译器控制的。
发表于 2004-12-4 03:56:00 | 显示全部楼层
在BC3.1下:
k=(a++)+(++a)+(a++); 则 k=6+6+6=18, a=8;
k=(a++)+(++a)+(++a); 则 k=7+7+7=21, a=8;
k=(++a)+(a++)+(++a); 则 k=7+7+7=21, a=8;
k=(++a)+(++a)+(a++); 则 k=7+7+7=21, a=8;
k=(++a)+(++a)+(++a); 则 k=8+8+8=24, a=8;
而在gcc下:
k=(a++)+(++a)+(a++); 则 k=6+6+6=18, a=8;
k=(a++)+(++a)+(++a); 则 k=5+7+7=19, a=8;
k=(++a)+(a++)+(++a); 则 k=7+5+7=19, a=8;
k=(++a)+(++a)+(a++); 则 k=7+7+7=21, a=8;
k=(++a)+(++a)+(++a); 则 k=7+7+8=22, a=8;

比较这些结果可以看出,对于同时有多个+操
作符的表达式,BC3.1及类似的编译器是先求
出所有的操作数,然后才对+操作符进行求值;
  而gcc等编译器则是服从先左后右的原则,即
从左往右,先计算第一个操作符,然后在计算
第二个操作符,以此类推。
  PS:此类问题拿来探讨一下,以更深认识C,
无可厚非,但是实际上编程序时应该避免这种
情况出现,因为这是带有歧义性的,不同的编
译器会有不同的处理办法,而却不能说谁对谁
错,C并没有规定按那种顺序计算。
发表于 2004-12-4 14:02:13 | 显示全部楼层
楼上的自相矛盾了吧
如楼上对gcc的结论所说k=(a++)+(++a)+(a++);是 k=5+6+6=17而不是k=6+6+6=18,a=8;还有k=(a++)+(a++)+(a++);又如何解释呢?
我在gcc下看反汇编代码的结果(汇编代码很长就不放上了)
k=a+b+c在gcc下实际是k=a+b;k+=c;
k=(a++)+(++a)+(a++); 则 a+=1;k=a+a;k+=a;a+=1;a+=1; //k=(6+6)+6
k=(a++)+(++a)+(++a); 则 a+=1;k=a+a;a+=1;k+=a;a+=1; //k=(6+6)+7
k=(++a)+(a++)+(++a); 则 a+=1;k=a+a;a+=1;k+=a;a+=1; //k=(6+6)+7
k=(++a)+(++a)+(a++); 则 a+=1;a+=1;k=a+a;k+=a;a+=1; //k=(7+7)+7
k=(++a)+(++a)+(++a); 则 a+=1;a+=1;k=a+a;a+=1;k+=a; //k=(7+7)+8
k=(a++)+(a++)+(a++); 则 k=a+a;k+=a;a+=1;a+=1;a+=1; //k=(5+5)+5
又如a=5;b=2;
k=(a++)+(++b)+(a++); b+=1;k=a+b;k+=a;a+=1;a+=1;  
k=(a++)+(b++)+(a++); k=a+b;k+=a;a+=1;b+=1;a+=1;
发表于 2004-12-4 14:52:41 | 显示全部楼层
楼上各位所说的vc大概都是vc6,vc6的处理方法和gcc是一样的,而
vc2005和vc6不一样,vc2005的处理方法和GavinLan所说bc3.1一样是先处理完各个加数表达式再求和
发表于 2004-12-4 19:55:36 | 显示全部楼层

to yangtou

我并没有说到'+'和‘++’之间的关系,我只是说明gcc是先做前面的‘+’号而已,而区别与BC3.1的那种方式
发表于 2005-2-10 00:35:56 | 显示全部楼层
Post by hupeng923
楼顶的,是19,8。
头晕,呵呵

是19,8啊
先k=(5)+(++a)+(a++);这时a=6;
接着k=(5)+(7)+(a++);a=7;
最后k=(5)+(7)+(7)=19;a=8
结果k=19,a=8
回复 支持 反对

使用道具 举报

发表于 2005-5-9 10:08:34 | 显示全部楼层
哈哈,有趣,原来是酱紫啊,hupeng923 兄找到的这篇文章通通透透,让俺长知识了。更重要的是俺明白了有些东东不是想当然的,也不是随随便便做个简单试验就一定通了,一定要认真细致,不能眼高手低。 还有发帖来探讨问题是好的,可是如果有些人一点试验都没作就乱下结论那就不好了,你错不要紧,但是给新手造成困扰就不好了
回复 支持 反对

使用道具 举报

发表于 2005-5-9 10:55:34 | 显示全部楼层
个人感觉是编译器的翻译方案的制定差异造成各个编译器生成代码不一致。

不必要深究
回复 支持 反对

使用道具 举报

发表于 2005-5-9 15:56:20 | 显示全部楼层
如果这个题目完全不加括号会有意思一些.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表