今天,当我阅读别人的代码时,我看到类似的含义,分别对函数名称和变量类型意味着void *func(void* i);
什么void*
?
另外,什么时候需要使用这种指针以及如何使用它?
malloc
和获得提示calloc
。手册页上继续说:“ ...返回一个指向已分配内存的指针,该指针适合任何内置数据类型。”
今天,当我阅读别人的代码时,我看到类似的含义,分别对函数名称和变量类型意味着void *func(void* i);
什么void*
?
另外,什么时候需要使用这种指针以及如何使用它?
malloc
和获得提示calloc
。手册页上继续说:“ ...返回一个指向已分配内存的指针,该指针适合任何内置数据类型。”
Answers:
指向的指针void
是“通用”指针类型。void *
可以将A 转换为任何其他指针类型,而无需显式强制转换。您不能取消引用a 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
以及lArr
隐式从数组类型转换为在函数调用指针类型,并且每个被隐式地从“指针转换int
/ double
/ long
”到“指针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
s,但实际上与double
s 一起使用。在编译时没有办法解决这个问题。您将得到一个错误排列的数组。
void*
可以将a强制转换为函数指针。但是对于数据指针,您所说的成立。
void*
是“在不假设存储了哪种类型的情况下指向内存的指针”。例如,如果要向函数传递参数,则可以使用该参数,并且该参数可以具有多种类型,在函数中,您将处理每种类型。
您可以在http://www.cplusplus.com/doc/tutorial/pointers/中查看有关指针的文章,并阅读以下章节:无效指针。
这也适用于C语言。
指针的void类型是一种特殊的指针。在C ++中,void表示不存在类型,因此void指针是指向没有类型的值的指针(因此,其长度也不确定,而解除引用的属性也不确定)。
这允许空指针指向任何数据类型,从整数值或浮点数到字符串。但是作为交换,它们具有很大的局限性:它们所指向的数据不能直接取消引用(这是逻辑上的,因为我们没有要取消引用的类型),因此,我们总是必须将地址转换为指向指针的void指针。在取消引用之前,其他一些指向具体数据类型的指针类型。
空指针称为通用指针。我想用一个示例pthread场景来解释。
线程函数的原型为
void *(*start_routine)(void*)
pthread API设计人员考虑了线程函数的参数和返回值。如果这些东西是通用的,我们可以在发送参数时将强制类型转换为void *。同样,可以从void *中检索返回值(但是我从未使用过线程函数的返回值)。
void *PrintHello(void *threadid)
{
long tid;
// ***Arg sent in main is retrieved ***
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
//*** t will be type cast to void* and send as argument.
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
pthread_exit(NULL);
而不是return 0;
在main结尾?
这意味着指针,您可以使用此链接来获取有关指针的更多信息 http://www.cprogramming.com/tutorial/c/lesson6.html