之前對*和&符號一直理解的比較淺顯。只知道:
*p好像表示的是一個指針;
&p表示的是一個地址。
然而這次當遇到了下面這個情況的時候:
int a = 10;
int *b = &a;
printf(“%d\n”, a);
printf(“%d\n”, &a);
printf(“%d\n”, b);
printf(“%d\n”, *b);
結果:
10
6487620
6487620
10
一臉懵逼,為什么&a和*b的值不是一樣?這才發現自己其實一點都沒有搞懂。
經過學習后,總結出來:
變量a 本質上代表一個存儲單元。CPU通過該存儲單元的地址訪問該存儲單元中的數據。所以a本來代表兩個值:存儲單元的地址和儲單元中的數據。於是就有了二異性。為了消除這種二義性,C語言規定a表示存儲單元中的數據,&a表示存儲單元的地址。
a存儲單元中的數據可以是一個普通數值,也可以是另一個存儲單元的地址,比如:a = &b; 語句就是將b的存儲單元的地址存入a存儲單元中。C語言規定*a代表a中存儲的地址對應的存儲單元中的數據,也就是訪問*a就等於訪問b,於是*a提供了通過a訪問b中的數據的手段。
a表示a對應的存儲單元中的數據。
&a表示a對應的存儲單元的地址。
*a表示:首先,要求a對應的存儲單元中的數據一定是另一個存儲單元的地址。
於是,*a表示另一個存儲單元中的數據。
當a聲明的類型是int時,a中存儲的是一個整數數值,通過a可以訪問(讀取或修改)這個數值。
當a聲明的類型是int*時,a中存儲的是一個存儲單元的地址,而該存儲單元中存儲的數據是一個整數數值;通過*a可以訪問(讀取或修改)這個數值。a == &*a 都是該存儲單元的地址。
當a聲明的類型是int**時,a中存儲的是一個存儲單元的地址,而該存儲單元中存儲的數據是另外一個存儲單元的地址,另外這個存儲單元中存儲的是一個整數數值;通過**a可以訪問(讀取或修改)這個數值。
…
最后,在C語言里地址叫指針。還有,在C語言中的數組本質上其實也是指針,即:*a 等同於 a[]。
int a = 10;
int *b = &a;
printf("%p\n",&a); \\輸出變量a自身地址
printf("%p\n", b); \\輸出指針b中指向的地址,即a地址
printf("%p\n", &b); \\輸出指針b自身的地址
printf("%d\n", a); \\輸出變量a中數據10
printf("%d\n", b); \\輸出指針b中存儲的數據,5240892即為16進制004FF83C
printf("%p\n", b); \\輸出指正b中存儲數據,以指針格式輸出
printf("%d\n", *b); \\輸出指針b指向的地址內的數據,即a的數據
輸出結果:
004FF83C
004FF83C
004FF830
10
5240892
004FF83C
10