首页 理论教育C语言程序设计:void指针

C语言程序设计:void指针

【摘要】:void类型指针中的数据不能访问,如果非要访问的话,可以通过强制转换将void类型指针转换为与所指向的数据类型相符的类型。所谓“相同存储对齐限制”是指void类型指针所指的数据在内存中所占的长度与显式转换后的指针所指的数据在内存中所占的长度相等。同理,如果是将void类型转换为具有更小存储对齐限制的指针时,也可能引起数值的改变。

void的字面意思是“无类型”,void*则为“无类型指针”,void类型指针(如void*p)所指向的数据类型不是确定的,即可以指向任何类型的数据。但是,这并不意味着void*可以无需强制类型转换就赋给其他类型的指针。例如,下面语句编译出错:

void*p1;

int*p2;

p2=p1;

编译时系统提示:“cannot convert from’void*’to’int*’”。

void类型指针中的数据不能访问,如果非要访问的话,可以通过强制转换将void类型指针转换为与所指向的数据类型相符的类型。

(1)任何类型的指针都可以强制转换为void类型,且不会丢失数据。

例7.6 试分析以下程序的运行结果。

(2)void类型指针可以通过强制转换为具有更小或相同存储对齐限制的指针,但数据可能失真。

所谓“相同存储对齐限制”是指void类型指针所指的数据在内存中所占的长度与显式转换后的指针所指的数据在内存中所占的长度相等(比如以上程序中的p1所指的源数据在内存中占2个字节,p2所指的数据在内存中也是占2个字节)。需要注意的是,只有上面的这种转换(前后指针所指数据类型一致的转换)才能保持数据不失真;如果类型不一致,即使具有相同存储对齐限制,也有可能失真(比如由short转向unsigned short)。(www.chuimin.cn)

例7.7 试分析以下程序的运行结果。

上述程序的输出结果就不再是-5了,因为在指针转换时,short类型的数据也经过转换变成了unsigned short类型的数据,具体的转换过程请参考数据类型转换。不过,也有数值不变的情况(如把a值变为5)。

同理,如果是将void类型转换为具有更小存储对齐限制的指针时,也可能引起数值的改变。

例7.8 试分析以下程序的运行结果。

程序运行后,p1所指向的数据不再是720,而是-48。因为a的值720在内存中的表示形式为D0 02(十六进制表示,共2块,即2个字节),其中D0的地址即a的地址0x0012ff7c,p2只保存0x0012ff7c,不知道它占有2个字节内存空间。而p1所指数据占有1个字节,因此p1只代表D0,无法代表D0 02,将D0翻译成有符号char类型,即-48(D0是补码)。当然,如果将a的值改为较小的数(-128~127)(如3),转换后的值变不会发生改变。

综合以上两种情况,其实void类型指针所指向的数据一直都在内存中存放着,并没有被改动,只是我们在引用时(从内存中提取数据的过程中)发生了提取错误。道理很简单,一个有2个字节组成的数据,而你非要提取1个字节,是有可能发生错误的(但不是一定会发生错误,当一个数据既能用1个字节表示,又能用2个字节表示时就不会产生错误)。如果我们提取正确的话,随时都可以得到正确的数据。例如,将上面的“printf(“%d\n”,*p1)”;改为“printf(“%d\n”,*(short*)p1)”;则又会输出720。

(3)如果将void类型的指针转换为具有更大存储对齐限制的指针时,则会产生无效值。

例7.9 试分析以下程序的运行结果。