为什么在有和没有取消引用指针的情况下获得相同的值

时间:2016-01-09 09:19:24

标签: c++ pointers

以下代码:

int number = 65;
char *ptr = reinterpret_cast< char* >(&number);
cout << *ptr << endl;

*ptr打印Aptr打印A。为什么他们都打印相同的结果?

2 个答案:

答案 0 :(得分:4)

流正在重载<<,因此无论如何都会隐式地为char完成解除引用。

更具体地说:由于char *是C的stringostream会尝试读取它,即它取消引用指针并读取char s直到找到它为止一个零字节。 (这仅适用于正确的Endianness。)

考虑以下代码:

#include <iostream>

int main(void) {
        char c = 'A';
        int  i = 66;
        std::cout <<  c << '\n';
        std::cout << &c << '\n';
        std::cout <<  i << '\n';
        std::cout << &i << '\n';
        return 0;
}

在我的机器上(不是全部!)打印

A
AB
66
0x7fff0d1db1bc

因为c打印正确,但&c被解释为字符串。但是c不是以空值终止的,因此ostream继续读取,找到i的第一个字节,然后最后一个空字节,因为i的值太小了,我们只使用其四个字节中的一个。

但是,i&i按预期打印。此行为仅针对char实现,因为对其他类型没有意义。

答案 1 :(得分:1)

两者都打印相同的结果,因为:

  1. ostream::operator<<包含char*char的重载(请参阅herehere)。
  2. char*重载将参数解释为指向null-terminated byte string的指针,而不是指向单个char的指针。
  3. 显然您的计算机为little endian并且sizeof(char) < sizeof(int)(与==相对)。这意味着number占用的内存在被解释为char的数组时,是值{65的char,后跟一个或多个空char。因此,当number被解释为以空字符结尾的字节字符串时,它包含值为65的单个字符。
  4. 因此,当您流式*ptr char时,char重载会打印出指向的值为65的字符。当您流式传输ptr时,在char*类型中,char*重载打印指向的以空字符结尾的字节字符串,其中包含值为65的单个字符,因此再次打印单个字符。

    关于第3点的进一步说明:

    请注意,给定sizeof(char) < sizeof(int),您可以保证得到一个以空字符结尾的字节字符串,其中只有一个字符,因为CHAR_BITat least 8。即值65不可能不适合单个char

    也许你的机器有sizeof(char) == sizeof(int)(在这种情况下,endianess无关紧要),number之后的内存是空字符只是巧合,再次构建一个看起来像是以null结尾的字节字符串。我说看起来像是因为只有你被允许读取终止空字符才真的是一个。由于大多数系统CHAR_BIT为8(required by POSIX},并且由于标准要求intat least 32 bits,因此您的计算机极不可能sizeof(char) == sizeof(int) }。