声明:个人所写所有博客均为自己在学习中的记录与感想,或为在学习中总结他人学习成果,但因本人才疏学浅,如果大家在阅读过程中发现错误,欢迎大家指正。
公众号:
参考:blog.chinaunix.net/uid-22197900-id-359211.html
一、void
void:无类型
void *:无类型指针,可以指向任何类型的数据
void的作用无非两种:
1、对函数返回值进行限定
2、对函数传入参数进行限定
void的常见使用:
1、所声明的函数没有返回值,声明为void类型
例如:
void fun(type temp){
//这个函数没有返回值
}
2、如果见到void * fun(type temp){}这种的函数声明又是怎么呢,有void,又有*,到底是没有返回值还是有返回值。
void *fun(type temp){
//这种函数是有返回值的,是可以返回任意类型的值得指针
//因为C语言会做严格的类型检查,比如在某些地方要使用各种类型的指针就需要void *了
//比如常见的C函数如mem **系列的
}
3、函数中没有传入参数,例如void fun(void){},这个函数既没有返回值,也没有传入参数
二、void *指针
指针有两个属性:所指向的数据的地址的数据长度
指针只存储指针的地址,指针类型决定了所指向的数据的长度
使用
1、void *是一种只有存储地址,没有数据长度属性的指针
void *vp; //因为没有类型,所以编译器不知道所指向数据的长度
2、void *指针可以指向任何类型的数据,可以随便赋值
type *p;
void *vp = p; //vp只获得了数据地址,而不具有数据长度属性
3、想将void *指针赋值给其他类型的指针,必须进行类型转换,因为只能得到数据地址,得不到数据长度,无法参与运算
type *pp = (type *)vp; //只有进行格式转换,才能得到数据长度
例:
int a = 1;
int *p = &a;
void *vp = &a;
printf("p: %p\n", p);
printf("p: %d\n", *p);
printf("vp: %p\n", vp);
printf("vp: %d\n", *vp); //会显示错误,不完整的类型,非法的间接寻址
改为:printf(“vp %d\n”, *(int *)vp); 后便可以参与运算
输出结果:
p: 001AFABC
p: 1
vp: 001AFABC
vp: 1
可见p与vp所指向的地址也一样,类型转换后可以参与运算
4、void *指针不能复引用
*vp; //错误,原因第3条
5、void *也不能进行指针运算
(type *)vp++; //vp = vpn+ sizeof(type);
例:
int a = 1;
int *p = &a;
void *vp = &a;
printf("p: %p\n", p);
printf("p: %d\n", *p);
printf("vp: %p\n", vp);
printf("vp: %d\n", *(int *)vp);
printf("vp+1: %d\n", *(int *)vp + 1);
printf("vp+1: %p\n", (int *)vp + 1);
输出结果:
p: 0065FB70
p: 1
vp: 0065FB70
vp: 1
vp+1: 2
vp+1: 0065FB74
2016-8-20更新内容
void *指针使用的一个典型例子:
内存分配:malloc 与 calloc 函数的使用
void *malloc(size_t size);
malloc 从内存中申请 size 大小的内存,并返回指向所分配区域的第一个字节的指针,若内存不满足,则返回 NULL。不对分配的内存区域进行初始化。
因为malloc的返回类型是 void * 的,在使用的时候,需要转换为相应的类型才能够使用。
int *p = (int *)malloc(sizeof(int));
calloc同理
void *calloc(size_t nobj, size_t size);
calloc 为由 nobj 个大小为 size 的对象组成的数组分配足够的内存,并返回指向所分配区域的第一个字节的指针,若内存不满足,则返回 NULL。该空间的初始大小为 0 个字节