c++ - 打印值 0x89 (-119) 时出现奇怪的输出

标签 c++ c hex output

正如标题所说,运行以下代码时我得到了一个“奇怪”的结果:

#include <stdio.h>

int main()
{
    char buff[4] = {0x17, 0x89, 0x39, 0x40};
    unsigned int* ptr = (unsigned int*)buff;
    char a = (char)((*ptr << (0*8)) >> (3*8));
    char b = (char)((*ptr << (1*8)) >> (3*8));
    char c = (char)((*ptr << (2*8)) >> (3*8));
    char d = (char)((*ptr << (3*8)) >> (3*8));

    printf("0x%x\n", *ptr);
    printf("0x%x\n", a);
    printf("0x%x\n", b);
    printf("0x%x\n", c);
    printf("0x%x\n", d);

    return 0;
}

输出:

0x40398917
0x40
0x39
0xffffff89
0x17

为什么我没有得到 0x89

最佳答案

这是因为您的 char 变量是有符号的,并且它们在提升时正在进行符号扩展(在这种情况下升级为更宽的类型)。符号扩展是一种在进行此提升时保留符号的方法,因此无论是 8 位、16 位还是更宽的类型,-119 都保持为 -119

您可以通过显式使用 unsigned char 来修复它,因为至少在 C 中,char 是有符号的还是无符号的是特定于实现的。来自 C11 6.2.5 类型/15:

The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.

符号扩展不会对无符号类型发挥作用,因为它们,...嗯,无符号 :-)

关于c++ - 打印值 0x89 (-119) 时出现奇怪的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17438792/

相关文章:

c - C中的位域内存使用

c - 将从系统调用 open() 打开的文件传递给函数

assembly - 为什么DCPU-16指令的二进制表示中有一个前导1

javascript - 在 Javascript 中格式化十六进制

c++ - 检查单选按钮状态 winapi

c++ - 如何为 native C++(非托管)开发配置 Visual Studio?

C++:使用重载箭头 (->) 运算符的指针模板

c - 使用 termios 发送 AT 命令并获得回复的正确方法是什么

c++ - 用于私有(private)、 protected 和公共(public)元素的 Doxygen 自定义 CSS

php - PHP hexdec 的大十六进制值