我运行以下代码:
#include <iostream>
using namespace std;
typedef struct Test
{
char a;
char b;
int i;
double d;
}Test;
int main()
{
Test test;
test.a = 'a';
test.b = 'b';
test.i = 478;
test.d = 4.7;
cout << &test.a << '\n'
<< &test.b << '\n'
<< &test.i << '\n'
<< &test.d << '\n';
return 0;
}
输出结果为:
ab@
b@
0x28fe94
0x28fe98
起初,我认为这是&
和.
之间优先的结果。
但是0x28fe94
和0x28fe94
表明它不是优先问题
我可以弄清楚ab@
和b@
是什么意思?
答案 0 :(得分:5)
写作时
cout << &test.a
因为test.a
是char
,这会调用operator<< (ostream&, const char*)
重载,认为你的char*
是指向C风格字符串的指针,而不是指向只有一个角色。因此,操作将从&test.a
的存储器地址开始读取字节,直到找到空终止符(零字节)。打印出ab@
时会发生这种情况,因为a
的值为'a'
,b
的值为'b'
,而系统上的数字478恰好对应到一个@
字符,最后是一个空字节。
如果您想查看test.a
和test.b
的数字地址,请将指针转换为void*
s,这将选择operator<< (ostream&, const void*)
重载。例如:
cout << static_cast<void*>(&test.a)
希望这有帮助!
答案 1 :(得分:3)
这意味着未定义的行为。 const char *
有一个特殊的重载,它将它打印为以null结尾的字符串。你的没有终结者,所以它超越并触发了前面提到的UB。修复它:
std::cout << static_cast<void *>(&test.a) << '\n'
<< static_cast<void *>(&test.b) << '\n'
<< &test.i << '\n'
<< &test.d << '\n';
答案 2 :(得分:1)
因为您在使用&test.a
和&test.b
时传递了字符的地址,所以cout
运算符将地址视为字符串的开头。这就是您首先获得ab@
然后b@
的原因。 @
不太明显;它落在两个char
值之后和结构中int
值之前的填充中,并且是准随机垃圾。您实际上是在调用未定义的行为,因为您要求输出代码访问填充。如果要打印地址,请转换为void *
。如果要打印字符,请不要提供地址。