void 的使用方法简介
- void的含义
void 意思就是“无类型”,而void *表示“无类型指针”,可以指向任何类型的数据。主要用途分两种:
一、对函数返回的限定。
eg:
a) 修饰函数时,表示函数无返回值
void fun(unsigned char a,unsigned char b) // 这里的void就是限定fun无须返回值
{
printf ( "a + b = %d", (a+b));
}
b) 修饰指针函数,表示函数返回的是void型的指针。
void *fun(void)
{
void *p = NULL;
p = malloc(sizeof(int));
if(p!=NULL)
{
*p = 10;
}
return p;
}
// 引用
int *q = (int*)fun();
注意这里特别注意:当指针函数返回指针类型时,该指针指向的地址不能为”局部地址”。否则会在返回后立马释放掉,返回值会出错。如下面例子:
int * func(void)
{
int a= 10;
int *p = &a;
return p;
}
注意:a变量是func的局部变量,在func退出时,a的地址就会释放,此时p所指向的是未知地址,导致内存出错。
二、对函数参数的限定。
我们知道有类型的指针P1和P2,在类型相同情况下,是可以互相赋值的,如果类型不同,则必须强制转换成一样的方可以转换。
eg1:
int *P1 = “ABC”, *P2;
P2 = P1; // 这是可以赋值的。
eg2:
int *P1 = “ABC” ;
char *P2;
P2 = (char *)P1; // 必须转换后才可以赋值
但是void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:
void *p1;
int *p2;
p1 = p2;
正是因为这个特点,很多函数在不清楚参数输入的指针类型的情形下,使用void来修饰参数。
如我们最常用的库函数:
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
这两个函数的参数都是void*型,任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不 论这片内存是什么类型。
特别注意:
1. void型指针没有经过转换,不能直接赋给有类型的指针。
eg1:
void *p1;
int *p2;
p2 = p1; // 因为p1为无类型,不能直接这样赋值。
正确做法:
p2 = (int*)p1;
2.void 型指针必须转换成有类型的指针后才能进行正常操作。
eg1:
void *p1;
int *p2 = “ABC”;
p1 = p2;
p1++; // 这是错误的
正确做法:
char *p3;
p3 = (char *)p1;
p3++;
- 不能用void直接声明参数。 如void a; 这是错误的做法。
最后我们欣赏一下memcpy的原函数,这是用void比较多的函数:
void* memcpy(void*destaddr,voidconst*srcaddr,size_tlen)
{
char* dest=destaddr;
char const* src=srcaddr;
while(len-->0)
{
*dest++ = *src++;
}
return destaddr;
}
- 用void *来修饰memcpy,表明是一个指针函数,返回的函数类型时void指针。
- 用void*和voidconst* 修饰参数,表示任何类型的指针都可以传入其中。
- char* dest=destaddr; char const* src=srcaddr;表示要对void类型指针指向的地址操作,必须先进行类型转换。