这些代码行显示如下错误:
int e = 5, * ePtr = &e;
void * vPtr = ePtr;
cout << *vPtr;
语法错误:
`void *'不是指向对象的指针类型
我知道:
但如果我们不能做#2点,除了语法正确之外,点#1的用途是什么?我想使用e
打印5(即vPtr
} ..这可能吗?
这很好用:
int e = 5, * ePtr = &e;
void * vPtr = ePtr; //specific to generic Ok!
double * dPtr = (double *)vPtr; //to let compiler know stoarge size
cout << *dPtr; //indirectly it is vPtr i.e. a void ptr, can be deref only if cast
答案 0 :(得分:5)
要使用void*
指针,需要将指针强制转换为兼容类型。
void*
指针经常在C中使用,但是,因为在C ++中我们可以执行函数重载和多态,它们的使用更加有限。
在C中使用void*
指针的一个很好的例子是使用回调的函数:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
当你调用pthread_create函数时,它会调用你的start_routine
。
在这种情况下,您可能希望将一些数据传递给start_routine
。由于线程库无法为您回调的每种类型声明pthread_create函数,因此使用void*
类型。
void myCallBack(void* arg) {
int* value = (int*)arg;
/* Do something with value: it is an int* now*/
printf("Message from callback %d\n", *value);
}
/* Some main function or whatever... */
{
/* ... */
int foo = 123;
ret = pthread_create(&thread, &attr,myCallBack, &foo);
/* ... */
}
答案 1 :(得分:4)
void*
可以指向任何东西,因此分配任何指针都非常好。
但是因为它可能指向任何东西,所以取消引用它是不可能的:编译器不知道它指向哪个对象类型,因此它无法生成代码来执行正确的事情,具体取决于对象的类型。
答案 2 :(得分:3)
你不能取消引用它,因为编译器不知道它是什么。你必须将它转换为适当的类型(并且编译器必须假设你知道你在做什么)。
void *
指针最适合用于与相当低级别的东西(例如I / O驱动程序)接口,在那里你很少关心你正在处理的数据,你只知道你有一个缓冲区和大小。
任何其他用途都充满了危险。例如
int i = 5;
void *p = &i;
.....
float *f = (float *)p;
这将不会出现编译器错误或警告。这完全有效。但它不太可能达到你的期望
答案 3 :(得分:2)
存储指针并对其类型保持无关紧要可能很有用。这就是void *的用途。在纯C中设计存储容器(链表,哈希映射)时,您可以采用这种方法。
如果你想使用指针,那么你必须跟踪它的类型及其值,因为你不能随意地引用指针,并且当你转换为void *时,所有的类型信息都会丢失。
在您的示例中,您可以使用带有void *和类型字段的简单结构。
在C ++中,您可以使用多态结构甚至模板来实现这些目标:您正在做的更多是C风格。
答案 4 :(得分:1)
如果没有进行类型转换,则无法使用e
在此处打印void*
。
指针不仅仅是一个存储地址的简单变量,但它也有一个类型,它告诉编译器使用该地址读取的大小。没有类型转换的void*
因为没有任何类型而无法解除引用。通过类型转换,您可以告诉编译器应该从指针携带的地址开始读取多少字节。
void*
为程序员提供了一种轻松存储和使用其他类型指针的简便方法。我们不能使用unsigned int
或类似的来存储指针的值,因为指针的大小取决于处理器。此外,我们可以使用void*
使指针参数/函数的返回值更通用。
答案 5 :(得分:0)
我确实要将int指针存储到void *指针。 在那种情况下,您可能会收到警告,例如“从不同大小的整数转换为指针”。为此您首先需要指定一些与整数相关的内存void指针,然后使用该void指针可能如下,
void *ptr = malloc(sizeof(int));
*((int*)ptr) = 5;
printf("%d\n",*((int*)ptr));