Char自动转换为int(我猜)

时间:2018-04-04 15:53:00

标签: c

我有以下代码

char temp[] = { 0xAE, 0xFF };
printf("%X\n", temp[0]);

为什么输出为FFFFFFAE,而不仅仅是AE

我试过

printf("%X\n", 0b10101110);

输出正确:AE

建议?

4 个答案:

答案 0 :(得分:2)

您获得的答案FFFFFFAE是签名char数据类型的结果。如果你检查了这个值,你会发现它等于-82,其中-82 + 256 = 174,或者是十六进制的0xAE

打印0b10101110甚至174时获得正确输出的原因是因为您直接使用了文字值,而在您的示例中,您首先将0xAE值放在{{1}中如果你想以这种方式想到它,那么这个值就像是“重新解释模128”一样。

换句话说:

signed char

要修复此“问题”,您可以声明您最初使用的相同数组,只需确保使用 0 = 0 = 0x00 127 = 127 = 0x7F 128 = -128 = 0xFFFFFF80 129 = -127 = 0xFFFFFF81 174 = -82 = 0xFFFFFFAE 255 = -1 = 0xFFFFFFFF 256 = 0 = 0x00 类型数组,您的值应按预期打印。

unsigned char

输出:

#include <stdio.h>
#include <stdlib.h>


int main()
{
    unsigned char temp[] = { 0xAE, 0xFF };

    printf("%X\n", temp[0]);
    printf("%d\n\n", temp[0]);

    printf("%X\n", temp[1]);
    printf("%d\n\n", temp[1]);

    return EXIT_SUCCESS;
}

答案 1 :(得分:1)

https://linux.die.net/man/3/printf

根据手册页,%x%X接受unsigned integer。因此它将从堆栈中读取4个字节。

在任何情况下,在大多数架构下,您都无法传递小于word(即intlong)的参数,在您的情况下它将转换为int.

在第一种情况下,您传递char,因此会将其投放到int。两者都是签名的,因此执行签名的强制转换,因此您可以看到前面的FF

在你的第二个例子中,你实际上一直在传递int,所以不会执行强制转换。

如果您尝试:

printf("%X\n", (char) 0b10101110);

您会看到FFFFFFAE将被打印。

答案 2 :(得分:1)

当您将小于int数据类型(如char is)传递给可变函数时(如printf(3)那样),参数将转换为int以防万一参数为signed,如果是无符号,则为unsigned int。正在做什么并且您观察到的是符号扩展,因为char变量的最有意义的位是活动的,它被复制到完成{{1}所需的thre字节}。

要解决此问题并将数据保存为8位,您有两种可能:

  • 允许您的int转换为int(带符号扩展名),然后屏蔽8位及以上的位。

    signed char
  • 将您的变量声明为printf("%X\n", (int) my_char & 0xff); ,因此会将其提升为unsigned

    unsigned int

答案 3 :(得分:0)

此代码会导致undefined behaviour%X的参数必须为unsigned int,但您提供char

未定义的行为意味着任何事情都可能发生;包括但不限于输出中出现的额外F。