【C 語言入門】187.在函式間傳遞二維陣列

之前我們說過怎麼在函式間傳遞一維陣列,

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int v[3] = {1,2,3};
    int i;
    for(i =0; i<3;i++){
        printf("%d",v[i]);
    }
    printf("\n");
    return 0;
}

我們也可以這樣表達:

#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;
}

在以上的程式中,print 函式參數的大小其實是不重要的,因為我們傳遞的時候傳遞的其實是指標。

我們之前說過陣列是不能被複製的,因此我們複製的不是陣列,是陣列的位址。

所以 main 函式裡的 v 會被複製一份,變成 print 裡面的 v。

main 裡面的 v 是一個整數的陣列,有 3 個元素,那他是怎麼複製成一個整數的指標呢?

陣列會先隱性轉型成 v[0] 的位址,傳到 print 裡面。

我們來看另一個程式

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

int main()
{
    int v[3][3] ={{1, 2, 3},{4, 5, 6},{7, 8, 9}};
    print(v);
    return 0;
}

print 函式裡的 v 是個陣列不能直接複製,v 其實是一個指標,指向一個陣列。

因此 main 裡面的 v 作為隱性轉型成指標。

main 裡的 v 有 3 個元素,每個元素都是含有 3 個元素的陣列。

我們要把它變成一個指標,指向一個陣列,因此會做一個隱性轉型,轉成 v[0] 的位址。

v 這個陣列可以隱性轉型成第一個元素,也就是 v[0] 的位址。

v[0] 的位址,其實也是三個元素陣列的位址。

就變成了這樣:

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

int main()
{
    int v[3][3] ={{1, 2, 3},{4, 5, 6},{7, 8, 9}};
    print(v);
    return 0;
}

同樣地,我們也可以直接取二位陣列的位址,然後傳整個二維陣列。

類似這樣

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

int main()
{
    int v[3][3] ={{1, 2, 3},{4, 5, 6},{7, 8, 9}};
    print(&v);
    return 0;
}

但是這樣我們無法彈性調整 print 函式裡的 3,於是我們可以換成這樣。

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

int main()
{
    int v[3][3] ={{1, 2, 3},{4, 5, 6},{7, 8, 9}};
    print(v,3);
    return 0;
}

這樣的程式我們可以用在 2X3 的陣列,也可以套用在 3X3 的陣列。

Leave a Comment

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