c - 打印字符的反转

标签 c

我想知道为什么 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);
}

最佳答案

当您对 char 数量进行任何算术或位运算时,它会首先默默地转换为 int。这称为integer promotion 。它也会影响 short(以及 signed charunsigned 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 和 Nick 建议的代码之间的区别在于,所有位操作都是在无符号数量上完成的。某些位运算在应用于有符号数量时具有未定义的行为,并且我永远无法准确记住规则是什么,因此我只是避免对有符号数量执行任何操作。 (从 %x 更改为 %02x 只是为了美观。)

如今,static_assert 失败的系统已经非常罕见,但同样,C 标准仍然允许这样做。我主要将其包含在内以记录程序的期望。 (0xFFu 掩码和 %02x 格式化程序在 CHAR_BIT 值不同的系统上是错误的。)

关于c - 打印字符的反转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32870276/

相关文章:

c - MISRA 2012 违规 - 类型不匹配(规则 10.1、10.4)

c - 如何分析coredump的内存泄漏

c - CUDA 中的强制对齐?

c++ - C/C++(还有其他语言吗?)有条件提前返回良好代码实践

c - C 中预期的说明符限定符列表

c - strtok() 覆盖它的源字符串

c - 在 C 中读取行并一次读取三个字母

c - 测试多个数组中是否存在某些值的最简单方法是什么?

c - heapusage 不显示正在分析的程序的函数名称

c - 如何在 C 语言中对汉字(UTF-8)进行操作?