void指针

看到有些人对void指针不太清楚,我就试着解释一下,权当抛砖引玉。
     

    大家都知道int *pint是定义了一个指针变量,这个变量里面放的是一个地址,而这个地址里面放的是一个int型的数值。

char *pchar是定义了一个指针变量,这个变量里面放的是一个地址,而这个地址里面放的是一个char型的数值。

以此类推……我们也知道在32位计算机上,一般sizeof(pint)是4,也就是说指针变量p的大小是4个字节,每个地址用32位来表示。

我们还知道一般sizeof(int)也是4,因为寻址的最小单元是字节,也就是一个int型数据一共占用了4个地址空间。比如定义int i;

假设从首地址到末地址分别为:10000,10001,10002,10003(这里为了讨论问题的方便,不考虑bigendian,little endian的问题,

有兴趣的可以查找有关资料)。然后int *pint = &因为i占用了4个地址,那么p里面放的是什么呢?p里面放的是变量i的首地址,

也就是10000。我们可以用*pint来表示i,当我们这样做时*pint = 10;编译器是怎么解释的呢?编译器的解释是向从10000地址

开始的4个字节里面放入整数10。可能你又要问了,编译器又是怎么知道是从10000地址开始的4个字节呢?是的,编译器知道它该

这么做,因为pint是一个指针而且它的内容10000,还有p是一个指向int型变量的指针,还因为sizeof(int)是4,所以它可以确保

做上面的事情。

      
     好了,罗里罗嗦的说了关于int类型指针这么多,对别的类型指针也是一样。

现在该说说void指针了。void *pvoid;这样定义后,我们必须明确的知道,p也是一个指针,sizeof(pvoid)或sizeof(void *)也是4。

给它赋值后,它的内容也是一个地址。比如我们把上面pint赋值给pvoid, pvoid = pint;现在pvoid和pint的内容完全一样,也是10000。

可当你这样使用时,*pvoid = 1;编译器就会报错了。问题就在于pvoid是无类型的指针,也就是它不指向任何类型,你间接引用时,

编译器从10000地址开始,要到哪个地址才能结束呢?编译器不知道这些事情,所以它会报错。当我们明确知道pvoid指向的是什么类型,

就可以用强制类型转换把pvoid转换为那个类型的指针,例如 *(int *)pvoid = 1;这样就可以了,此时i的值为1。

     

      现在你应该清楚void指针的概念了吧。任何类型的指针都可以赋值给void指针,你也可以把void指针转换成任何类型(当然,

你把它转换成并不是它实际指向的类型,结果不可预测。比如你把int型指针赋予void指针,然后把void指针强制转换成doube型指针,

并间接引用它,这样的结果不可预测)所以使用时应该把void指针转换成它实际指向的类型。使用void指针增加了程序的灵活性,

但一定要谨慎使用。
      
      这是我刚刚写的,由于是上班,也没有很好的考虑,如果有错误,欢迎指正!下面附带一些测试代码,环境aix5l,gcc3.3
  1. #include <stdio.h>; 

  2. int main() 

  3.         int *pint; 
  4.         int i = 10;
  5.         pint = &
  6.         void *pvoid;
  7.         pvoid = (void *)pint;
  8.         printf("sizeof(void *) = %d\n",sizeof(void*));
  9.         printf("pint = %p,pvoid = %p\n",pint,pvoid);
  10.         printf("(int*)i = %d\n",*pint); 
  11.         printf("(void*)i = %d\n",*(int *)pvoid);
  12.         printf("(void*)i = %d\n",*pvoid);//不能通过编译
  13.         *(int *)pvoid = 1;
  14.         printf("%d\n",i);
  15.         *(long *)pvoid = 1;//可以编译通过,结果也正确
  16.         printf("%d\n",i);
  17.         *(short *)pvoid = 1;//可以编译通过,结果不正确
  18.         printf("%d\n",i);
  19.         return 0;
  20. }
复制代码
void指针使用规范
①void
指针可以指向任意类型的数据,亦即可用任意数据类型的指针对void指针赋值。例如:
int *pint;
void *pvoid;
pvoid = pint; /* 
不过不能 pint = pvoid; */
如果要将pvoid赋给其他类型指针,则需要强制类型转换如:pint = (int *)pvoid;

void的作用
对函数返回的限定。
对函数参数的限定。
当函数不需要返回值时,必须使用void限定。例如: void func(int, int);
当函数不允许接受参数时,必须使用void限定。例如: int func(void)

由于void指针可以指向任意类型的数据,亦即可用任意数据类型的指针对void指针赋值,因此还可以用void指针来作为函数形参,这样函数就可以接受任意数据类型的指针作为参数。例如:
void * memcpy( void *dest, const void *src, size_t len );
void * memset( void * buffer, int c, size_t num );

你可能感兴趣的:(gcc,测试,buffer,AIX,编译器)