在例2.11中,既然&a[i]表示數組a的各個元素的地址,這些地址存儲相應數組元素的值,就應該能直接將這些值輸出。
【例2.13】使用「*」操作符輸出數組內容。
#include <stdio.h> void main ( ) { int a[3]={1 ,2 ,3} ; int i=0 ; // 輸出數組地址 for (i=0 ;i<3 ;i++ ) printf ("0x%p " ,&a[i] ); printf ("\n" ); // 輸出數組內容 for (i=0 ;i<3 ;i++ ) printf ("%d " ,*&a[i] ); printf ("\n" ); }
地址用十六進制輸出,地址裡的內容採用在地址前加「*」號的方法輸出。輸出結果如下。
0x0012FF74 0x0012FF78 0x0012FF7C 1 2 3
上面演示了對數組的地址使用「*」操作的方法。如果用變量存儲一個有效的地址,例如整型變量addr存儲整型變量a的地址,能用「*addr」輸出變量a的值嗎?下面就通過程序來看看是否可行。
【例2.14】分析程序中存在的錯誤。
#include <stdio.h> int main () { int a=25 ; int addr ; addr=&a ; printf (" 分配給變量a 的地址0x%d\n" ,&a ); printf ("addr 的地址值=0x%p\n" ,addr ); // 輸出addr 的值 printf ("addr 地址裡的內容=%d\n" ,*addr ); // 輸出addr 的內容 return 0 ; }
編譯給出一個錯誤信息和一個警告信息。
warning C4047 : '=' : 'int ' differs in levels of indirection from 'int *' error C2100 : illegal indirection
因為addr是整型變量,&a是地址值,所以造成語句「=」兩邊的數據類型不匹配。可以對地址值使用int進行強制轉換以解決不匹配問題,即使用語句
addr= (int )&a ;
將地址轉換成整型數值,完成「=」兩邊的匹配,這樣就解決了編譯時的警告信息。
直接對&a使用「*」,輸出正確。但對addr出錯,顯然也是表達方式不匹配。使用強制轉換,改用
printf ("addr 地址裡的內容=%d\n" ,(int* )addr );
編譯正確,輸出結果如下。
分配給變量a 的地址0x1245052 addr 的地址值=0x0012FF7C addr 地址裡的內容=1245052
雖然輸出結果不對,但有了解決辦法。「1245052」就是addr的十進制地址,所以對這個地址使用「*」操作符即可。
因為語句「addr=(int)&a;」將地址強制轉換成int類型值的地址,所以不能直接使用「*addr」,需要使用「(int*)addr」再將其轉換成存儲的地址值。程序的輸出結果也證實了它就是變量a的地址,也就是存儲在addr變量裡的地址。這時再對它使用「*(int*)addr」,就能輸出存儲在addr地址裡的值了。
// 改正後的正確程序 #include <stdio.h> int main () { int a=25 ; int addr ; addr= (int )&a ; printf (" 分配給變量a 的地址0x%d\n" ,&a ); printf ("addr 的地址值=0x%p\n" ,addr ); // 輸出addr 的值 printf ("addr 地址裡的內容=%d\n" ,*&a ); // 輸出addr 的值 printf ("addr 地址裡的內容=%d\n" ,* (int* )addr ); // 輸出addr 的內容 return 0 ; }
輸出結果如下。
分配給變量a 的地址0x1245052 addr 的地址值=0x0012FF7C addr 地址裡的內容=25 addr 地址裡的內容=25
顯然,把變量a的地址直接賦給變量addr,效果是一樣的。
【例2.15】直接將地址賦給變量的例子。
#include <stdio.h> int main () { int a=25 ; int addr ; addr= (int )0x0012FF7C ; printf (" 分配給變量a 的地址0x%d\n" ,&a ); printf ("addr 的地址值=0x%p\n" ,addr ); // 輸出addr 的值 printf ("addr 地址裡的內容=%d\n" ,*&a ); // 輸出addr 的值 printf ("addr 地址裡的內容=%d\n" ,* (int* )addr ); // 輸出addr 的內容 return 0 ; }
運行結果相同,不再給出。