C++ 为什么这些变量的地址打印为ab@和b@?

C++ 为什么这些变量的地址打印为ab@和b@?,c++,memory-address,C++,Memory Address,我运行以下代码: #include <iostream> using namespace std; typedef struct Test { char a; char b; int i; double d; }Test; int main() { Test test; test.a = 'a';

我运行以下代码:

    #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;
    }
起初,我认为这是
&
之间优先级的结果
但是
0x28fe94
0x28fe94
表明这不是优先级问题。

我能弄清楚
ab@
b@
是什么意思?

它意味着未定义的行为。
const char*
有一个特殊的重载,它将其打印为以null结尾的字符串。你的没有终结者,所以它超越并触发前面提到的UB。用石膏固定:

std::cout << static_cast<void *>(&test.a) << '\n'
          << static_cast<void *>(&test.b) << '\n'
          << &test.i << '\n'
          << &test.d << '\n';
std::cout当你写

 cout << &test.a

希望这有帮助

因为在使用
&test.a
&test.b
时传递的是字符的地址,
cout
运算符将地址视为字符串的开头。这就是为什么您首先获得
ab@
,然后获得
b@
@
不太明显;它位于结构中两个
char
值之后和
int
值之前的填充中,是准随机垃圾。实际上,您正在调用未定义的行为,因为您要求输出代码访问填充。如果要打印地址,请强制转换为
void*
。如果要打印字符,请不要提供地址。

如果字段是给定的数值,这真的是未定义的行为,还是未指定的行为?@templatetypedef,我在Coliru上得到了不同的输出,所以有一个开始。其他成员可能会发生一些事情,但据我所知,只要它们按顺序出现(似乎不包括这种行为),它们就可以重新排列,因此从技术上讲,它可以是最后一个,从最大到最小,并且可以有填充,我不确定这是否需要0字节。不妨提及非ASCII的可能性,但你已经知道了。不过,我完全同意您对实际发生的情况的解释。@templatetypedef:无法保证结构打包(事实上,考虑到使用的数据类型,这不太可能),因此在假定的ASCIIZ字符串流传输期间首次读取的字段之间可能存在未初始化的内存。。。不是所有未初始化的读取都有未定义的行为吗?我得再检查一下标准。只有当CPU支持写入机器字中的特定字节,并且编译器使用这些指令时,才可能产生影响,但这不是一个荒谬的假设。
 cout << &test.a
cout << static_cast<void*>(&test.a)