c 之陣列形參

2022-01-22 10:40:03 字數 1710 閱讀 1088

1.問題,最近看專案log模組,_log模板函式中的乙個引數竟然看蒙x了。函式原形是這樣:

template

void _log(char (&strdest)[size], const char *scetion, const char *key, const char *msg, va_list &parm);

對!就是 char (&strdest)[size]沒有看懂。這個傳進來的是個字串陣列。

2.翻開c++聖經,找到答案。設計模板型別形參中的 非型別形參和陣列引用型別形參。

首先,陣列作為形參,有引用和非引用兩種形式。一般我們使用非引用形式,也就是將形參定義為陣列元素型別的指標,一共有三個等價形式:

1.void func(int *p);

2.void func(int p);

3.void func(int p[10]);

其中第三個顯示的表明 呼叫該函式時,所傳遞的陣列最多有10個元素。但是實際上編譯器會忽略為任何陣列指定的形參長度,換句話說,第三個函式宣告中的10,其實是被編譯器忽略的。

當我們呼叫上邊的函式時,傳遞陣列名時,陣列名會自動轉化為指向陣列第乙個元素的指標。也就是該指標所存放的是陣列第乙個元素的位址。 然後形參複製的是這個指標指向的位址。

然後,當陣列作為形參,採用引用的方式時,形式是這樣:

1.void func(int (&p)[10]);

當呼叫此函式時,必須傳遞的是 具有10個int型元素的陣列。類似這樣

int a[10] = {};

func(a);

如果這樣 int b[2] = {}; func(b); 是不正確的,因為b不是10個元素。當形參是引用型別時,理解引用的含義很重要。引用就是乙個變數的別名,但是終究是該變數自己。

同時,使用引用時,沒有複製的環節,大多時候會節省空間,提公升效率。

3.但是,我們可以看出,以上形式的陣列的引用型形參,是很不方便的。因為傳遞陣列時,存在型別和長度的雙重限制。

那麼有沒有一種方法,能夠解決上述問題呢? 既能用到引用的有點,同時又能避免長度帶來的限制?

答案就是採用 1. 中的模板函式以及使用非型別模板形參。

template

void func(int (&p)[size])

聖經中講到:模板非型別形參是模板定義內部的常量值,在需要常量表示式的時候,可使用非型別形參指定陣列的長度, 當呼叫 func是,編譯器會從陣列的實參計算非型別形參的值,也就是編譯器替我們

計算好了size的值,從而省去我們自己傳遞長度。這樣一來,就可以傳遞陣列元素相同的陣列了,不必擔心長度。從而避免了2中的缺點

這樣一來:

int a[10], b[2];

func(a);func(b)都可以正確呼叫,同時size的值為a和b的陣列長度。   

另外一點需要說明,儘管用了模板的非型別形參,讓我們可以省去陣列長度的限制,但是實際上,編譯器會產生兩個func的例項 func<10>, func<2>.

如果此時宣告 int c[10]; func(c); 此時a和c將使用相同的例項。

這基於: 對於模板的非型別形參而言,求值結果形同的表示式將認為是等價的。

因此 a和c呼叫 func(int (&p)[10]), b呼叫 func(int (&p)[2]).

4.至此,_log函式中的第乙個形參已經弄清--陣列的應用型形參。同時利用模板的非型別形參,除去了陣列長度的限制。

水平有限,歡迎指正錯誤。

C 陣列形參

1.c primer 首先,陣列作為形參,有引用和非引用兩種形式。一般我們使用非引用形式,也就是將形參定義為陣列元素型別的指標,一共有三個等價形式 1.void func int p 2.void func int p 3.void func int p 10 template void log c...

C 陣列形參的傳遞

陣列有兩個特性 傳參的方法 當下有乙個陣列int j 2 我們自寫了乙個函式void findsomeone 要求將陣列引數傳進去。有以下兩種方式 在函式內部使用時,point 即可實現指標的移動 陣列大小 陣列是以指標的形式傳遞給函式的,所以函式並不知道陣列的確切尺寸,因此呼叫者應該為此提供一些資...

7 2 4陣列形參

1.編譯器不會檢查實參陣列的長度 2.通過引用傳遞陣列 void printvalues int arr 10 編譯器檢查實參的大小.3.main 處理命令列選項 code include using namespace std int main int argc,char argv else 4....