【C 語言入門】173.陣列的指標

在這篇文章,我們來介紹陣列的指標。

舉個例子,v 是三個元素的 int 所構成的陣列。v 作為變數,會佔據一個記憶體空間,裡面可以存 3 個 int 的大小。

int v[3] = {1, 2, 3};

我們之前提過,針對一個變數,我們可以用取址符(&)去取得位址,v 是個變數,因此也可以用取址符去取得位址。

我們知道型別會影響儲存,也會影響它可以做怎麼樣的運算。

這時候我們已經取得了位址,那他的型別會是甚麼呢?

今天 int 是個整數陣列,那它的位址的型別會是甚麼呢?

如果這個型別叫 int,那它的指標就是 int 的 pointer,也就是 int *。

如果 v 是 double ,那就是 double *。

陣列的指標取址

取位址的時候,我們可能會這樣表達 (int *[3]) &v,不過這樣會被誤以為這是一個有三個元素的陣列,而每個元素都是一個指標。

實際上,它本身是個指標,指向一個 3 個元素的整數陣列。

正確寫法

我們應該在指標外加個括弧,(int (*) [3]) &v,做優先順序的調整。

這時候我們就可以用這個型別來宣告定義一個變數來存 v的位址。

它就會長這個樣子。

int v[3] ={1, 2, 3};
int (*q) [3] = &v;

q 本身是個指標,q 指向一個有三個都是 int 元素的空間,q 本身只存一個位址。

v 的位址就可以存一個 q 變數。

#include <stdio.h>

int main()
{
    int v[3] ={1, 2, 3};
    int (*q) [3] = &v;
    
    int i;
    for(i = 0; i < 3; i++){
        (*q)[i] = 0;
    }

    return 0;
}

q 代表的是 v 的位址,因此 q 前面加 * ,就是變數 v 。

變數v 後面加一個中括弧就可以存取每個元素了。

#include <stdio.h>

int main()
{
    int v[3] ={1, 2, 3};
    int (*q) [3] = &v;
    
    int i;
    for(i = 0; i < 3; i++){
        (*q)[i] = 0;
    }
    
    //隨機存取
    (*q)[2] = 5;
    return 0;
}

小結:

q 是 v 的位址,*q 代表是 v 本身。

v 本身是個陣列,我們可以用中括弧去存取每個元素。

如果我們要在函式間傳遞陣列,我們也可以這樣做:

範例一:

#include <stdio.h>
void print(int (*q)[3]){
    int i;
    for(i=0;i<3;i++){
        printf("%d",(*q)[i]);
    }
    printf("\n");
}

int main()
{
    int v[3] ={1, 2, 3};
    print(&v);
    return 0;
}

我們要傳遞 v 陣列,因為 v 不能直接複製,因此我們不能直接把 v 傳過去,但是我們可以像上面的程式一樣,把 v 的位址複製過去。

v 的位址會被複製到 q,然後 q 加星號,就可以還原為 v。

(*q)[i] 就會存取 v 陣列的每個元素。

之前我們用了另一個方法。

範例二:

#include <stdio.h>
void print(int *n){
    int i;
    for(i=0;i<3;i++){
        printf("%d",n[i]);
    }
    printf("\n");
}

int main()
{
    int v[3] ={1, 2, 3};
    print(v);
    return 0;
}

main 裡面傳的 v 會隱性轉型成一個 pointer。

而範例一 我們是直接取得。

範例一和範例二做出來的效果是非常接近的。

範例一的 print 函式的 q 本身是一個指標,指向一個陣列,(int (*) [3]) &v 代表的是整個陣列的位址。

範例二的 print 函式的 n 本身也是一個指標,指向整數,(int *)&v[0] 代表的是第一個元素的位址。

(int (*) [3]) &v(int *)&v[0] 型別不同,會造就使用上的特性不一樣。

範例二是我們更常使用的版本,關於這部份我們會在之後的文章探討。

Leave a Comment

Your email address will not be published. Required fields are marked *