[C 语言] 字符型的16进制输出

阅读更多

问题:将一个字符类型按16进制输出,输出格式为0xab, 0x后面要求是2位,不够2位则补0,比如“0x0b”。

常见的错误做法是:

#include 
int main()
{
    char a = 0x41; // a = 'A'
    printf( "the hex value of a is 0x%02x\n", a );
    return 0;
}

 貌似正确,但是如果a = 0xf1,上面的输出将是 0xfffffff1 而不是 0xf1。

 

究其原因,%x 是 unsigned int  或  int  型输出 ,所以 printf("%x", a) 在执行时将自动将 a 类型提升(char 将提升至 int;unsigned char 将提升至 unsigned int), 注意到 char 是 signed(有符号的),如果这时 a 是负数 ,在提升的时候前面将会补1 ,即象反例中的 0xf1 => 0xfffffff1;而unsigned char 在提升的时候只会补0。

 

解决的办法有三:

方法1. 强制类型转换

#include 
int main()
{
    char a = 0xf1;
    printf( "the hex value of a is 0x%02x\n", (unsigned char)a );
    return 0;
}

但是上面的例子不能写成 (unsigned int)a 或者 (unsigned short)a。这又涉及到类型隐式转换的过程,举例来说:

当 a 是 char,(unsigned int)a 提升的过程:
char => int
int => unsigned int

 

方法2. 精确打印格式

#include 
int main()
{
    char a = 0xf1;
    printf( "the hex value of a is 0x%02hhx\n", a );
    return 0;
}

其中 hh 将会将 int 转化成 char;unsigned int 转化成 unsigned char。具体可以 man 3 printf 查看详情。

hh     A following integer conversion corresponds to a signed char or unsigned char argument, or a following n conversion corresponds to a pointer to a signed char argument.

注意:printf format 格式与平台相关( linux 中的 printf 在 glibc 中实现 ),方法2在 VC 并不能通过。

 

方法3. 强制位数为 1 byte

#include 
int main()
{
    char a = 0xf1;
    printf( "the hex value of a is 0x%02x\n", (a&0xff) );
    return 0;
}

上面隐含过程是:先将 char a 提升至 int,然后再与 0xff 相与。

 

 

你可能感兴趣的:(C,linux)