數組無法被拷貝,所以函數無法返回一個數組。但是,函數可以返回數組的指針或引用。下面是返回數組的指針或引用的方式:
typedef int arrT[10]; //arrT是一個類型別名,表示的類型是含有10個整數的數組 using arrT=int[10]; //arrT的等價聲明 arrT* func(int i); // func返回一個指向含有10個整數的數組的指針
其中arrT是含有10個整數的數組的別名、因為我們無法返回數組,所以將返回類型定義成數組的指針。因此,func函數接受一個int實參,返回一個指向包含10個整數的數組的指針。
聲明一個返回數組指針的函數
int arr[10]; //arr是一個含有10個整數的數組 int *pi[10]; //p1是一個含有10個指針的數組 int (*p2)[10]=&arr; //p2是一個指針,它指向含有10個整數的數組
和這些聲明一樣,如果我們想定義一個返回數組指針的函數,則數組的維度必須跟在函數名字之后。然而,函數的形參列表也跟在函數名字后面且形參列表應該先於數組的維度。因此,返回數組指針的函數形式如下所示:
Type (*function(parameter_list))[dimension]
類似於其他數組的聲明,Type表示元素的類型,dimension表示數組的大小。(*function(patameter_list))兩端的括號必須存在,就像我們定義p2時兩端必須有括號一樣。如果沒有這對括號,函數的返回類型將是指針的數組。
舉個具體的例子,下面這個func函數的聲明沒有使用類型別名:
int (*func(int i))[10];
可以按照以下的順序來逐層理解該聲明的含義:
- func(int i)表示調用func函數時需要一個int類型的實參。
- (*func(int i))意味着對我們可以對函數調用的結果執行解引用操作。
- (*func(int i))[10]表示解引用func的調用將得到一個大小是10的數組。
- int (*func(int i))[10]表示數組中的元素是int類型。
使用尾置返回類型
在C++11新標准中還有一種可以簡化上述func聲明的方法,就是使用尾置返回類型(trailing return type)。任何函數的定義都能使用尾置返回,但是這種形式對於返回類型比較復雜的函數最有效,比如返回類型是數組的指針或者數組的引用。尾置返回類型跟在形參列表后面並一個->符號開頭。為了表示函數真正的返回類型跟在形參列表之后,我們在本應該出現返回類型的地方放置一個auto:
auto func(int i)->int(*)[10];
因為我們把函數的返回類型放在了形參列表之后,所以可以清楚地看到func函數返回的是一個指針,並且該指針指向了含有10個整數的數組。
使用decltype
還有一種情況,如果我們知道函數返回的指針將指向哪個數組,就可以使用的decltype關鍵字聲明返回類型。例如,下面的函數返回一個指針,該指針根據參數i的不同指向兩個已知數組中的某一個:
int odd[]={1,3,5,7,9}; int even[]={0,2,4,6,8}; //返回一個指針,該指針指向含有5個整數的數組 decltype(odd) *arrPtr(int i) { return (i%2)?&odd:&even; }
arrPtr使用關鍵字decltype表示它的返回類型是個指針,並且該指針所指的對象與odd的類型一致。因為odd是數組,所以arrPtr返回一個指向含有5個整數的數組的指針。有一個地方需要注意:decltype的結果是個數組,要想表示arrPtr返回指針還必須在函數聲明時加一個*符號。