定义的行为,将字符传递给printf(“%02X”

时间:2011-05-20 08:14:44

标签: c printf undefined

我最近遇到this question,其中OP在打印变量的十六进制值时遇到问题。我相信问题可以归结为following code

#include <stdio.h>

int main() {
    char signedChar = 0xf0;

    printf("Signed\n”);
    printf(“Raw: %02X\n”, signedChar);
    printf(“Masked: %02X\n”, signedChar &0xff);
    printf(“Cast: %02X\n", (unsigned char)signedChar);

    return 0;
}

这给出了以下输出:

Signed
Raw: FFFFFFF0
Masked: F0
Cast: F0

用于每个打印的格式字符串是%02X,我总是将其解释为“将提供的int打印为至少有两位数的十六进制值”。

第一种情况将signedCharacter作为参数传递并输出错误的值(因为int的其他三个字节都设置了所有位。)

第二种情况通过对值应用位掩码(0xFF)来解决此问题,以删除存储char的除最低有效字节之外的所有字节。这有用吗?当然:signedChar == signedChar & 0xFF

第三种情况是通过将字符转换为unsigned char来解决问题(这似乎清除了前三个字节?)。

对于上述三种情况中的每一种情况,有人可以告诉我是否定义了行为?如何/在哪里?

1 个答案:

答案 0 :(得分:10)

我不认为这种行为完全由c标准定义。毕竟它取决于有符号值的二进制表示。我将描述它是如何工作的。

printf(“Raw: %02X\n”, signedChar);
可以写为(char)0xf0

(char)-16转换为(int)-16,其十六进制表示为0xfffffff0

printf(“Masked: %02X\n”, signedChar &0xff);

0xff属于int类型,因此在计算&之前,signedChar会转换为(int)-16((int)-16) & ((int)0xff) == (int)0x000000f0

printf(“Cast: %02X\n", (unsigned char)signedChar);
可以写为(unsigned char)0xf0

(unsigned char)240转换为(unsigned int)240为十六进制0x000000f0