陣列名作為函數引數傳遞,C語言陣列作為函數引數傳遞詳解

2020-07-16 10:04:22
本節開始,先問大家一個問題:“要確定一個一維陣列需要知道哪些資訊?”一個是陣列的首地址,另一個是陣列的長度。這樣就可以唯一地確定一個一維陣列。因為陣列是連續存放的,只要知道陣列的首地址和陣列的長度就能找到這個陣列中所有的元素。

因此,要想通過實參和形參將一個陣列從主調函數傳到被調函數,那麼只需要傳遞這兩個資訊即可。對於一維陣列來說,其陣列名就表示一維陣列的首地址。所以只需要傳遞陣列名和陣列長度這兩個引數就可以將陣列從主調函數傳入被調函數中。

當陣列名作為函數的實參時,形參列表中也應定義相應的陣列(或用指標變數),且定義陣列的型別必須與實引數組的型別一致,如果不一致就會出錯。但形參中定義的陣列無須指定陣列的長度,而是再定義一個引數用於傳遞陣列的長度。所以在傳遞實參的時候,陣列名和陣列長度也只能用兩個引數分開傳遞,而不能寫在一起。因為即使寫在一起,系統在編譯時也只是檢查陣列名,並不會檢查陣列長度。所以陣列長度要額外定義一個變數進行傳遞。

綜上所述,當將陣列從一個函數傳到另一個函數中時,並不是將陣列中所有的元素一個一個傳過來(那樣效率就太低了)。而是將能夠唯一確定一個陣列的資訊傳過來,即陣列名(陣列首地址)和陣列長度。此時主調函數和被調函數操作的就是同一個陣列。

下面來寫一個程式:
# include <stdio.h>
int AddArray(int array[], int n);  //函數宣告
int main(void)
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int size = sizeof(a) / sizeof(a[0]);  /*陣列所占記憶體總大小除以該陣列中一個元素所占記憶體的大小, 從而得到陣列元素的個數*/
    printf("sum = %dn", AddArray(a, size));
    return 0;
}
int AddArray(int array[], int n)  //形引數組中不需要寫長度
{
    int i, sum = 0;
    for (i=0; i<n; ++i)
    {
        sum += array[i];
    }
    return sum;
}
輸出結果是:
sum = 36

再問大家一個問題:“前面講過,當對陣列名使用 sizeof 時可以求出整個陣列在記憶體中所佔的位元組數。那麼上面這個程式中,對被調函數 AddArray 中的陣列 array 使用 sizeof 得到的值會是多少?”

有人會說,實引數組 a 佔 32 位元組,實參 a 傳給形參 array,所以 array 也佔 32 位元組。但實際上,array 只佔 4 位元組。下面寫一個程式看一下:
# include <stdio.h>
int AddArray(int array[]);  //函數宣告
int main(void)
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    AddArray(a);
    return 0;
}
int AddArray(int array[])
{
    printf("sizeof(array) = %dn", sizeof(array));
    return 0;
}
輸出結果是:
sizeof(array) = 4

因為陣列名做函數引數時,只是將實引數組的“首地址”傳給了形引數組。此時被調函數 AddArray 中的陣列 array 本質上是一個指標變數,裡面存放的是主調函數中陣列 a 的地址。指標變數也是一個變數型別。不同於前面所講的其他變數型別,指標變數裡面存放的不是一般的資料,而是地址。在 C 語言中,指標變數所佔的位元組數都是 4。所以對 array 使用 sizeof 求出的就是 4(但有些顯示求出的可能是 8,這跟作業系統有關)。