为什么包含未使用的bool会影响char的引用?

时间:2011-08-11 12:30:19

标签: c++ g++

此代码......

#include <iostream>

int main(int argc, char * argv[])
{
    char c = 'A';
    std::cout << &c;
    return 0;
}

...在Eclipse调试模式和命令行中正确输出“A”。

但是,当我将代码修改为...

#include <iostream>

int main(int argc, char * argv[])
{
    char c = 'A';
    bool b = true;
    std::cout << &c;
    return 0;
}

...它在Eclipse调试模式和Windows 7命令行中输出“A␁”(拉丁字母'A'后跟'标题的开头'ASCII控制字符)。顺便说一下,当使用bool b = false时,我没有得到␁字符。

我知道␀的值为0,␁的值为1,但为什么cout << &c会受到布尔的影响?任何人都可以解释为什么会这样吗?

编辑:忘记添加我的环境:Eclipse Indigo中的Windows 7 64位,带G ++ 4.5.2的MinGW

4 个答案:

答案 0 :(得分:8)

&c未传递对c的引用,它正在传递c的地址。也就是说,您将char*传递给operator<<。该函数将从&c开始遍历内存,并在找到\0时结束。

因为你没有以空字符结尾的字符串,所以当函数走过c内存的末尾时,你正在调用未定义的行为。

您是否尝试过以下操作?

#include <iostream>

int main(int argc, char * argv[])
{
    char c = 'A';
    std::cout << c << std::endl; // no & needed.
    return 0;
}

答案 1 :(得分:8)

在第一个版本中,您将获得(非)幸运。

在第二个中你得到(非)幸运(它不会崩溃)但它会打印更多垃圾。

当你使用&amp;在char对象上你得到一个char *。当您尝试流式传输char *时,它对所有其他指针(通常打印地址)的行为方式不同。但是char *被假定为C-String。 C-String是由空字符'\ 0';

终止的字节序列

实际发生的是它正在打印每个内存位置(将其视为char)从变量'c'开始并在内存中移动直到找到字符'\ 0'

上面的示例1:

在你的情况下,你很幸运,在变量'c'之后恰好在内存中存在一个空字符。

上面的例子2:

在你的情况下,你很幸运,在变量'b'之后恰好在内存中存在一个空字符。但变量'b'也被解释。

  • 当'b'的值为false时:转换为char,这是'\ 0'(同样的事情)。所以只打印字母'A'。
  • 当'b'的值为true时:转换为char,这是'\ 01'。不是'\ 0'所以它被打印出来。你很幸运,下一个字节是'\ 0',打印停止。

你真正想做的是:

std::cout << c; // prints a character

或者您可以创建一个字符串:

char const* c = "A";  // Creates a null terminated C-String. Note the double quotes " "

或者获取地址

std::cout << static_cast<void*>(&c); // All other pointer types will print the address
                                     // Of the standard types only char* is treated 
                                     // differently with its own overload.

答案 2 :(得分:5)

假设char*指向C样式字符串(零终止),而不是单个字符。

如果要显示地址(指针值),请尝试

cout << static_cast<void*>(&c);

答案 3 :(得分:4)

简短回答operator<<传递char的地址,并假定它是null终结字符串中第一个char的地址。除了偶然之外,它不是。代码有UB。