这次对void差不多有点多少的理解了,从最初的理解就是空,么有的意思。首先void是C语言中的关键字,对函数返回值的限定,对函数参数的限定。
但是这并不意味着,void *可以无需强制类型转换的赋值给其他指针。
2.void 修饰返回值和参数列表
(1)如果函数没有返回值,则应该显式地声明为 void。如果函数没有 返回值,则默认为返回什么?是不是 void?
上面的这段代码只会出现警告,但是编译器还是会乖乖的听话,帮你执行了。默认int类型
(2)如果函数无参数,则应该声明其参数列表为 void。
p++;//错误,编译器无法知道每次前进的大小。
其实对上面的这个我在linux下的gcc中调式了,可以运行出来,没有在windows下调式,我也不知道对不对。因为环境和编译器不一样,那么运行的结果也会不一样。
在linux下的测试代码:
通过上面的代码。可以测试出void*p,p++地址会加1,,而对于int *q,q++那么地址会加4,float也是如此,对于他们三个开辟的空间的地址起始还不一样。之后还测试出,可能linux下人家的gcc太高端,编译器太好了,人家对于未初始化的指针直接放到保留区,直接为NULL,在windows下这可就不一样了。
5.void 关键应用最广泛的领域:C 语言的泛型编程。
必须记得每次malloc完之后一定要free,否则会出现内存泄漏
1.void*常常被称为空指针,其实理解为指向任意类型的指针比较合适,as we all kown,如果指针p1和指针p2的类型相同,那么才可以相互赋值,类型不同的话,有必要在此之间进行强制类型转化。而任意类型的指针都可以直接赋值给void*。
int *p1;
float *p2;
void *p3;
p1 = p2; //报错,类型不匹配。
p1 = (int *)p2; //需要强制转换
p3 = p2; //可以直接赋值
但是这并不意味着,void *可以无需强制类型转换的赋值给其他指针。
void *p1;
float *p2;
p2 = p1; //错误
p2 = (float *)p1; //强转后正确
2.void 修饰返回值和参数列表
(1)如果函数没有返回值,则应该显式地声明为 void。如果函数没有 返回值,则默认为返回什么?是不是 void?
add(int a, int b)
{
return a + b;
}
int main(int argc, char **argv)
{
printf("2 + 3 = %d\n", add(2, 3));
}
上面的这段代码只会出现警告,但是编译器还是会乖乖的听话,帮你执行了。默认int类型
(2)如果函数无参数,则应该声明其参数列表为 void。
3. void 不能真实的表达一个变量。
void a; //错误,编译器无法知道分配给 a 多大的空间。
4.void*指针不能进行算术操作。(ANSI C 规定)
void *p;p++;//错误,编译器无法知道每次前进的大小。
其实对上面的这个我在linux下的gcc中调式了,可以运行出来,没有在windows下调式,我也不知道对不对。因为环境和编译器不一样,那么运行的结果也会不一样。
在linux下的测试代码:
#include <stdio.h>
int main(int argc,char *argv[])
{
void *p;
int *q;
float *m;
printf("before q = %p\n",q);
q++;
printf("after q = %p\n",q);
printf("before p=%p\n",p);
p++;
printf("after p = %p\n",p);
printf("before m=%p\n",m);
m++;
printf("after m = %p\n",m);
return 0;
}
通过上面的代码。可以测试出void*p,p++地址会加1,,而对于int *q,q++那么地址会加4,float也是如此,对于他们三个开辟的空间的地址起始还不一样。之后还测试出,可能linux下人家的gcc太高端,编译器太好了,人家对于未初始化的指针直接放到保留区,直接为NULL,在windows下这可就不一样了。
before q = (nil)
after q = 0x4
before p=0x7ffff93fd5a0
after p = 0x7ffff93fd5a1
before m = 0x400440
after m = 0x400444
5.void 关键应用最广泛的领域:C 语言的泛型编程。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void my_swap(void *a,void *b,int lenth)
{
void *p =malloc(lenth);
memcpy(p,a,lenth);
memcpy(a,b,lenth);
memcpy(b,p,lenth);
free(p);
}
int main(int argc,char *argv[])
{
int a = 10;
int b = 20;
double c = 100.123;
double d = 200.789;
printf("before a = %d,b = %d\n",a,b);
my_swap(&a,&b,sizeof(int));
printf("after a = %d,b = %d\n",a,b);
printf("before c = %lf,d = %lf\n",c,d);
my_swap(&c,&d,sizeof(double));
printf("after c = %lf,d = %lf\n",c,d);
return 0;
}
必须记得每次malloc完之后一定要free,否则会出现内存泄漏