此代码......
#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
答案 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'
在你的情况下,你很幸运,在变量'c'之后恰好在内存中存在一个空字符。
在你的情况下,你很幸运,在变量'b'之后恰好在内存中存在一个空字符。但变量'b'也被解释。
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。