【C 語言入門】174.在函式間使用哪種指標傳遞陣列

我們先複習一下指標和陣列的關係。

我們現在有一個 v 陣列,它有三個元素,我們之前有討論到,我們可以把整數陣列隱性轉型成一個整數的指標。

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

n 代表的是陣列 v 的第一個元素的記憶體位址。

我們之前也介紹了指標陣列。

指標陣列

int *p[3] = {&v[2],&v[1],&v[0]};

指標陣列和只有一個指標的 n 差在哪裡呢?

原本的 n 存的是第一個元素的位址,如果是指標陣列,每一個元素的位址都有辦法存,而且位址的順序我們也可以自行調整。

int (*q)[3] = &v;

星號因為有括弧會優先解釋,會解釋成一個 pointer。

q 是一個指標,q 存的是三個元素的陣列的記憶體位址,每個元素都是一個整數。

你會發現v 符合這個條件,v 是三個元素的整數陣列,這也是 v 的位址可以存在 q 裡面。

q 和 n 存的都是位址,不同的是,對 n 來說,該位置住的是 int 整數;對 q 來說,該位置住的是有三個元素的陣列。

程式 1

#include <stdio.h>

int main()
{
    int v[3] ={1, 2, 3};
    printf("%zu\n", sizeof(v));     //sizeof(int[3])=12
    printf("%zu\n", sizeof(v[0]));  //sizeof(int)=4
    printf("%zu\n", sizeof(&v[0])); //sizeof(int*)=8
    printf("%zu\n", sizeof(&v));    //sizeof(int(*)[3])=8

    return 0;
}

輸出結果

12
4
8
8

&v[0] 佔據的記憶體空間的大小和 &v 佔據的記憶體空間的大小一樣,代表我們存第一個元素的位址和我們存整個陣列的第一個開頭的位址所耗費的記憶體空間是一樣的。

不過需要注意的是,大部分型別所佔據的記憶體空間大小是實作的定義,印出來的大小不一定和這裡一樣。

我們要怎麼在函式間傳遞陣列呢?

我們可以直接對陣列取位址,也就是 &v。

程式 2

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

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

然後我們再透過 sizeof(*q)/sizeof((*q)[0]) 換算,這樣我們就可以知道它有多少元素。

如果我們希望在函式間傳遞陣列,我們可以直接對陣列取位址(&v),然後我們把指標傳進來。

這樣做有甚麼好處呢?我們可以通過 q 這個指標,sizeof(*q)/sizeof((*q)[0]) 來換算它有幾個元素。

在這個範例,sizeof(*q)/sizeof((*q)[0]) 就是 12。

q 本身是一個指標,存的是 v 的位址,*q 代表的是 v 陣列,(*q)[0] 其實也是 v[0]

sizeof(int [3])/sizeof(int) ,整個元素的大小除以一個元素的大小就是 3。

Leave a Comment

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