QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1215|回复: 12

一道简单的C语言题

[复制链接]
发表于 2003-9-15 22:53:18 | 显示全部楼层 |阅读模式
[code:1]
main()
{int i=5;
printf("%d",(++i)+(++i)+(++i));
printf("%d",(i++)+(i++)+(++i));
}
[/code:1]
两个打印结果是什么,为什么呢
发表于 2003-9-15 23:44:51 | 显示全部楼层
result:2255
跟同学讨论了一下,第一行应该是这样的:{(++i)+(++i)}+(++i)
先算大括号里的。因为前置的++级别高,i先自增两次,为7,故7+7=14,
随后再增一次得8,故第一次输出14+8=22
第二行这样:{(i++)+(i++)}+(++i),后置++再整个运算后才加,
所以是8+8+9=25,整个程序执行完后看i值是11。
回复

使用道具 举报

发表于 2003-9-15 23:49:52 | 显示全部楼层
我用gcc 3.3编译的结果也是这样的的,但是对你的分析还是不大理解。
这一段:{(++i)+(++i)}, ++级别高没错,可是两个小括号是并列的,就是说
取值应该有先后,为什么两个括号里面的运算结果会相同呢?
回复

使用道具 举报

发表于 2003-9-18 17:05:12 | 显示全部楼层
呵呵,这个问题我一开始也想不通,我的解释是:
对编译器来讲,在计算()+()时,由于对(++i)这种运算的定义是先自增,后运算,所以实际的情况时这样的:我们要算的是i+i,但是i在运算前会先自增两次,然后再相加。
也就是说对(++i)+(++i),(i++)+(i++),这样的运算,其实都是
i+i,的运算,不同之处是(++i)是在运算之前自增,而(i++)是在运算之后
自增。
回复

使用道具 举报

发表于 2003-9-18 20:57:48 | 显示全部楼层
不必计较,这是电脑不是人。
回复

使用道具 举报

发表于 2003-9-21 21:26:51 | 显示全部楼层

Re: 一道简单的C语言题

[quote:a3e04ac703="chinapower"][code:1]
main()
{int i=5;
printf("%d",(++i)+(++i)+(++i));
printf("%d",(i++)+(i++)+(++i));
}
[/code:1]
两个打印结果是什么,为什么呢[/quote]

nonsense.
回复

使用道具 举报

发表于 2003-9-22 00:11:10 | 显示全部楼层
to dreamdreams:
为什么两个括号里面的运算结果会相同呢?
我想答案是这样的:
这是编译器对二元运算符的解释造成的,编译器认为对于二元运算符,必需将两个操作数都得到后再分别将他们移入寄存器而不是得到一个立即移入寄存器,所以:
第一个小括号运算完成之后,结果存在哪了? 存在i的地址里!
然后第二个小括号又取出i来自加一次,结果又存回i的地址里,
然后将i取出两次(由于都是从一个地址取出的值,这两次的值当然相等),再分别mov到寄存器里,然后相加
看待这个问题只要: 牢记没有++i或者i++这种对象,只有一个对象i,只要跟踪好当前i的值,结果就会如你所料
回复

使用道具 举报

发表于 2003-9-22 13:13:05 | 显示全部楼层
这是一个比较不好的程序例子之一.

i++, p++ 经常用于遍历数组或者内存。
而且一个表达式只用一次。

从软件工程的角度来说,不应该写这样的代码。

既然我们永远不会写这样的代码,为什么还去研究他呢?
回复

使用道具 举报

发表于 2003-9-23 01:30:57 | 显示全部楼层
多谢littlepig的解释,简单易懂。

研究还是有必要的,首先C语言的标准没变,大家还是要继续用,就算为了避免出错了解一下也好。另外,更重要的是很多已经存在的代码也许某一天发现有bug,要调试,如果正好有相似的代码,你不知道这个trick,恐怕是没办法了。
回复

使用道具 举报

发表于 2003-9-23 10:49:33 | 显示全部楼层
各位知道gdb的用法吗?我想看一下上面那个程序的汇编代码,那样子应该会比较好理解
回复

使用道具 举报

发表于 2003-9-24 14:16:01 | 显示全部楼层
我有了一个GDB的调试的文章,不知道能不能帮你。
http://charleswang.533.net


如果真的看到类似下面的代码,
(++i)+(++i)+(++i));
我会测试他,然后重写一个简单的。但我猜我不会碰到这样的代码。
回复

使用道具 举报

发表于 2003-9-25 21:40:28 | 显示全部楼层
不用gdb,你想看汇编代码,用objdump命令就可以
回复

使用道具 举报

发表于 2003-10-7 10:53:33 | 显示全部楼层
实际上这样的代码在商业软件中是被禁止的,没有人愿意维护这种程序,不过看看汇编代码就知道了
回复

使用道具 举报

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

本版积分规则

GMT+8, 2024-11-14 11:39 , Processed in 0.054810 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

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