2015-09-30 69 views
-1

我想知道为什么printf语句在下面的代码中将字符值显示为4字节值(fffffffe)。由于字符是1字节,所以我认为我们应该只得到FE一个字节值的结果。打印反转字符

int main(void) 
{ 
    unsigned char a4=1; 
    char b4=1; 
    printf("inverted a4 = %x\t b4= %x\n",~a4, ~b4); 
    return(0); 
} 
+1

打印用'hh'如在'的printf( “倒A4 =%HHX \吨B4 =%HHX \ n” 个,〜 a4,〜b4);'以避免打印符号扩展名。 – chux

回答

2

当你做任何算术或位操作char量,它被悄悄地转换为int第一。这被称为integer promotion。它也会影响short(和signed char,unsigned charunsigned short)。 (从技术上讲,如果sizeof(unsigned short) == sizeof(unsigned int)然后unsigned short将促进unsigned int而非int,但你可能不会在与特性的系统跳闸了,尽管它仍然C标准允许的。)

发生在charshort当它们通过匿名参数传递到printf(或任何其他可变参数函数)。

所以,你的代码

unsigned char a4=1; 
char b4=1; 
printf("inverted a4 = %x\t b4= %x\n",~a4, ~b4); 

相当于

... 
printf("inverted a4 = %x\t b4= %x\n", (int) ~(int)a4, (int) ~(int)b4); 

(该在~投后没有做任何事情,但我已经写它无论如何强调的是,转换可能发生,因为算术和因为参数传递。)

有没有办法来打开这种行为关闭。为了得到你想要的效果,我会写

static_assert(CHAR_BIT == 8); 
printf("inverted a4 = %02x\tb4 = %02x\n", 
     (~(unsigned int)a4) & 0xFFu, 
     (~(unsigned int)b4) & 0xFFu); 

这和MikeCAT和尼克建议的代码之间的区别是,所有的位操作上无符号量完成。有些操作在应用于带符号数量时具有未定义的行为,并且我无法准确记住规则是什么,所以我只是避免将它们中的任何一个用于有符号数量。 (从%x%02x的变化仅仅是为了美观。)

static_assert失败的系统现在很少见,但仍然被C标准允许。我主要把它包括在内以记录程序的期望。 (该0xFFu掩模和%02x格式化是错具有用于CHAR_BIT不同的值的系统。)

0

sizeof(~b4)为4中Wandbox

要得到只有FE,使用AND掩码。
此外,将%x更改为%X以获得FE,而不是fe。

#include <stdio.h> 

int main(void) 
{ 
    unsigned char a4=1; 
    char b4=1; 
    printf("inverted a4 = %X\t b4= %X\n",(~a4) & 0xFF, (~b4) & 0xFF); 
    return(0); 
} 
0

参数%X和%x预计为int

您提供char,它被铸造为int

的解决方案是为MikeCAT给:

printf("inverted a4 = %X\t b4= %X\n",(~a4) & 0xFF, (~b4) & 0xFF); 
0

这样做的原因是这样的......(省略号)函数C.工作当char参数提供给省略的功能,它是“扩大'int(或unsigned int,取决于char是有符号还是无符号)。实际上,小于int的所有东西都被扩展(正确的术语被提升)为int。作为这次升级的结果,当printf看到这个价值时,它已经被提升了。顺便提一下,float以同样的方式被提升为double。

0

编译器在将字符反转之前将字符(0x01)提升为32位整数(0x00000001),这会给出值(0xFFFFFFFE)。

你可以做一个位与作为其他的答案中提到,或添加一个类型转换的答案转换回char类型之后:

unsigned char a4=1; 
char b4=1; 
printf("inverted a4 = %X\t b4= %X\n",(unsigned char)(~a4), (char)(~b4)); 
return(0); 
+0

'(char)' - >'(unsigned char)' – BLUEPIXY

+0

它不给出'0xFFFFFFFE'的值;它给出值'-2'。 –

2

~操作者的操作经历整数促销charunsigned char类型的操作数被提升为int,结果为int

char b4=1; 

b4char类型。

~b4 

b4值晋升为int,并且操作者~产生的1按位求补。如果int是32位,则结果是-2,假设有符号整数的2的补码表示。

printf"%x\n", ~b4); 

int-2被打印,好像它是unsigned char类型;结果是fffffffe

如果你只想低8位,你可以使用一个位掩码:

printf("%X\n", ~b4 & 0xFF); 

这将打印FE