1. 程式人生 > >C語言查缺補漏(五)指標作參

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

​ 只要捋清每個變數所代表的意義,指標作參就不會那麼迷糊了,就醬紫~