您的位置:首页 > 编程语言 > C语言/C++

C/C++语言中的void及void指针总结

2011-09-15 10:54 288 查看

C/C++语言中的void及void指针总结

分类: c/c++进行时2011-06-27 15:18 102人阅读 评论(0) 收藏 举报

一、void 和 void* 含义

void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。

对于void,如果定义void a;是会编译出错的(vc6下得到:error C2182: 'a' : illegal use of type 'void',vs08中: error C2182: “a”: 非法使用“void”类型)

对于void*,任何类型的指针都可以直接赋值给它,无需进行强制类型转换。

view plain

void *p1;
int *p2;
p1 = p2;

这样是正确的,不过不能将int*转换为void*
二、我们在什么地方能用到void和void*

1、对于void,发挥作用的有两个地方:一是对函数返回值的限定,二是对函数参数的限定。下面举例说明:

(林锐的《高质量c++编程指南》上有以下3个对void和void*的使用的类似示范,即,如没有参数,一定要写明void;如没有返回值,一定标注;如果函数参数可以为任意类型指针,声明函数参数为void*)

1)对于返回值的限定

view plain

#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++中,类似代码:

view plain

#include <iostream>
using namespace std;
add ( int a, int b )
{
return a + b;
}
int main(int argc, char* argv[])
{
cout << "2 + 3 = "<< add ( 2, 3) << endl;
return 0;
}

在vc6中编译依旧没有问题的,但是在vs08中测试,会得到错误:error C4430: 缺少类型说明符 - 假定为 int;在gcc下编译会出错:error: ISO C++ forbids declaration of 'add' with no type。

这里需要注意的是: C++ 不支持默认 int 因为,C++语言有很严格的类型安全检查,不允许函数不加类型声明的情况发生。因此,为了避免混乱,如果函数没有返回值,一定要声明为void类型。
说到返回值,顺便提一下,在C++中对函数的重载,是不能通过返回值实现的,因为如同这个示范程序,调用add函数而忽略了其返回值,也就是使用了函数的副作用。

2)对参数的限定

view plain

#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中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型
malloc原型如下:

extern void *malloc(unsigned int num_bytes);
对于malloc,函数可以保证返回的内存是地址对齐的(怎么保证的楼主也不知道,《linux程序设计(第4版)》217页描述,待查证),所以,它可以被转换为任何类型的指针。

有没有觉得库函数的设计者的确很有远见啊,哈哈

3、总结

对于小小的void和void*,其实还是蛮有学问的,从中,可以看到操作的不断严谨,可以看到设计者的远见,也更提醒我们啊,coding的时候,要尽可能的严密啊。正好碰到了,搜资料,总结然后敲字于此,以备忘,同时,更希望对大家有用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: