首页
社区
课程
招聘
C语言中的变量问题
发表于: 2010-5-11 21:29 3235

C语言中的变量问题

2010-5-11 21:29
3235
最近在看一本讲C语言的外国教材《C Primer Plus》,看了些内容后发现有很多东西是以前谭浩强教授编的书《C程序设计》所没有提到的,现在我暂时有两个疑问想请教下大家,打扰了。
第一个问题就是在C语言中float类型的数据为什么要默认以double类型来存储,这样做有什么好处?《C Primer Plus》和《C程序设计》两本书中均没有对此解释。

第二个问题:请大家看下面一张截图:

在这个小程序中书上对前面两个printf的输出结果的解释我可以理解,但是书中对第三个printf中n3和n4变量输出结果的解释是这样的:在堆栈中n1和n2各自占用8个字节,n3和n4各自占用4个字节。当printf函数从堆栈中把值读取出来时,%ld说明符指出,printf()应该读取4个字节,所以printf()在堆栈中读取前4个字节作为它的第一个值。这就是n1的前半部分,它被解释成一个长整型数。下一个%ld说明符在读取4个字节;这就是n1的后半部分,它被解释成第二个长整型数。同样,%ld的第三个和第四个实例使得n2的前半部分和后半部分被分别读出,并解释成两个长整型数。所以,虽然n3和n4的说明符正确,但printf()仍然读取了错误的字节。
我注意到一个问题就是它这样解释的前提条件是在堆栈中n1,n2,n3,n4的存放空间是首尾相接的,各自所占内存空间之间没有夹杂其他数据,我是不是可以这样认为,在C语言的一个主程序(就是main主函数体)中,操作系统给程序分配的所有变量存储空间是一段连续的堆栈,首尾顺次连接?

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 15
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
分配的内存应该不是连续的首尾相接的,   中间有 指针的
2010-5-11 21:38
0
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
3
第一个问题我也解释不了。
第二个问题 分配变量的存储空间不能保证是连续的 但在call printf之前会有参数入栈过程,入栈是的n1 ...4确实是连续的,你可能把参数入栈和给变量分配空间认为是等同的了。
2010-5-11 21:58
0
雪    币: 724
活跃值: (81)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
存储和压栈并不是一个概念,楼主把它们弄混了。

printf的函数原型是: int __cdecl printf(const char*,...),这意味着printf只有第一个参数是有类型的,后续的参数可选且没有类型,而参数是通过栈传递的,没有类型的可选参数如何入栈?对于这种情况,VC有一个约定,如果参数是浮点类型,则将它们转成double压入栈中,如果参数是8位/16位的整型,则将它们转成32位整型压入栈中。
如果参数不是可选的参数,则会严格根据函数原型将参数入栈,如对函数:
        int __cdecl test(int op0, float op1, double op2);
进行如下调用:
        int n0=10;
        int n1=1;
        void* pOther;
        int n2=2;
        test(n0,n1,n2);
        ...
则编译器会根据函数原型将n1转为float压入栈中,将n2转为double压入栈中,n0由于类型匹配,不进行转换,直接压入栈中。
注意入栈的是数据副本,入栈的数据在空间上是连续的,但并不意味着n0,n1,n2的存储空间是连续的。
2010-5-12 08:39
0
游客
登录 | 注册 方可回帖
返回
//