打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

一、void 和 void* 含义

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

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

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

  1. void *p1;  
  2. int *p2;  
  3. p1 = p2;  
 这样是正确的,不过不能将int*转换为void*

二、我们在什么地方能用到void和void*

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

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

1)对于返回值的限定

  1. #include "stdio.h"  
  2. add ( int a, int b )  
  3. {  
  4.     return a + b;  
  5. }  
  6. int main(int argc, char* argv[])  
  7. {  
  8.     printf ( "2 + 3 = %d /n ", add ( 2, 3) );  
  9.     return 0;  
  10. }  

     上述程序,在C语言中运行是没有任何问题的,因为c语言中,函数如果没有返回值限定,则编译器默认返回为int来处理。虽然看起来会以为返回void。

     但是在c++中,类似代码:

  1. #include <iostream>  
  2. using namespace std;  
  3. add ( int a, int b )  
  4. {  
  5.     return a + b;  
  6. }  
  7. int main(int argc, char* argv[])  
  8. {  
  9.     cout << "2 + 3 = "<<  add ( 2, 3) << endl;  
  10.     return 0;  
  11. }  
 

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

     这里需要注意的是: C++ 不支持默认 int   因为,C++语言有很严格的类型安全检查,不允许函数不加类型声明的情况发生。因此,为了避免混乱,如果函数没有返回值,一定要声明为void类型。

     说到返回值,顺便提一下,在C++中对函数的重载,是不能通过返回值实现的,因为如同这个示范程序,调用add函数而忽略了其返回值,也就是使用了函数的副作用。

2)对参数的限定

  1. #include "stdio.h"  
  2. fun()  
  3. {  
  4.     return 1;  
  5. }  
  6. int main()  
  7. {  
  8.     printf("%d/n",fun(2));  
  9.     return 0;  
  10. }  
 

   说明,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。

    内存操作函数memcpymemset的函数原型分别为:

    void * memcpy(void *dest, const void *src, size_t len);
    void * memset ( void * buffer, int c, size_t num );

    这样,任何类型的指针都可以传入memcpymemset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型

    malloc原型如下:

 

    extern void *malloc(unsigned int num_bytes);

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

 

 

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

 

3、总结

     对于小小的void和void*,其实还是蛮有学问的,从中,可以看到操作的不断严谨,可以看到设计者的远见,也更提醒我们啊,coding的时候,要尽可能的严密啊。正好碰到了,搜资料,总结然后敲字于此,以备忘,同时,更希望对大家有用。

 

 

参考网址:http://developer.51cto.com/art/200510/9059.htm

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
new、delete 与指针
指针和内存分配
05、C++ 11 函数参数类型传递分析与总结
memset函数及其用法,C语言memset函数详解
C语言中函数和指针的参数传递
C语言指针详解
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服