回 帖 发 新 帖 刷新版面

主题:以16进制打印unsigned char的问题

代码如下:

#include <stdio.h>
int main(int argc,char *argv[])
{
    unsigned char a[2];
    char b[2];
    a[0] = 0x7f;
    a[1] = 0xf0;
    b[0] = 0x7f;
    b[1] = 0xf0;
    printf("a[0] is %02x\n",a[0]);
    printf("a[1] is %02x\n",a[1]);
    printf("b[0] is %02x\n",b[0]);
    printf("b[1] is %02x\n",b[1]);
    printf("c is %02x\n",c);
}
下面是执行结果
[root@localhost unsigned char]# ./a.out 
a[0] is 7f
a[1] is f0
b[0] is 7f
b[1] is fffffff0


我的问题是:我不是很明白变量b[1](char型,值为0xf0),以%02x方式打印出来为什么是fffffff0。我可以肯定和类型转换有关系,b[1]到最后肯定被转换成了int型,但不能完全搞清楚当中的原因。请各位指教哈

回复列表 (共13个回复)

11 楼

[quote]无论是0xfffffff0L == a或0xfffffff0U == a。结论是都成立。
[/quote]

这也是肯定的了,因为(signed int)0xfffffff0 == (unsigned int)0xfffffff0
(signed int)0xfffffff0 转换成unsigned int已经溢出了,根本没有一个无符号数来表示一个负数。

如果把代码中的char a = 0xf0改为unsigned char a = 0xf0, 就不会出现这样的问题。

12 楼

唉,我還真沒仔細分析,這回真是錯大了:)
看了匯編,再重给讲一回吧:
短类型升阶到长类型,需要走两步。
1、将位数变成目标长度。这一步是否扩展符号位是看源数(而不是目标数,这就是我之前的错误)
2、调整类型到目标数。这一步之后,后面所有的运算就按目标数类型做再次的升阶或其他运算了。
比如说:
char a=0xf0;
long long b=(0UL+a)*1LL;
结果b=0x00000000fffffff0;
原因就是表达式中0UL+a就导致a升阶为unsigned long,而后就不会再以有符号的方式继续升阶为long long了:)

13 楼

谢谢各位,搞定结帖

我来回复

您尚未登录,请登录后再回复。点此登录或注册