zoukankan      html  css  js  c++  java
  • void指针(void*)用法

    首先看一段测试代码:

     1 #include <stdio.h>
     2 
     3 int void_test(void* data)
     4 {
     5     int num = 0;
     6     
     7     num = *(int*)data;
     8     printf("num = %d
    ", num);
     9     
    10 }
    11 
    12 int main()
    13 {
    14     int val;
    15     
    16     val = 123;
    17     void_test(&val);
    18     return 0;
    19 }

    将以上代码编译并运行,输出结果为:

    num = 123

    下面摘录对void类型指针使用方法总结。

    1.void *可以指向任何类型的数据

    2. void真正发挥的作用在于:

      (1) 对函数返回的限定;

      (2) 对函数参数的限定。

    3.例如:

      float *p1;

      int *p2;

      p1 = p2;

      其中p1 = p2语句会编译出错,提示“'=' : cannot convert from 'int *' to 'float *'”,必须改为:

      p1 = (float *)p2;

      而void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:

      void *p1;

      int *p2;

      p1 = p2;

    4.但这并不意味着,void *也可以无需强制类型转换地赋给其它类型的指针。因为“无类型”可以包容“有类型”,而“有类型”则不能包容“无类型”。道理很简单,我们可以说“男人和女人都是人”,但不能说“人是男人”或者“人是女人”。下面语句编译出错:

      void *p1;

      int *p2;

      p2 = p1;

      提示“'=' : cannot convert from 'void *' to 'int *'”。

    15.void的使用:

    规则一

      如果函数没有返回值,那么应声明为void类型

    规则二

      如果函数无参数,那么应声明其参数为void。

    规则三

      小心使用void指针类型

      按照ANSI(American National Standards Institute)标准,不能对void指针进行算法操作,即下列操作都是不合法的:

      void * pvoid;

      pvoid++; //ANSI:错误

      pvoid += 1; //ANSI:错误

      //ANSI标准之所以这样认定,是因为它坚持:进行算法操作的指针必须是确定知道其指向数据类型大小的。

      //例如:

      int *pint;

      pint++; //ANSI:正确

      pint++的结果是使其增大sizeof(int)。( 在VC6.0上测试是sizeof(int)的倍数)

      但是大名鼎鼎的GNU(GNU's Not Unix的缩写)则不这么认定,它指定void *的算法操作与char *一致。

      因此下列语句在GNU编译器中皆正确:

      pvoid++; //GNU:正确

      pvoid += 1; //GNU:正确

      pvoid++的执行结果是其增大了1。( 在VC6.0上测试是sizeof(int)的倍数)

      在实际的程序设计中,为迎合ANSI标准,并提高程序的可移植性,我们可以这样编写实现同样功能的代码:

      void * pvoid;

      (char *)pvoid++; //ANSI:正确;GNU:正确

      (char *)pvoid += 1; //ANSI:错误;GNU:正确

      GNU和ANSI还有一些区别,总体而言,GNU较ANSI更“开放”,提供了对更多语法的支持。但是我们在真实设计时,还是应该尽可能地迎合ANSI标准。

    5.规则四

      如果函数的参数可以是任意类型指针,那么应声明其参数为void *

      

      典型的如内存操作函数memcpy和memset的函数原型分别为:

      void * memcpy(void *dest, const void *src, size_t len);

      void * memset ( void * buffer, int c, size_t num );

      这样,任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型。如果memcpy和memset的参数类型不是void *,而是char *,那才叫真的奇怪了!这样的memcpy和memset明显不是一个“纯粹的,脱离低级趣味的”函数!

    6.规则五

      void不能代表一个真实的变量

      下面代码都企图让void代表一个真实的变量,因此都是错误的代码:

      void a; //错误

      function(void a); //错误

      void体现了一种抽象,这个世界上的变量都是“有类型”的,譬如一个人不是男人就是女人(还有人妖?)。

        参考链接:http://jingyan.baidu.com/article/6c67b1d68f93bb2786bb1e46.html

  • 相关阅读:
    MVC梳理与总结
    《岛上书店》
    PIL简单图片处理(上)
    Day 3---快捷键
    Day 2---控制快捷键
    Day 1--快捷键
    每天学点Emacs
    swift写ios mvc的小demo
    hexo博客部署到github无法上传的问题
    Django Web开发【7】 投票与评论
  • 原文地址:https://www.cnblogs.com/geekham/p/4225993.html
Copyright © 2011-2022 走看看