我无法理解此指针代码中(void *)的使用。
std::cout<< "address character = " << (void *) &givenChar<<"\n\n";
答案 0 :(得分:4)
首先,您需要知道地址运算符&
的作用。对于&givenChar
,它返回一个指向变量givenChar
的指针。假设givenChar
为char
类型,那么&givenChar
将为char*
类型。
使用格式化的输出运算符<<
时,传递char*
会将指针视为指向零终止字符串的第一个字符的指针,并将打印该字符串。如果要打印实际的 pointer (而不是它指向的字符串),则需要将指针转换为类型为void*
的通用无类型指针。
这就是cast的原因:为了能够打印指向字符的实际指针。
答案 1 :(得分:2)
您未告知我们givenChar
是什么类型。根据名称,它必须为char
。在这种情况下,表达式&givenChar
的类型为char*
。如果按原样使用它,那么将选择参数类型为const char*
的重载流运算符,该运算符将被视为指向以C空终止的字符串的指针。这是不正确的,因为&givenChar
是指向单个字符的指针,并导致未定义的行为。表达式(void *) &givenChar
强制编译器选择参数类型为const void*
的重载流运算符,该运算符将打印指针中包含的地址。
答案 2 :(得分:1)
无效指针只是存储任何内存地址的变量。指针值只是一个内存地址。所有内存地址都是一定大小的,因此让我们有一个通用的数据类型,它可以存储任何对象的地址。
&givenChar
返回变量givenChar
所在的内存地址。如果变量的数据类型为char
,则返回的内存地址的数据类型为char*
。然后,我们将该char*
值转换为void*
数据类型。然后将类型转换的结果打印到屏幕上。
如果您有一个char*
值,则可以取消引用它以获得指向的char
。这很容易记住:取消引用星星“ *
”。但是,由于void*
可以存储任何数据类型的内存地址,因此我们无法取消引用它,因为我们不知道该值以前是char*
还是int*
,或者甚至没有std::string*
转换成void*
之前。这很重要,因为不同的数据类型在内存中具有不同的大小和不同的表示形式。这就是为什么我们不能取消引用void*
的原因,我们只是不知道它曾经指向什么。
答案 3 :(得分:0)
在这种情况下,需要打印字符地址,这就是为什么使用&givenChar
获取givenChar
地址的原因。再次将其强制转换为(void *)
,以便调用适当的重载来打印地址,而不将其视为char*
至Null
终止的字符串。
此外,如果我们深入了解它,指向void
的指针是一种“通用”指针类型。 void *
可以转换为任何其他指针类型,而无需显式强制转换。您不能取消引用void *
或对其进行指针算术;您必须先将其转换为指向完整数据类型的指针。
它用于需要在同一代码中使用不同指针类型的地方。一个经常引用的示例是库函数qsort
:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
base
是数组的地址,nmemb
是数组中元素的数量,size
是每个元素的大小,compar
是指针一个比较数组两个元素的函数。它的调用方式如下:
int iArr[10];
double dArr[30];
long lArr[50];
...
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt);
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble);
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong);
在函数调用中,数组表达式iArr, dArr, and lArr
被隐式地从数组类型转换为指针类型,并且每个表达式都被隐式地从“ pointer to int/double/long
”转换为“ pointer to void
”。
比较功能类似于:
int compareInt(const void *lhs, const void *rhs)
{
const int *x = lhs; // convert void * to int * by assignment
const int *y = rhs;
if (*x > *y) return 1;
if (*x == *y) return 0;
return -1;
}
通过接受void *
,qsort
可以使用任何类型的数组。
使用void *的缺点是您将类型安全性扔出了窗外,迎面而来。没有什么可以保护您避免使用错误的比较例程:
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);
compareInt
期望其参数指向int
,但实际上正在与double
使用。在编译时没有办法解决这个问题。您会发现数组排序错误。