class Address {
int i ;
char b;
string c;
public:
void showMap ( void ) ;
};
void Address :: showMap ( void ) {
cout << "address of int :" << &i << endl ;
cout << "address of char :" << &b << endl ;
cout << "address of string :" << &c << endl ;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
address of int : something
address of char : // nothing, blank area, that is nothing displayed
address of string : something
Run Code Online (Sandbox Code Playgroud)
为什么?
另一个有趣的事情:如果int,char,string是公共的,那么输出就是
... int : something
... char :
... string : something_2
Run Code Online (Sandbox Code Playgroud)
something_2 - something总是等于8. 为什么?(不是9)
hrn*_*rnt 82
当你拿到b的地址时,你得到了char *.operator<<将其解释为C字符串,并尝试打印字符序列而不是其地址.
试着cout << "address of char :" << (void *) &b << endl改为.
[编辑]像Tomek评论的那样,在这种情况下使用更合适的演员阵容static_cast,这是一个更安全的选择.这是一个使用它而不是C风格的强制转换的版本:
cout << "address of char :" << static_cast<void *>(&b) << endl;
Run Code Online (Sandbox Code Playgroud)
Cas*_*Cow 26
有两个问题:
打印指针将打印地址int*和string*,但不会对打印内容char*,因为在一个特殊的过载operator<<.如果你想要地址,那么使用:static_cast<const void *>(&c);
int和string是8在你的平台sizeof(int)是4和sizeof(char)是1让你真正应该问为什么8不5.原因是字符串在4字节边界上对齐.机器使用单词而不是字节,并且如果单词因此不是"分割"在这里的几个字节和那里的几个字节,则工作得更快.这称为对齐
您的系统可能与4字节边界对齐.如果您的64位系统具有64位整数,则差异为16.
(注意:64位系统通常是指指针的大小,而不是int.因此,具有4字节int的64位系统仍然会有8的差异,因为4 + 1 = 5但是最多为8如果sizeof(int)是8那么8 + 1 = 9但这最多可以达到16)
Ton*_*roy 13
当您将char的地址流式传输到ostream时,它会将其解释为ASCIIZ"C-style"字符串的第一个字符的地址,并尝试打印假定的字符串.您没有NUL终结器,因此输出将继续尝试从内存中读取,直到找到一个或操作系统关闭它以尝试从无效地址读取.它扫描的所有垃圾都将被发送到您的输出.
您可以通过投射来显示所需的地址,例如(void*)&b.
将偏移量重新放入结构中:您观察到字符串位于偏移量8.这可能是因为您有32位整数,然后是8位字符,然后编译器选择再插入3个8位字符,以便字符串对象将在32位字边界处对齐.许多CPU /内存架构需要指针,整数等在字大小的边界上对它们执行有效的操作,否则必须做更多的操作来从内存中读取和组合多个值,然后才能使用这些值在一次行动中.根据您的系统,可能每个类对象都需要从单词边界开始,或者std::string特别是可能需要以size_t,指针或需要这种对齐的其他类型开始.
peo*_*oro 10
因为当你传递char*给std::ostream它时,它将打印char*它所指向的C风格(即:char数组)字符串.
记住那"hello"是一个char*.
| 归档时间: |
|
| 查看次数: |
19382 次 |
| 最近记录: |