但應注意的是。僅僅有上面的這樣的轉換先後指針所指數據類型一致的轉換才保持數據不失真,假設類型不一致,即便具備一樣存儲對齊限制,也有可能失真,比方由short轉向unsigned short,請看下面程序:
#include<stdio.h>
int main(void)
{
short a=-5,*p1=&a;
unsigned short *p2;
void *p3;
p3=(void *)p1;
p2=(unsigned short *)p3;
printf("%d\n",*p2);
return 0;
}
其輸出結果就再也不是-5了。因爲在指針轉換時,short類型的數據也通過轉換變成了unsigned short類型的數據,詳細的轉換過程請參考數據類型轉換。翻譯
只是,也有數值不變的狀況,如把a值變爲5。指針
同理,假設是將void類型轉換爲具備更小存儲對齊限制的指針時,也可能引發數值的改變。請看下面程序:
#include<stdio.h>
int main(void)
{
short a=720;
char *p1;
void *p2;
p2=(void *)&a;
p1=(char *)p2;
printf("%d\n",*p1);
return 0;
}
p1所指向的數據再也不是720,而是-48。因爲a的值720在內存中的表示形式爲D0 02(十六進制表示,共兩塊,即兩個字節),當中D0的地址即a的地址:0x0012ff7c。p2僅僅保存0x0012ff7c,不知道它佔有兩字節內存空間。而p1所指數據佔有一字節。所以p1僅僅表明D0。沒法表明D0 02。將D0翻譯成有符號char類型,即-48(D0是補碼)。固然。假設將a的值改成較小的數(-128~127)。如3,轉換後的值變不會發生改變。內存
綜上兩種狀況,事實上void類型指針所指向的數據一直都在內存中存放着,並無被修改。而僅僅是咱們在引用時從內存中提取數據的過程當中發生了提取錯誤。道理很是easy,一個有兩字節組成的數據。而你非要提取一字節,是有可能錯誤發生的(但不是必定會錯誤發生。當一個數據既能用一字節表示,又能用兩字節表示時就不會產生錯誤)。假設咱們提取正確的話。隨時都可以獲得正確的數據。比方將上面的printf("%d\n",*p1);改成printf("%d\n",*(short *)p1);則又會輸出720。
3.假設將void類型的指針轉換爲具備更大存儲對齊限制的指針時。則會產生無效值。例如如下面程序:
#include<stdio.h>
int main(void)
{
short a=23;
void *p1;
int *p2;
p1=(void *)&a;
p2=(int *)p1;
printf("%d\n",*p2); return 0;
}
其返回值爲-859045865 io