C++陣列做函數引數詳解

2020-07-16 10:04:37
程式設計師通常會想要編寫函數來處理陣列中的資料。例如,可以編寫函數將值放入陣列中、在螢幕上顯示陣列的內容、累計陣列的所有元素或計算其平均值。通常,這樣的函數將接收一個陣列作為引數。

當某個陣列的單個元素被傳遞給一個函數時,它就像任何其他變數一樣被處理。例如,下面程式顯示了一個迴圈:
//This program demonstrates that an array element
//can be passed to a function like any other variable.
#include <iostream>
using namespace std;

void showValue(int); // Function prototype

int main()
{
    const int ARRAY_SIZE = 8;
    int collection[ARRAY_SIZE] = {5, 10, 15, 20, 25, 30, 35, 40};
    for (int index = 0; index < ARRAY_SIZE; index++)
        showValue(collection[index]);
    cout << endl;
    return 0;
}
void showValue(int num)
{
    cout << num << " ";
}
程式輸出結果:

5 10 15 20 25 30 35 40

此程式中,每次執行迴圈時都會將 collection 陣列的一個元素傳遞給 showValue 函數。因為 collection 陣列的元素是 int 整數,所以每次呼叫時都會將一個 int 值傳遞給 showValue 函數。請注意這在 showValue 函數原型和函數頭中是如何指定的。實際上,showValue 只知道它正在接收一個 int,至於資料是不是來源於一個陣列則無關緊要。

由於 showValue 函數只是顯示 num 的內容,並不需要直接處理陣列元素本身,所以陣列元素可以通過值傳遞給它。如果函數需要存取原始陣列的元素,則它們將需要通過參照進行傳遞。

如果函數被編寫為接收整個陣列作為實參,則形參的設定將迥然不同。在下面的函數定義中,形參 num 之後是一組空的方括號。這表明實參將會是整個陣列,而不是單個值。
void showValues (int nums[], int size)
{
    for (int index = 0; index < size; index++)
        cout << nums[index] << " ";
    cout << endl;
}
請注意,與包含值的陣列一起,陣列的大小也被傳遞給 showValues。這樣就可以知道需要處理多少個值。

還要注意在 nums 的方括號內沒有大小宣告符,這是因為 nums 實際上不是一個陣列,它只是一個接收陣列地址的特殊變數。當整個陣列傳遞給一個函數時,它不會被通過值傳遞。

想象一下,如果在每次傳遞給一個函數時都需要建立一個 10000 元素陣列的副本,那該需要消耗掉多少 CPU 時間和記憶體!所以,被傳遞的只能是陣列的起始記憶體地址。這與通過參照將變數傳遞給函數類似,只不過在這種情況下不使用 &。

下面程式演示了函數 showValues 如何接收整個陣列的地址,這樣它就可以存取和顯示其所有元素的內容:
// This program shows how to pass an entire array to a function.
#include <iostream>
using namespace std;

void showValues(int intArray[], int size); // Function prototype
int main()
{
    const int ARRAY_SIZE = 8;
    int collection[ARRAY_SIZE] = {5, 10, 15, 20, 25, 30, 35, 40};
    cout << "The array contains the valuesn";
    showValues(collection, ARRAY_SIZE);
    return 0;
}
void showValues (int nums[], int size)
{
    for (int index = 0; index < size; index++)
    cout << nums[index] << " ";
    cout << endl;
}
程式輸出結果為:

The array contains the values
5 10 15 20 25 30 35 40

仔細觀察第 5 行中的 showValues 原型和第 14 行中的函數頭,在這兩種情況下,都有一對方括號緊跟第一個引數名稱,這讓程式知道這個形參將接收一個陣列的地址。如果函數原型沒有使用形參名稱,那麼它看起來將像這樣:

void showValues(int [],int);

這仍然表示第一個 showValues 形參將接收一個整數陣列的地址,第二個形參則接收一個整數值。

再來看下面的語句,在程式的第 11 行如何呼叫 showValues 函數:

showValues(collection, ARRAY_SIZE);

第一個實參是傳遞給函數的陣列的名稱。請記住,在 C++ 中,沒有方括號和下標的陣列的名稱實際上是陣列的開始地址。在這個函數呼叫中,collection 陣列的地址被傳遞給函數。第二個實參是該陣列的大小。

在 showValues 函數中,collection 陣列的開始地址被複製到 nums 形參變數中。nums 變數然後被用於參照 collection 陣列。圖 1 說明了 collection 陣列和 nums 形參變數之間的關係。當顯示 nums [0] 時,實際上螢幕中出現的是 collection [0] 的內容。


圖 1 collection 陣列和 nums 形參變數之間的關係