一、void 和 void* 含义
void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。
对于void,如果定义void a;是会编译出错的(vc6下得到:error C2182: 'a' : illegal use of type 'void',vs08中: error C2182: “a”: 非法使用“void”类型)
对于void*,任何类型的指针都可以直接赋值给它,无需进行强制类型转换。
void *p1; int *p2; p1 = p2; 这样是正确的,不过不能将int*转换为void*
二、我们在什么地方能用到void和void*
1、对于void,发挥作用的有两个地方:一是对函数返回值的限定,二是对函数参数的限定。下面举例说明:
(林锐的《高质量c++编程指南》上有以下3个对void和void*的使用的类似示范,即,如没有参数,一定要写明void;如没有返回值,一定标注;如果函数参数可以为任意类型指针,声明函数参数为void*)
1)对于返回值的限定
#include "stdio.h" add ( int a, int b ) { return a + b; } int main(int argc, char* argv[]) { printf ( "2 + 3 = %d /n ", add ( 2, 3) ); return 0; }
上述程序,在C语言中运行是没有任何问题的,因为c语言中,函数如果没有返回值限定,则编译器默认返回为int来处理。虽然看起来会以为返回void。
但是在c++中,类似代码:
#include
在vc6中编译依旧没有问题的,但是在vs08中测试,会得到错误:error C4430: 缺少类型说明符 - 假定为 int;在gcc下编译会出错:error: ISO C++ forbids declaration of 'add' with no type。
这里需要注意的是: C++ 不支持默认 int 因为,C++语言有很严格的类型安全检查,不允许函数不加类型声明的情况发生。因此,为了避免混乱,如果函数没有返回值,一定要声明为void类型。
说到返回值,顺便提一下,在C++中对函数的重载,是不能通过返回值实现的,因为如同这个示范程序,调用add函数而忽略了其返回值,也就是使用了函数的副作用。
2)对参数的限定
#include "stdio.h" fun() { return 1; } int main() { printf("%d/n",fun(2)); return 0; }
说明,C语言中,可以给无参数的函数传送任意类型的参数,当然,这不安全(C99以后C语言有没有改进不知)
而在c++中,会得到提示错误:error C2660: 'fun' : function does not take 1 parameters(vc6下)或 error: too many arguments to function 'int fun()'(gcc下)
所以,无论在C还是C++中,若函数不接受任何参数,一定要指明参数为void。
2、void*
对于void*,也许最常见的应该是库函数吧,像memset,malloc,memcopy。
内存操作函数memcpy和memset的函数原型分别为:
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
这样,任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型
extern void *malloc(unsigned int num_bytes);
对于malloc,函数可以保证返回的内存是地址对齐的(怎么保证的楼主也不知道,《linux程序设计(第4版)》217页描述,待查证),所以,它可以被转换为任何类型的指针。
有没有觉得库函数的设计者的确很有远见啊,哈哈
3、总结
对于小小的void和void*,其实还是蛮有学问的,从中,可以看到操作的不断严谨,可以看到设计者的远见,也更提醒我们啊,coding的时候,要尽可能的严密啊。正好碰到了,搜资料,总结然后敲字于此,以备忘,同时,更希望对大家有用。
参考网址:http://developer.51cto.com/art/200510/9059.htm