2017-06-04 104 views
-2

C++中的函數原型聲明中的變量被視爲全局範圍嗎?函數原型變量作用域C++

E.g.在下面的腳本中,我們聲明瞭一個函數原型readArray,它將數組integerArray和整數maxNumElements作爲輸入並返回用戶提供的元素數。當然,從main調用readArray函數。我的問題是,如果displayArray可以通過提供用戶插入的最大元素數來打印在readArray中編輯的數組。總之,全球是integerArraynumElements

/* prototype declaration*/ 
int readArray (int integerArray [], int maxNumElements); 
void displayArray(int integerArray[], int numElements); 

int main() 
{ 
    int inputValues[128]; /*the array to be read*/ 
    int numberOfValues = readArray(inputValues, 128); 
    displayArray(inputValues, numberOfValues); 
    return 0; 
} 

int readArray(int integerArray[], int maxNumElements) 
{ 
    int numberOfValues; 
    for (numberOfValues = 0; numberOfValues < maxNumElements; numberOfValues++) 
    { /*take integers as input from user and insert into array */ 
     /*return the number of elements the user as provided*/ 
    } 
    return numberOfValues; 
} 

void displayArray(int integerArray[], int numElements) 
{ /*print the array*/ 
    for (int = 0; i < numElements; i++) 
    { 
     cout << i << ":" << integerArray[i] << endl; 
    } 
    cout << endl; 
} 
+2

每個函數都有自己的私有和本地*副本*的變量。 –

+1

不要亂用原始數組。我們已經在C++標準中有'sdt :: array'和'std :: vector'實現。 –

+0

可能不是一個真正的問題。你可以做到這一點,看看會發生什麼。這是我們應該做的任何易於測試的行爲。 –

回答

-1

我不認爲將函數參數作爲變量說起來是有意義的。它們基本上充當佔位符,用於在調用它時提供給該功能的數據。

因此,在您的示例中,您不是在integerArray上運行,而是在運行​​指向的數據,您在main()中聲明的數據。 inputValue是變量,而不是integerArray

在你的情況下,你碰巧正在做所謂的呼叫參考。即你的函數原型正在接收一個指向一個整數的指針。當您通過指針inputValues到readArray:

int numberOfValues = readArray(inputValues, 128); 

那麼你給它的地址inputValues。然後readValues將在inputValues指向的內存區域上運行。

因此,displayArray將在您的示例中顯示readArray編輯的數據。

請注意,這是您通過引用進行調用的結果,而不是函數參數在某種意義上在全局範圍內。

如果函數原型已經看起來是這樣的:

int readArray (vector<int> integerArray); 
void displayArray(vector<int> integerArray); 

然後displayArray不會被打印的integerArray在任何意義上的內容。當你打電話給readArray時,你會按值進行呼叫:它會得到inputValues的副本(在這種情況下,它將被聲明爲vector<int> inputValues),並且當函數調用返回時,將保留原始值inputValues和在這種特殊情況下,displayArray將打印一個空向量。

+1

函數參數實際上只是一種特殊的局部變量,並且在函數被調用時被初始化。它們可以在寄存器或實際內存中,就像其他本地變量一樣。另外,如果你仔細想一想,_all_變量只是數據的佔位符;它們實際上只是我們使用的名稱,所以我們不必直接使用寄存器和內存地址本身。 –

+0

我想你是對的。我只是試圖去看看OP,它並不總是一個有用的概念,就像「正常」變量一樣思考函數參數,特別是當你正在查看函數聲明時。特別是在他的例子中,他可能會得到一個印象,即函數參數在某種程度上具有全局範圍,但實際上它可能看起來就像它在特定的例子中那樣,這是由於參考引用。我認爲這是令他困惑的事情。我希望我沒有加入這個混淆之中,意圖是相反的。 – ThorOdinsson

+1

啊,好的。只是想澄清他們仍然是變數,以澄清任何潛在的誤解。 –

-2

不,它們不是全球性的。函數在接收參數時創建本地副本。您可以通過在複製構造函數中使用cout創建自己的類來驗證這一點。將該類的對象傳遞給一個函數(按值),您將看到正在調用的複製構造函數。在C++中,更好的方法是使用std :: array和std :: vector。對於非原始類型和巨大的數據塊,傳遞值也不是一個明智的想法。始終按「地址」(指針)或「參考」(您可能想要了解std :: ref)傳遞參數

+1

*「總是通過」address「或」reference「傳遞參數」* const int&param'如何比int int param更好? – HolyBlackCat

+1

請注意,對於簡單類型(例如內置類型,帶簡單構造函數的類型或可以放在單個寄存器中的類型),通過值傳遞通常更高效,除非您明確需要修改原始類型。另外請注意,由於移動語義(您可以移動本地副本),因此無論如何您都要創建副本,傳遞值可以更有效。 –

+0

@HolyBlackCat「const int&param」 - >這有兩件事。首先,如果你不打算改變函數中param的值,並且想避免意外地改變它的值,那麼接收一個參數爲const是非常好的做法。其次,「&param」。將參數作爲參考而不是值接受也是一種非常好的做法,但當參數是「大」類型時,如類/結構對象更有意義。它避免了大塊的本地副本。在像int這樣的基本類型的情況下,這不會產生很大的差異。但仍然「const int&param」不會造成任何傷害。 –

0

範圍是關於名稱可見的地方。例如,全球範圍內的名稱從其宣佈地點到申報單位翻譯單位末尾處都是可見的;本地範圍內的名稱從它們的聲明點到聲明塊的末尾是可見的(即截至})。僅在原型中才能看到函數原型中的參數名稱。傳遞給函數的參數的名稱在整個函數中都是可見的。

所以,從你的代碼:

int readArray(int integerArray[], int maxNumElements); 

名稱integerArraymaxNumElements沒有這個原型外可見。

int readArray(int integerArray[], int maxNumElements) { 
    // ... 
} 

名稱integerArraymaxNumElements是thoughout函數定義可見,但不是外面。

int displayArray(int intgerArray[], int numElements) { 
    // ... 
} 

名稱integerArraynumElements是thoughout函數定義可見,但不是外面。

名稱integerArray的三個用途彼此沒有聯繫;就好像他們每個人都是一個完全不同的名字一樣。