void
,很常见,理解为空我自己认为没什么不妥(一般函数定义时只使用()
其实并不能代表(void)
,前者是可以空,后者是必须空)
void*
,库函数也算常见,我自己没用过,之间一直理解为空指针,这两天才知颇有偏差,其实它叫通用指针,只是在未初始化时候是空的,一旦初始化后再叫空指针肯定就别扭了,毕竟内容已经不空了,空的是指针类型,而不是指针值。
- 什么是通用指针?
顾名思义,就是通用的指针,本身没有类型,类型为空,内容可以不空,任何其他指针都能赋值给它,而不会有警告,所以叫通用指针(在gcc11.2中,它赋值给其他指针也不会警告,但不要这样使用)。
因为类型特殊,所以引用的时候要强转为对应的类型后再引用,赋值的时候虽然也可以直接赋值给实际的同类型指针(gcc11.2这样做默认没有任何警告,clangd LSP服务器也检查不到错误),但不建议这么做。强制转换可以触发编译器的指针类型赋值时的类型检查,所以最好都在使用前强转,如下是一个示例程序和运行结果:
#include "stdio.h"
#include "stdlib.h"
int main(void)
{
char a = 2;
char *p = &a;
void* vp = NULL;
char *pc = NULL;
vp = p; //char*指针直接赋值给通用指针
*(char*)vp = 1; //通用指针强转后也可以引用
p = (char*)vp; //其实直接赋值也可以,但强转后更安全,否则没有指针赋值的类型检查
printf("%d, %d",*(char*)vp, *p); //打印时可以看到通用指针引用正常
pc = (char*)malloc(100*sizeof(char)); //返回的通用指针通常都做了强制转换,已经是默认的写法
free(pc);
getchar();
return 0;
}
标准库函数中大量使用了void*
,比如C语言提供的内存管理,再看就更理解为什么用void*
了:
//申请固定大小内存
void *malloc(int num);
//内存释放
void free(void *address);