void(*p)()
- void(*p)()是一个指向函数的指针,表示一个指向函数入口的指针变量,该函数的返回类型是void类型。
void *p()
- void *p()是一个指针型函数,它的函数名为p,范围了一个指针,因为是void,这个指针没有定义类型,所以返回的是一个通用型指针。
void指针
- void 指针是一种特殊的指针,表示为“无类型指针”。 由于 void 指针没有特定的类型,因此它可以指向任何类型的数据。
- 比如
void *p1;
int *p2;
p1 = p2;
将 void 指针赋给其他类型的指针,通常也是要强转的。
因为“空类型”可以包容“有类型”,而“有类型”则不能包容“空类型”
void *p1;
int *p2;
p2 =(int*)p1;
对于 void 指针,编译器并不知道所指对象的大小,所以对 void 指针进行算术操作都是不合法的。
void * p;
p++; // ANSI:错误
p+= 1; // ANSI:错误
如果函数的参数可以是任意类型指针,应该将其参数声明为 void*
比较典型的函数有内存操作函数 memcpy ,如下面的代码所示:
void *memcpy (void *dst, const void *src, size_t size)
{
assert((dst!=NULL) && (src!=NULL));
char *temp_dest = (char *)dst;
char *temp_src = (char *)src;
char* retAddr = temp_dest;
size_t i = 0;
/* 解决数据区重叠问题*/
if ((retAddr>temp_src) && (retAddr<(temp_src+size)))
{
for (i=size-1; i>=0; i--)
{
*(temp_dest++) = *(temp_src++);
}
}
else
{
for (i=0; i<size; i++)
{
*(temp_dest++) = *(temp_src++);
}
}
*(retAddr+size)='\0';
return retAddr;
}
任何类型的指针都可以传入 memcpy 函数中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型。
memcpy 函数的调用示例如下面的代码所示:
char buf[]="abcdefg";
// buf+2(从c开始,长度3个,即cde)
memcpy(buf, buf+2 ,3);
printf("%s\n", buf);
或者进行如下形式的调用:
int dst[100];
int src[100];
memcpy(dst, src, 100*sizeof(int));
因为参数类型是 void*,所以上面的调用都是正确的。