理解Endianness - 变量值

时间:2012-01-05 13:17:45

标签: c++ endianness

我正在使用一段代码(在本网站的其他位置找到)在运行时检查字节顺序。

static bool isLittleEndian()
{
  short int number = 0x1;
  char *numPtr = (char*)&number;

  std::cout << numPtr << std::endl;
  std::cout << *numPtr << std::endl;

  return (numPtr[0] == 1);
}

在调试模式下,numPtr值如下所示:0x7fffffffe6ee "\001"

我假设第一个十六进制部分是指针的内存地址,第二部分是它保存的值。我知道\ 0在旧式C ++中是空终止,但为什么它在前面呢?是否与字节序有关?
在小端机器上:01第一个字节,因此最低有效位(字节位置0),\ 0第二个字节/最后一个字节(字节位置1)?

此外,cout语句不会打印指针地址或它的值。原因是什么?

7 个答案:

答案 0 :(得分:2)

其他人已经明确回答了"\000"的含义,所以这是对你问题的回答:

  

在小端机器上:01第一个字节,因此最低有效位(字节位置0),\ 0第二个字节/最后一个字节(字节位置1)?

是的,这是正确的。你看看像0x1234这样的值,它由两个字节组成,高位部分0x12和低部分0x34。术语“小端”意味着低位部分首先存储在存储器中:

addr:   0x34
addr+1: 0x12

您是否知道术语“endian”早于计算机行业?它最初由Jonathan Swift在他的书“ Gulliver's Travels 中使用,其中描述了人们是从尖头还是圆头吃蛋。”

答案 1 :(得分:1)

检查字节顺序的最简单方法是让系统为您执行此操作:

if (htonl(0xFFFF0000)==0xFFFF0000) printf("Big endian");
else printf("Little endian");

答案 2 :(得分:1)

那不是\0后跟“01”,它是单个字符\001,表示八进制中的数字1。这是你的字符串中的唯一字节。它后面有另一个字节,值为零,但你没有看到它,因为它被视为字符串终止符。

答案 3 :(得分:1)

对于初学者:这种类型的功能完全没用:在机器上 其中sizeof(int)为4,有24个可能的字节顺序。大多数 当然,没有意义,但我已经看过至少三个。和endianness 并不是影响整数表示的唯一因素。如果你有 一个int,您希望得到低位8位,使用intValue & 0xFF,用于接下来的8位(intValue >> 8) & 0xFF

关于你的确切问题:我假设你在描述什么 因为“看起来像这样”是你在调试器中看到的,当你突破时 回报。在这种情况下,numPtrchar*(一个unsigned char const*会更有意义),因此调试器采用C样式 串。 0x7fffffffe6ee是地址;接下来是什么 编译器看作C样式字符串,它显示为字符串,即 "..."。据推测,您的平台是传统的小端 (英特尔);指向C样式字符串的指针可以看到序列(数字 价值)1, 00当然等同于'\0',所以它 认为这是一个字符串,其中一个字符具有 编码1.没有可编码的可打印字符 一,它不对应任何正常的转义序列 (例如'\n''\t'等)。所以调试器使用它输出它 八进制转义序列,'\'后跟1到3个八进制数字。 (传统的'\0'只是一个特殊情况;后面是'\' 由一个八进制数字。)它输出3位数,因为(可能) 它不希望向前看以确保下一个角色不是 八进制数字。 (例如,如果序列是两个字节1, 49, 在通常的编码中,49是'1',如果它只输出一个字节 对于八进制编码为1,结果为“\ 11”,即a 单个字符串 - 对应于通常的编码 '\t'。)所以你得到"这是一个带有第一个字符的字符串\001 编码为1(并且没有可显示的表示)," 那是字符串的结尾。

答案 4 :(得分:0)

您看到的"\001"只是一个字节。它可能是八进制表示法,需要三位数才能正确表达(十进制)0到255之间的值。

答案 5 :(得分:0)

\ 0不是NUL,调试器显示numPtr为字符串,其第一个字符是\ 001或控制-A的ASCII。第二个字符是\ 000,由于在显示字符串时未显示NUL,因此不显示该字符。 'number'的两个字符串版本在big-endian机器上显示为“\ 000 \ 001”,而不是像小端机器上显示的“\ 001 \ 000”。

答案 6 :(得分:0)

  

另外,cout语句不打印指针地址或   它的价值。原因是什么?

因为在打印时,字符和字符指针的处理方式与整数不同。

当您打印字符时,它会从正在使用的任何字符集中打印字符。通常,这是ASCII,或ASCII的一些超集。 ASCII中的值0x1是非打印的。

当你打印一个字符指针时,它不会打印地址,而是将它打印为以空字符结尾的字符串。

要获得所需的结果,将char指针转换为void指针,并将char转换为int。

std::cout << (void*)numPtr << std::endl;
std::cout << (int)*numPtr << std::endl;