c++ - 为什么 (int )'\xff' != 0xff 但 (int )'\x7f' == 0x7f?

标签 c++ byte

考虑这段代码:

typedef union
{
    int integer_;
    char mem_[4];
} MemoryView;

int main()
{
    MemoryView mv;
    mv.integer_ = (int)'\xff';
    for(int i=0;i<4;i++)
        std::cout << mv.mem_[i]; // output is \xff\xff\xff\xff

    mv.integer_ = 0xff;
    for(int i=0;i<4;i++)
        std::cout << mv.mem_[i]; // output is \xff\x00\x00\x00

    // now i try with a value less than 0x80
    mv.integer_ = (int)'\x7f'
    for(int i=0;i<4;i++)
        std::cout << mv.mem_[i]; // output is \x7f\x00\x00\x00


    mv.integer_ = 0x7f;
    for(int i=0;i<4;i++)
        std::cout << mv.mem_[i]; // output is \x7f\x00\x00\x00

    // now i try with 0x80
    mv.integer_ = (int)'\x80'
    for(int i=0;i<4;i++)
        std::cout << mv.mem_[i]; // output is \x80\xff\xff\xff

    mv.integer_ = 0x80;
    for(int i=0;i<4;i++)
        std::cout << mv.mem_[i]; // output is \x80\x00\x00\x00

}

我用 GCC4.6 和 MSVC2010 测试了它,结果是一样的。 当我尝试使用小于 0x80 的值时,输出是正确的,但使用大于 0x80 的值时, 左边三个字节是'\xff'。

CPU:英特尔“酷睿 2 双核” 字节顺序:小 操作系统:Ubuntu 12.04LTS(64 位)、Windows 7(64 位)

最佳答案

类型 char有符号还是无符号特定于实现的。


char 类型的变量分配 0xFF 的值可能会产生 255(如果类型真的是 unsigned) 或 -1(如果类型确实是 signed)在大多数实现中(其中 char 中的位数是 8)。

小于或等于 0x7F (127) 的值将适合 unsigned charsigned char 这解释了为什么您会得到所描述的结果。


#include <iostream>
#include <limits>

int
main (int argc, char *argv[])
{
  std::cerr << "unsigned char: "
            << +std::numeric_limits<unsigned char>::min ()
            << " to "
            << +std::numeric_limits<unsigned char>::max ()
            << ", 0xFF = "
            << +static_cast<unsigned char> ('\xFF')
            << std::endl;

  std::cerr << "  signed char: "
            << +std::numeric_limits<signed char>::min ()
            << " to "
            << +std::numeric_limits<signed char>::max ()
            << ", 0xFF = "
            << +static_cast<signed char> ('\xFF')
            << std::endl;
}

典型输出

unsigned char: 0 to 255, 0xFF = 255
  signed char: -128 to 127, 0xFF = -1

为了避免您遇到的问题,请将您的变量显式声明为 signedunsigned,在本例中,将您的值转换为 unsigned char 就足够了:

mv.integer_ = static_cast<unsigned char> ('\xFF'); /* 255, NOT -1 */

旁注: 当读取一个union 的成员时,您正在调用未定义的行为,而该成员不是您写信给的最后一个成员。该标准没有指定在这种情况下会发生什么。当然,在大多数实现中它会按预期工作。访问 union.mem_[0] 很可能会产生 union.integer_ 的第一个字节,但这并不能保证。

关于c++ - 为什么 (int )'\xff' != 0xff 但 (int )'\x7f' == 0x7f?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17896321/

相关文章:

c++ - boost 程序选项短/长参数名称

c++ - Clang、LLVM 和 g++

C# 如何在偏移处写入一个字节?

c - 带有两个 0x00 字节前缀的 unsigned char 指针数组

java - 从 2 或 4 个字节转换为有符号/无符号短整型

c++ - 如果 switch 语句达到默认值,则重复 do while 循环

c++ - 如何调试 .pc 文件?

c++ - 从包含多行的文本文件中读入 float 变量的代码

java - 如何将保存的指纹字节转换为图像

python - 具有非标准字符到 int 的十六进制转储(字节数组)