[英]How is C++ function's default parameter passed?
說我有以下代碼:
#include <iostream>
using namespace std;
int defaultvalue[] = {1,2};
int fun(int * arg = defaultvalue)
{
arg[0] += 1;
return arg[0];
}
int main()
{
cout << fun() << endl;
cout << fun() << endl;
return 0;
}
結果是:
2
3
這是有道理的,因為指針*arg
操縱了數組的defaultvalue
。 但是,如果我將代碼更改為:
#include <iostream>
using namespace std;
int defaultvalue[] = {1,2};
int fun(int arg[] = defaultvalue)
{
arg[0] += 1;
return arg[0];
}
int main()
{
cout << fun() << endl;
cout << fun() << endl;
return 0;
}
但結果仍然是:
2
3
而且,當我打印出defaultvalue
:
cout << defaultvalue[0] <<endl;
結果是3。
我的問題是,在第二個例子中,函數參數是否應該通過值傳遞,以便arg
更改對defaultvalue
沒有影響?
我的問題是,在第二個例子中,函數參數是否應該通過值傳遞,以便arg的更改對defaultvalue沒有影響?
沒有。
按值傳遞數組是不可能的(非常感謝C!)因此,作為“妥協”(讀取:設計失敗),函數參數列表中的int[]
實際上意味着int*
。 所以你的兩個程序完全相同。 甚至寫int[5]
或int[24]
或int[999]
實際上也意味着int*
。 荒謬,不是嗎?!
在C ++中,我們更喜歡將std::array
用於數組:它是一個數組包裝類,它具有適當的對象語義,包括可復制。 您可以通過值將它們傳遞給函數。
實際上, std::array
主要是為了使這些愚蠢和令人驚訝的本機數組語義過時而引入的。
當我們聲明這樣的函數時
int func(int* arg);
或這個
int (func(int arg[])
它們在技術上是一樣的。 這是表達性的問題。 在第一種情況下,API作者建議該函數應該接收指向單個值的指針; 而在第二種情況下,它表明它想要一個數組(一些未指定的長度,例如可能以nullptr結尾)。
你也可以寫
int (func(int arg[3])
這將再次在技術上相同,只是它會暗示API用戶他們應該傳遞至少3個元素的int
數組。 在這些情況下,編譯器不會強制執行任何這些添加的修飾符。
如果你想將數組復制到函數中(以非黑客方式),你首先要在調用代碼中創建它的副本,然后再傳遞它。 或者,作為更好的選擇,使用std::array
(由@LightnessRacesinOrbit建議)。
正如其他人所解釋的那樣,當你把int arg[]
作為函數參數時,這些括號里面的內容並不重要(你甚至可以做int arg [5234234]並且它仍然可以工作]因為它不會改變事實上,它仍然只是一個普通的int *指針。
如果你真的想確保一個函數采用一個數組[],最好將它傳遞給它
template<size_t size>
void func (const int (&in_arr)[size])
{
int modifyme_arr[100];
memcpy(modifyme_arr, in_arr, size);
//now you can work on your local copied array
}
int arr[100];
func(arr);
或者如果你想要100個元素
void func (const int (&arr)[100])
{
}
func(arr);
這些是傳遞一個簡單數組的正確方法,因為它會保證你得到的是一個數組,而不僅僅是一個隨機的int *指針,該函數不知道它的大小。 當然你可以傳遞一個“計數”值,但是如果你犯了一個錯誤並且它不是正確的那個怎么辦? 然后你得到緩沖區溢出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.