打印
[嵌入式linux]

潭浩强的C和linux的C,请老手指教

[复制链接]
10557|43
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
netfight|  楼主 | 2009-2-7 10:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有这样一段程序
#include <stdio.h>
#define SQ(y) ((y)*(y))
main(){
    int i=1;
    while(i<=5)
     
      printf("%d ",SQ(i++));
}
在谭浩强的C教材中(大约是2001年版),用的应该是TuboC2.0,给吃的结果是
2
12
30

我在里linux中(Fedora 10),gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC)
结果是
1
9
25

其差别在于i的增值的点。
请问这种差别正常吗?什么原因呢?

相关帖子

沙发
E007| | 2009-2-8 22:42 | 只看该作者

和编译器有关系

这种写法我从来不用,程序一移植就可能出问题,问题就出在对这种写法没有个统一的说法,有的是先加,有的是后加,各种编译器处理的方式不尽相同.多写一行很费劲吗?如果说是为了提高速度(现在的处理器还在乎你那一条语句吗?),那用汇编.如果不是为了提高执行速度,分开写,多写一行而已.

使用特权

评论回复
板凳
dragon_hn| | 2009-2-9 04:03 | 只看该作者

正常,两个C标准不一样.

在实际工作中要避免这样的写法.

使用特权

评论回复
地板
xwj| | 2009-2-9 08:32 | 只看该作者

原则上,第一个是错的

后加应该是扫描完整个语句后再++


这不是“多写一行”的问题,而是做编译器的人对C语法的理解、定义问题

使用特权

评论回复
5
E007| | 2009-2-9 12:08 | 只看该作者

xwj说的没错!

是做编译器的人对这种语法的理解问题,可我们没法去左右那些人哪,只能是人家做成啥样咱用啥样的.再者,多写一行其实也未必就会使指令增加,在编译优化后可能与合在一起生成同样的汇编指令队列.但程序的可读性更强,不容易使人迷糊.

使用特权

评论回复
6
sinanjj| | 2009-2-9 22:29 | 只看该作者

我确定在linux中是这个结果

我试过。。。。
而且 i++就是该先用i,后++

使用特权

评论回复
7
jueju300| | 2009-2-12 13:46 | 只看该作者

..

原帖没被编译过吧?
结果应该是
1
4
9
16
25

5个结果吧?
++i 是先加再用
i++ 是先用在加

我的这个算法 是哪个标准?



旧帖重读 虽然有点汗 但是决定原来的话就不删除了
也算是进步了 总体来说是被高手忽略 伪高手忽悠了
变量在被调用的过程中 不会直接使用变量 而是被移入寄存器
在编译的时候 用编译命令通知编译器 处理方式
正常(默认)情况下 会是结果2 编译器认为变量在此过程中不会改动 所以只读取一次变量值到寄存器
如果使用volatile关键字 编译器认为变量随时会变动 每次在使用该变量时都会重新读变量到寄存器 那么计算出来的就是谭浩强的结果
看什么高手说 再看就是没脑子 尤其是不说情况 云山雾罩的伪高手

再汗一下!好久不来了 更正完了出去之后才发现别人早已经解释过了 这不是直接抄的 - -!

使用特权

评论回复
8
qiangzhang| | 2009-2-18 10:10 | 只看该作者

DAMN IT

F U C K Y  standard ,(i++)*(i++) double plus,can you see what I mean?

使用特权

评论回复
9
luckyfzl| | 2009-2-22 22:44 | 只看该作者

AVRStudio里好像也是第一种结果

AVRStudio里好像也是第一种结果。
哪种该算是正确的?

使用特权

评论回复
10
老树昏鸦| | 2009-3-1 12:45 | 只看该作者

千万不要这么干!

   根据C/C++的定义,如果在同一表达式中两次读取同一个变量,并且还对该变量进行写操作,那么结果就是为定义的。

使用特权

评论回复
11
老树昏鸦| | 2009-3-1 12:58 | 只看该作者

纠正错别字:那么结果就是“未”定义的。

使用特权

评论回复
12
老树昏鸦| | 2009-3-1 13:15 | 只看该作者

举个例子:

   形如:i++ + i++;这类的表达式其结果就是未定义的。
   结果未定义的后果是很可怕的,按照C专家Peter Van Der Linden的话说,只要编译器作者喜欢,它可以采取任何动作----包括发射几枚核导弹。

使用特权

评论回复
13
tw2835| | 2009-3-1 13:22 | 只看该作者

……

宏定义  SQ(y) ((y)*(y))
按照TC的理解 先直接替换 成(i++)*(i++)
第一次 1*(1+1)
第二次 (1+1+1)*(1+1+1+1)
第三次 (1+1+1+1+1)*(1+1+1+1+1+1)
而linux  gcc编译器是这样 先把i的值代进去 进行乘法运算,然后统计i加了几次 
我在vs2005 realse和debug上编译也是  1 9 25 


使用特权

评论回复
14
backupyan| | 2009-3-12 22:00 | 只看该作者

这么写的程序员会被炒鱿鱼吧

使用特权

评论回复
15
linux123| | 2009-3-13 15:05 | 只看该作者

对,是C的环境和开发C的开发者对规则定义的问题

使用特权

评论回复
16
wrc8922| | 2009-3-21 22:53 | 只看该作者

潭浩强的C和linux的C,请老手指教

什么嘛!第一个我在C-free中做出的也是1;9;25.现在谁还用tuboC做啊!!!

使用特权

评论回复
17
wrc8922| | 2009-3-21 22:55 | 只看该作者

现在谁还用TUBOC啊!

第一个我用Cfree做了,结果是2;9;25

使用特权

评论回复
18
bombzhao| | 2009-3-22 16:13 | 只看该作者

编译器相关的

使用特权

评论回复
19
后学| | 2009-3-25 21:54 | 只看该作者

编译器的实现细节不一样,

如果考虑移植性的话,尽量避免这种写法。。。

使用特权

评论回复
20
snakeemail| | 2009-3-26 16:00 | 只看该作者

你这样写代码,不符合规范。

把这些都写到while循环里不是好看些吗?
把乘法写进去,i++和printf分开写,你再试一下。
代码好不好理解重要些。特别在你这种场合,效率不是很高得情况。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

24

帖子

0

粉丝