为什么`(void *)&`获取变量的地址?
Why does `(void *)&` get the address of the variable?
谁能解释一下这背后的逻辑?为什么 void
?例如
#include <iostream>
using namespace std;
int main()
{
char c;
cout << (void *)&c;
return 0;
}
cout << (void *)&c;
获取c
的地址,然后将其转换为void*
,然后打印指针。
这里的目的是打印变量c
的地址。但是当将 char *
传递给 std::cout <<
时,它将尝试打印一个以 null 结尾的字符串。为避免这种情况(并打印实际地址),您必须先转换为 void*
。
更多解释:
std::ostream::operator<<
具有处理 char *
和 const char*
的 overload (2)。它假定 const char*
将指向某个最终由空字符 '[=21=]'
终止的字符串。这只是 C 和 C++ 中使用的约定。
您想避免这种情况,而是使用 overload (7) 打印地址。
Why does (void *)&
get the address of the variable?
一元&
是addressof运算符。 addressof 运算符获取操作数的地址,因为这是该运算符的目的。
Why void?
因为
&c
的类型为char*
,该类型的指针在输出流中被当做指向空终止字符串的指针,处理方式不同来自所有其他指针。具体来说,将输出字符串的内容。将不是指向空终止字符串的指针的 char*
插入到字符流中会导致未定义的行为。 &c
不是指向空终止字符串的指针。将另一种类型的指针插入字符流将导致输出地址的数字表示形式。
该示例将 &c
转换为另一种指针类型,这样它就不会被视为空终止字符串。
所有的对象指针都可以转换成void*
,所以也就是通常选择的输出字符地址的指针类型
关于更多细节,字符流插入运算符有重载:
operator<<(ostrea&, const char*);
operator<<(ostrea&, const void*); // I'm cheating a bit
// this is technically a member overload
So would I need to convert it to void* when and only when a variable is NULL?
完全没有。变量 c
不为空。而一个指针是否为null对是否需要转换为void*
.
没有影响
另请注意,终止空终止字符串的空终止符不是空指针。空指针不是指向空终止符的指针。这些是完全不同的概念。
operator <<
为类型 char *
的对象重载,这样它输出字符就好像使用的指针是指向 C 字符串(序列)的第一个字符的指针以零字符终止的字符数 '[=14=]'
).
并且没有强制转换的表达式 &c
的类型为 char *
。因此运算符假定传递的指针表达式 &c
提供指向 C 字符串的指针。
要输出对象 c
的地址,您需要将表达式 &c
转换为类型 void *
.
这是一个演示差异的简单程序。
#include <iostream>
int main()
{
const char *s = "Hello";
std::cout << s << '\n';
std::cout << static_cast<const void *>( s ) << '\n';
return 0;
}
程序输出为
Hello
0x5598fd4a3004
谁能解释一下这背后的逻辑?为什么 void
?例如
#include <iostream>
using namespace std;
int main()
{
char c;
cout << (void *)&c;
return 0;
}
cout << (void *)&c;
获取c
的地址,然后将其转换为void*
,然后打印指针。
这里的目的是打印变量c
的地址。但是当将 char *
传递给 std::cout <<
时,它将尝试打印一个以 null 结尾的字符串。为避免这种情况(并打印实际地址),您必须先转换为 void*
。
更多解释:
std::ostream::operator<<
具有处理 char *
和 const char*
的 overload (2)。它假定 const char*
将指向某个最终由空字符 '[=21=]'
终止的字符串。这只是 C 和 C++ 中使用的约定。
您想避免这种情况,而是使用 overload (7) 打印地址。
Why does
(void *)&
get the address of the variable?
一元&
是addressof运算符。 addressof 运算符获取操作数的地址,因为这是该运算符的目的。
Why void?
因为
&c
的类型为char*
,该类型的指针在输出流中被当做指向空终止字符串的指针,处理方式不同来自所有其他指针。具体来说,将输出字符串的内容。将不是指向空终止字符串的指针的char*
插入到字符流中会导致未定义的行为。&c
不是指向空终止字符串的指针。将另一种类型的指针插入字符流将导致输出地址的数字表示形式。该示例将
&c
转换为另一种指针类型,这样它就不会被视为空终止字符串。所有的对象指针都可以转换成
void*
,所以也就是通常选择的输出字符地址的指针类型
关于更多细节,字符流插入运算符有重载:
operator<<(ostrea&, const char*);
operator<<(ostrea&, const void*); // I'm cheating a bit
// this is technically a member overload
So would I need to convert it to void* when and only when a variable is NULL?
完全没有。变量 c
不为空。而一个指针是否为null对是否需要转换为void*
.
另请注意,终止空终止字符串的空终止符不是空指针。空指针不是指向空终止符的指针。这些是完全不同的概念。
operator <<
为类型 char *
的对象重载,这样它输出字符就好像使用的指针是指向 C 字符串(序列)的第一个字符的指针以零字符终止的字符数 '[=14=]'
).
并且没有强制转换的表达式 &c
的类型为 char *
。因此运算符假定传递的指针表达式 &c
提供指向 C 字符串的指针。
要输出对象 c
的地址,您需要将表达式 &c
转换为类型 void *
.
这是一个演示差异的简单程序。
#include <iostream>
int main()
{
const char *s = "Hello";
std::cout << s << '\n';
std::cout << static_cast<const void *>( s ) << '\n';
return 0;
}
程序输出为
Hello
0x5598fd4a3004