16

我正在尝试将无符号字符值打印为 2 位十六进制值,但总是将结果作为 4 位十六进制值,不确定我的代码有什么问题。

// unsigned char declaration
unsigned char status = 0x00;
// printing out the value 
printf("status = (0x%02X)\n\r", (status |= 0xC0));

我期待 2 位十六进制结果为0xC0,但我总是得到0xC0FF

同样,当我尝试使用%bu格式标识符将相同的变量(状态)打印为无符号字符时,我得到的输出为255.

你如何得到两个十六进制字符作为输出?

4

4 回答 4

29

据我所知,Keil C 编译器并不完全符合 C 标准。如果是这样,它很可能没有完全遵循标准的提升规则,比如将char值传递给可变参数函数;在 8 位 CPU 上,不自动将 8 位值扩展到 16 位或更多位具有性能优势。

作为一种解决方法,您可以在将参数传递给printf. 尝试这个:

#include <stdio.h>

int main(void) {
    unsigned char status = 0x00;
    status |= 0xC0;

    printf("status = 0x%02X\n", (unsigned int)(status & 0xFF));
    return 0;
}

用按位“与”0xFF清除除底部 8 位以外的所有位;unsigned int 不需要强制转换为,但它保证参数实际上是printf格式"%02X"所期望的类型。

您还应该查阅您的实现文档,了解关于类型提升和printf.

于 2012-09-10T03:13:57.267 回答
7

您正在将 char 发送到需要 int 的格式字符串。printf 函数正在从堆栈中抓取另一个字节来填充它。尝试

 printf("%02X",(int)(status|0xC0));
于 2012-09-10T02:49:15.367 回答
4

查看所有答案,我认为我们可能缺少另一种方法。

const unsigned char chararr[]="abceXYZ";
for (int i=0; i< 7; ++i) {
    printf("%#04X %d %c\n", chararr[i], chararr[i], chararr[i]);
}
0X61 97 a
0X62 98 b
0X63 99 c
0X65 101 e
0X58 88 X
0X59 89 Y
0X5A 90 Z

如果你使用 %#04x small x 那么输出将是 b 0x small x 前缀。# 井号告诉函数打印 0x。04 指示要输出多少位,如果输入是'0x0a',它将打印这个,没有04它将打印'0xa'。

在我的电脑戴尔工作站中,输出与问题所预期的一样。除非

unsigned char status = 0x00;
printf("status = (0x%02X)\n\r", (status |= 0xC0));
// output
//status = (0xC0)
// is exactly expected by the original question. 

通过示例更好地说明:

 37    printf("status = (%#02x)\n", (status |= 0xC0));
 38    printf("status = (%#04x)\n", (status |= 0xC0));
 39    printf("status = (%#04x)\n", 0x0f);
 40    printf("status = (%#02x)\n", 0x0f);
status = (0xc0)
status = (0xc0)
status = (0x0f)
status = (0xf)
于 2019-01-20T18:34:15.753 回答
1

将其转换为无符号字符:

printf("status = (0x%02X)\n\r", (unsigned char)(status |= 0xC0));
于 2012-09-10T02:49:22.297 回答