LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 839|回复: 11

printf 的输出问题

[复制链接]
发表于 2004-1-10 22:25:16 | 显示全部楼层 |阅读模式
以下代码:
main( )
{
    int a=1;
    printf("%d,%ld\n",a,a);
}
在Turbo C 2.0下编译。
在Windows 98下得到输出:1,14221313
Windows 98启动按F8进入的Dos输出为:1,11272193
用Windows 98启动盘启动则为:1,6619137
####################################
将上述代码中的数据类型改为short,
则三种情况的输出都为:1,65537
####################################
将数据类型改为long,
输出都为:1,65536;
将声明赋值语句改为 long a=1L,也是一样
####################################
上述情况让我很郁闷,我看的是谭浩强的《C 程序设计》,因为书中
是以Turbo C 2.0为例子,所以找了Turbo C 2.0来学习C 语言,看了前两章有
一些小问题,觉得自己太钻牛角尖了,也就忽略过去了,但这次的试验实在太让人
困惑了,一颗满腔热血学习C语言的菜鸟之心被泼了一盆冷水。

恳请高手为我释疑阿,万分感激!!!
###################################
在gcc下(gcc-2.96):可之short为16位,int和long都为32位,我得到了正确的输出
发表于 2004-1-10 22:33:16 | 显示全部楼层
简单的说就是因为编译器的不同而有这样不同的输出的。
 楼主| 发表于 2004-1-10 22:52:10 | 显示全部楼层
但是以上代码是如此之简单阿!!!
发表于 2004-1-10 22:59:37 | 显示全部楼层
最初由 wanglej 发表
但是以上代码是如此之简单阿!!!


编译器的作用是解释一段程序和编译成目标代码。怎么解释要看编译器是怎么写的,这就要问写编译器的人了。
就象把一幅图(程序)给不同的人(不同的编译器)看,每个人的见解都不同一样。
 楼主| 发表于 2004-1-10 23:16:13 | 显示全部楼层
谢谢777兄
但我还是不明白啊!
我以为这么简单的代码都得不到正确输出,那Turbo C有什么用
希望有多平台下C编程经验的高手能为我释疑,谢谢了
发表于 2004-1-11 00:16:32 | 显示全部楼层
tony:/tony# cat 6.c
#include <stdio.h>

main() {
int a =1;
printf("%d,%ld\n",a,a);
}
tony:/tony# gcc -o 6.o 6.c
tony:/tony# ./6.o
1,1
tony:/tony#

所以 还是用GCC吧!
发表于 2004-1-11 13:12:10 | 显示全部楼层
原因在于TC2是16位的编译器,它的int类型是2个字节。

对于第一种情况调用printf时堆栈的情况是:
00
01 <-第二个a
00
01 <-第一个a
用%d,%ld输出时%d没问题,因为类型正确,而%ld需要long类型,就是4个字节,所以就用到了第二个a后面的两个字节,而这两个字节的值是不一定的(如果你连续运行程序多次也很有可能一样),所以出现了你说的情况。

对第二种情况,我还没搞清楚,TC2里short和int都是2个字节,这里应该和第一种情况表现一样呀,没搞懂。
65537应该是10001h,输出%ld的内存是
00
01
00
01
这里上面的00 01是从哪来的我还不清楚。
我这里没有TC2,你能不能用TC2的调试看看汇编码是什么样的。

对第三种情况,堆栈是:
00
00
00
01 <-第二个a
00
00 <-输出%ld
00
01 <-第一个a
这里要参考一下va_arg,输出%d时取出了前两个字节(int的长度),所以输出1,输出%ld时取出4个字节(long的长度),但是因为输出%d时没有取足4个字节,所以这里取出的是00 00 01 00,就是65536
 楼主| 发表于 2004-1-11 22:00:33 | 显示全部楼层
libinary兄,太感谢了,很佩服你!!!
你说的我现阶段还不能完全理解,我还没学汇编,C也刚开始;
本来想gcc ,Turbo C 两手抓,现在是不是应该抛弃Turbo C呢?libinary觉得呢?
#######################
有一点不明白,Turbo C 的Logo 说它出于1987,此时i80386已上市两年,Boland为何还出16位软件,还很受欢迎呢?

谭浩强《C 程序设计》P74,第四行:”一个int数据可以用%d或%ld格式输出“
他是不是用的286啊?
发表于 2004-1-11 22:13:57 | 显示全部楼层
现在主流32位的计算,已经出现了向64位转移的趋势。16位的只是在一些工业控制的场合还在使用,如果不想往这方面发展,就不要学了。
不同的编译环境对整数的自理不一样,函数库的实现也不一样,谭浩强《C 程序设计》应该已经在书中的说明书上例程的编译环境,如果你的编译环境与他的不一致,出现问题并不奇怪。
 楼主| 发表于 2004-1-11 22:18:04 | 显示全部楼层
可以参考这本书在gcc下学C吗?多谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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