【C語言入門】163.在函式間傳遞陣列 (使用指標)

上一篇文章,我們討論了關於陣列和指標之間的關係。

今天我們來看看,在函式間傳遞陣列的時候,指標扮演的是怎麼樣的一個角色。

#include <stdio.h>
int maxv(int []);


int main()
{
    int a[3] = {3,9,7};
    printf("Max: %d\n", maxv(a));
    return 0;
}

int maxv(int v[3]){
    int max = v[0],i;
    for(i=1;i<3;i++){
        if(v[i] > max){
            max = v[i];
        }
    }
    return max;
}

這個範例有個函式叫 maxv,maxv有個參數是整數的陣列 b,他會求得這個 b 陣列裡面、三個元素中,最大的那一個,把最大的那一個回傳回去。

在 main 執行的時候,會產生一個 a 陣列,a 陣列有三個元素。

  int a[3] = {3,9,7};

接著我去呼叫 maxv 這個函式,把 a 陣列傳給他。

maxv 就會對 a 陣列裡的 a[0]、a[1]、a[2] 找出最大值,就會把其中最大的 9 回傳給 main。

我們之前有提到,陣列是不能被複製的,a 陣列不能直接被複製成 maxv 函式裡面的 v 陣列的。

如果我在函式中傳的參數改成沒有大小的陣列,這個程式還是可以運作的。

int maxv(int v[]){
    int max = v[0],i;
    for(i=1;i<3;i++){
        if(v[i] > max){
            max = v[i];
        }
    }
    return max;
}

這是因為其中的 v 根本不是陣列,它是一個指標。

我們寫成這樣:

int maxv(int v[])

在 C 語言中其實是這個意思:

int maxv(int *v)

是不是很有意思?

為甚麼寫成陣列的形式和寫成指標的形式,函式內都不需要改?

陣列的形式:

int maxv(int v[3])

指標的形式:

int maxv(int *v)

這也是我們在上一篇文章提到的,指標也可以使用中括弧這個下標運算子。

在呼叫的時候,主程式中的 maxv(a)不是直接傳給 maxv。

主程式中 maxv(a) 的 a 是整數的陣列,maxv 中的 v 則是整數的指標。

整數的陣列可以存到一個整數的指標裡嗎?

上次我們提過,整數的陣列是不能直接存到一個整數的指標裡面的,所以會做一個隱性轉型,主程式中 maxv(a) 的 a 會變成 &a[0]。

一個整數的陣列,可以隱性轉型成一個整數元素的位置,這個位置呢是第一個元素的位置。

maxv 函式中的 v 是 a[0] 的位置。

v[0] 是甚麼呢?

v[0] 也就是 (v+0) 再取值,也就是 (v+0),再取星號(*)。

v 一開始存的是 a[0] 的位址。

接著我們來延伸一下,我們先看一下程式。

#include <stdio.h>
int maxv(int[]);

int main()
{
    int a[3] = {3,9,7};
    printf("Max: %d\n", maxv(a));
    int a[3] = {3,9,1,2,7};
    printf("Max: %d\n", maxv(b));
    return 0;
}

int maxv(int v[]){
    int max = v[0],i;
    for(i=1;i<3;i++){
        if(v[i] > max){
            max = v[i];
        }
    }
    return max;
}

假設我們有一個陣列叫 b,它有 5 個元素,分別是 b[0] 到 b[4]。

如果是 b,我們希望它可以數到 5,如果是 a ,我們希望它可以數到 3。

這時候我們可以用另一個參數 N,可以看以下程式。

#include <stdio.h>
int maxv(int[], int);


int main()
{
    int a[3] = {3,9,7};
    printf("Max: %d\n", maxv(a,3));
    int b[5] = {3,9,1,2,7};
    printf("Max: %d\n", maxv(b,5));
    return 0;
}

int maxv(int v[], int N){
    int max = v[0],i;
    for(i=1;i<N;i++){
        if(v[i] > max){
            max = v[i];
        }
    }
    return max;
}

N 代表這個陣列有多大,也會決定 maxv 裡的迴圈執行幾次。

當我把 a 和 3 傳給 maxv ,v 其實存的就是 a[0] 的位址。

v[0] 就是 a[0],v[1] 就是 a[i]。

如果傳的是 b 和 5 也一樣。

我們傳的參數 a 或 b 其實是一個位址,所以需要補大小 (數字 5 或 3)。

這樣,我們就可以處理任意大小的陣列。

使用指標的時候也可以用中括弧表示。

小結:我們把陣列當引數傳,我們的參數是一個指標。另外,在函式內部,指標會作為一個陣列使用。

Leave a Comment

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