franksunny的个人技术空间
获得人生中的成功需要的专注与坚持不懈多过天才与机会。 ——C.W. Wendte

今天一个很偶然的机会,需要回答一个将无符号数据存到有符号变量的问题。我编码如下,结果很有意思,我是在VC6里调试的,有高人看到可否帮忙指点下。
int main()
{
    unsigned short temp1 = 65535;
    short temp2 = temp1;
    unsigned short temp3 = (unsigned short)temp2;
    unsigned short temp4 = temp2;
    int temp5 = temp2;
    unsigned int temp6 = temp2;
    unsigned long temp7 = temp2;
    int temp8 = (unsigned short)temp2;
    short temp9 = temp2;
    printf("temp1 = %d\n temp2 = %d\n temp3 = %d\n temp4 = %d\n temp5 = %d\n temp6 = %d\n temp7 = %d\n temp8 = %d\n temp9 = %d\n",
     temp1,temp2,temp3,temp4, temp5,temp6,temp7,temp8,temp9);
    return 0;
}
//改程序的输出结果
//temp1 = 65535
//temp2 = -1
//temp3 = 65535
//temp4 = 65535
//temp5 = -1
//temp6 = -1
//temp7 = -1
//temp8 = 65535
//temp9 = -1;


//根据结果也就是说,无符号符号数据是可以存储在有符号型变量内存中的,
//而且有例子在内存块长度一样时,不用强转,直接赋给无符号变量时也可行
//上述事实可以解释为内存块不变,采用不同的解码方式解出不同的数据
//但是读出来的时候要注意,如果有符号转无符号一定要强转
//之所以上例unsigned int输出-1,我并不是很清楚

posted on 2007-10-17 22:46 frank.sunny 阅读(2985) 评论(13)  编辑 收藏 引用 所属分类: C/C++学习和实践

FeedBack:
# re: 无符号变量居然也能输出-1
2007-10-17 23:46 | Minidx全文检索
计算机采用的是补码,而非原码或反码
写成补码试试看  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 08:57 | 回复一下
格式化输出的类型要和参数相匹配,你把所有的类型都以%d来输出是有问题  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 09:05 | 绝对零度
输出无符号型要用%ud  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 09:33 | Minidx全文检索
汗……居然没想到ud  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 09:41 | frank.sunny

其实昨天写了这个东西也没有太去细想,今天看到有人回复,我就跟踪内存调试了下,其实执行到temp6和temp7赋值时,内存中实际存储的是4294967295(也即FFFFFFFF),所以如果不用“%d”输出,改用“%u”输出的话,结果也不是65535,而是4294967295。
当然没有“%ud”这种输出,大概是楼上笔误吧。

至于为什么赋值时赋成FFFFFFFF,而不是0000FFFF,我也不是很清楚,我自己刚开始以为初始化问题,所以先将temp6 = 0;再用temp6 = temp2;发现结果还是一样。这个问题还望高手指点一下啊  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 10:14 | Minidx全文检索
temp6需要高位清零
temp6 = temp2 & 0xFFFF;  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 10:45 | frank.sunny
@Minidx全文检索
楼上谢谢你的关注,咱们讨论讨论哦
像你所说的方法,进过运算,默认0xFFFF是int型的,所以是先计算了一下的,我现在需要考虑的是直接赋值,也就是说如果我想得到正确的值,我默认可以
temp6 = (unsigned short)temp2强转一下就可以了,不用运算。

我想知道short型的变量赋给int型的时候,是什么样的机制,还有就是有符号和无符号的机制是什么样的?
其次就是我是在Windows的VC6环境下调试的,是不是其它环境下也是将0xFFFF变成了0xFFFFFFFF了?  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 11:08 | 蚂蚁终结者
实际上就是有符号数转换中"符号位扩展"的问题。
short temp2 = temp1;
...
unsigned int temp6 = temp2;
先不管temp2的值是多少,上面就是short符号位扩展到int,然后再从int转unsigned int的问题。short是有符号类型,先进行符号位扩展(假设short为16位,int/unsigned int为32位)
1. short为正数,则最高位为0,当从16位扩展到32位int时,扩展的高16位用0填充,即将符号位0进行扩展,这样扩展后的32位整数和原来的整数值是一样的。
2. short为负数,则最高位为1,当从16位扩展到32位int时,扩展的高16位用1填充,即将符号位1进行扩展,这样扩展后的32位整数和原来的整数值是也是一样的。
即上面的代码等效于:
short temp2 = temp1;//temp2为-1(11111111 11111111)
...
int tempInt = temp2; //符号位扩展,tempInt也为-1(11111111 11111111 11111111 11111111)
unsigned int temp6 = tempInt;//将(11111111 11111111 11111111 11111111)解释为无符号
  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 11:21 | Minidx全文检索
这下应该OK了,问题的本质出来了,呵呵  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 12:19 | frank.sunny
果然是这样子,谢谢蚂蚁
我顺着你的符号位扩展的线索网上搜了一下,发现原来有本入门级的书就讲这个的,http://book.csdn.net/bookfiles/169/1001697518.shtml
不知道大家有没有看过,好的话,我也去弄一本,感觉在学校那会没人跟我提到过有这么一个术语呢,是不是有需要空闲时拿来翻翻  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-10-18 12:44 | 蚂蚁终结者
呵呵,过来改正个笔误,11111111居然写成了1111了...  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2007-11-30 10:56 |
你用%d输出,当然可能输出负数了.要用%u输出  回复  更多评论
  
# re: 无符号变量居然也能输出-1
2008-01-31 22:15 | Gildor
蚂蚁兄说得对。从short到unsigned int有两步转换,先从short到int,再由int到unsigned int。你可以显式指定转换顺序,让它先由short转为unsigned short再转为unsigned int: unsigned int temp6 = (int)(unsigned short)temp2;。这样就会得到temp6为0x0000ffff。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理



常用链接

留言簿(13)

随笔分类

个人其它博客

基础知识链接

最新评论

阅读排行榜

评论排行榜