| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2277 人关注过本帖
标题:C程序关于整型数据溢出的几种情况求解
只看楼主 加入收藏
zyzwlh
Rank: 1
等 级:新手上路
帖 子:43
专家分:0
注 册:2007-5-17
收藏
 问题点数:0 回复次数:4 
C程序关于整型数据溢出的几种情况求解
在谭的书上有讲
#include <stdio.h>
void main()
{
   int a,b;
   a=32767;
   b=a+1;
   printf(“%d,%d”,a,b);

这个将b改为long就可得到希望的结果   
但我采用
#include <stdio.h>
void main()
{
   int a;
   long b;
   a=32767;
   b=a+1;
printf(“%d,%ld”,a,b);

所得到的仍然是32767,-32768

如果采用
#include <stdio.h>
void main()
{
   int a;
   long b;
   a=32767;
   b=a+1;
printf(“%d,%d”,a,b);

结果和上面的一样

采用
#include <stdio.h>
void main()
{
   int a,b;
   a=32767;
   b=a+1;
printf(“%d,%ld”,a,b);

结果是a为32767,b的值却是一个很大很奇怪的数

采用
#include <stdio.h>
void main()
{
   long int a,b;
   a=32767;
   b=a+1;
printf(“%d,%d”,a,b);

结果也很奇怪  a为32767,b却变成了0

困惑了半天也没想通   所以发到帖吧来寻求明白的人给我点提示  感激不尽!
PS:
我的环境是TC2.0
我用
#include <stdio.h>
void main()
{
   int a,b;
   a=32767;
   b=a+1;
   printf("%d,%d\n",a,b);
}   已经得得正确结果   我主要是想了解出现前面几种情况的原因
先在这里谢谢了!
搜索更多相关主题的帖子: 整型 数据 求解 
2008-05-10 20:13
yd4433
Rank: 1
等 级:新手上路
帖 子:404
专家分:0
注 册:2008-3-9
收藏
得分:0 
long -> %ld   当 数据益处的时候 是随即的值     回答完毕

------...-.-..-...-----........-------.......----.....------....||- - !
2008-05-10 21:38
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
我测试的结果如下:
1.32767,32768请按任意键继续. . .
2.32767,32768请按任意键继续. . .
3.32767,32768请按任意键继续. . .
4.32767,32768请按任意键继续. . .

我用GCC编译器。
至于为什么是这结果。因为GCC是32位编译器,%d对应32位整型。我想无论如何都不会溢出的吧……上次为了有溢出的效果,还得手动加上%hd………………
至于LZ的问题。你分两方面考虑:1 变量内部的实际值是多少?
比如short a;long b;a为32767时其实际值为0x7FFF,b为a+1的实际值是0x00008000。显然b没有发生溢出,其值为32768。当short a,b;a=0x7FFF,b会等于0x8000而最高位表示正数的0被溢出为1,所以b现在是负数。数值大家可以算出来,是-0x08000,即-2^15=-32768。
2 显示的的时候,实际输出的是多少?
首先强调一点。就是printf并不知道你后面的数字是什么类型。它只是按照你给出的格式控制符,自己往后面取相应的位数,当作相应的类型而已。举个最简单的例子:
printf("%hx,%hx",0x12345678,0);
输出多少?有人说是5678,0,错误。首先h规定了只取16位。而后面0x12345678有32位。于是只取前16位,根据Little-Endian,前16位为9x5678,然后取后16位,后16位为0x1234。如果你是TC,可以写成0x12345678L比较安全一点,反正应该是5678,1234这个结果。
回到原题。对于上面第一种情况(short a;long b;)a倒是%hd这个毫无疑问了,对于b,问题就来了。你用%hd是100%会得到-32768,因为它只取了b的低16位然后当作一个short!所以b高位是什么,就没什么必要了(这里没用到高位),而如果是第二种情况,也是同样的结果。
如果b用%ld,对于第一个,很正常地读到了32位值,然后忠实地显示为32768。对于第二个,为什么会乱码呢?因为b根本只有16位,它读了b的16位以后又跟过去读了b后面的16位,这16位是随机的数据(在本题里,是上一个函数,即main函数的返回地址,也就是Startup Code的地址),那么当然会是一个很怪异的大数字咯。
不知道你看懂没,没看懂的话,跟帖问。关键是搞清楚这两个不同的过程。

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-05-10 22:28
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
补充:上面的代码printf("%hx,%hx",0x12345678,0);,TC上运行的确是5678,1234,符合预期,但是GCC和VC居然都是5678,0。晕了……怎么回事?我记得如果是va_arg的话,的确只是按照位来取,而没有办法判断变量的间隔的啊??不明白了,于是使用了下面的代码:
    printf("%hx,%hx",0x12345678abcdLL,0);
得到了预期值abcd,1234。NND,好狡猾,无论是什么类型的变量居然都占用32位空间,差点被忽悠了……

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-05-10 22:36
zyzwlh
Rank: 1
等 级:新手上路
帖 子:43
专家分:0
注 册:2007-5-17
收藏
得分:0 
  基本看懂了  
   我之前也用了gcc   当时就发现没有溢出    感觉gcc和TC至少默认的int所占用的存储空间不同  gcc要大些
     真的很感谢你
2008-05-10 23:33
快速回复:C程序关于整型数据溢出的几种情况求解
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017200 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved