C語言查缺補漏(五)指標作參
忽略點五:指標作參
平時比賽很少用到指標(連結串列,動態陣列都有對應的STL,字典樹也可以用陣列模擬),業精於勤荒於嬉,C語言的指標就這樣被我遺忘了。。
之前博文說過,C語言的優勢之一就是在於能夠直接訪問實體地址,C語言的一大特色就是指標!!所以,學C語言捨棄指標是非常不明智的選擇,終歸是要還以前忽略的債。。苦笑~
關於指標,自己忽略的部分有很多,這一篇主要講一下關於指標作參的用法:
——對於函式來說:
它不像變數那樣可以進行值傳遞,我們在將函式作參進行傳遞時,需要傳遞它的地址,格式為:
int g (int (*f)(int), int a) { //定義 return f(a); } //省略程式碼 g(函式名, int型變數); //呼叫
——對於一維陣列來說:
它的格式為:
void f (int *p) { //定義
//省略程式碼
}
//省略程式碼
int a[5];
f (a); //呼叫
關於這個a,我對它的理解是陣列的初始位置,它等價於&a[0]。因為我們在宣告指標指向a陣列時,是通過 int *p = a來實現的。
——對於二維陣列來說:
它的格式為:
void f (int *p) { //定義
//省略程式碼
}
//省略程式碼
int a[5][5];
f (a[0]); //呼叫 由一維陣列可知,a[0]等價於&a[0][0],也等價於*a
a[0]等同於二維陣列的首地址,也是二維陣列下標為0行的首地址,同理a[1]為下標為1行的首地址,以此類推。
下面的問題沒想明白,歡迎大佬來為我解惑。
我的認識(不一定正確):那麼二維陣列的a是什麼呢?從上邊我們可以知道,a[0], a[1]等等都是地址資訊,把他們整體來看,就是一個一維的指標陣列。那麼a為這個一維指標陣列的首地址,而*a就是a[0]的值,也就是二維陣列的首地址,從下面程式碼中也可以證實我的觀點:
void f(int *p) {
for (int i = 0; i < 4; i++) {
printf("%d\n", p[i]);
}
}
//省略程式碼
int a[2][2] = {1, 2, 3, 4};
f(*a);
最後結果輸出 1,2,3,4,說明了*a 等價於a[0],也就是二維陣列的首地址
但是按上面的邏輯,*a等價於a[0],那麼a就是儲存a[0]指標地址的地址,可我通過以下程式碼輸出發現,a的值等於 *a
int a[2][2] = {1, 2, 3, 4};
printf("%p\n", a);
printf("%p\n", *a);
輸出為:
如果a的值等於*a,以下程式碼卻報錯:
void f(int *p) {
for (int i = 0; i < 4; i++) {
printf("%d\n", p[i]);
}
}
//省略程式碼
int a[2][2] = {1, 2, 3, 4};
f(a);
很迷茫。。。希望有大佬能為我解惑~
——對於結構體來說:
結構體指標和變數指標作參類似,但它的指標可通過 ->符指向它的成員,舉個栗子(擷取遍歷連結串列程式碼的一部分):
struct node {
int val;
node *next;
}
void f(node *root) {
while (root -> next != NULL) {
printf("%d\n", root -> val)
}
}
root -> val等價於 *(root).val
只要捋清每個變數所代表的意義,指標作參就不會那麼迷糊了,就醬紫~