某些時候,有必要令區域性變數的生命週期貫穿函式呼叫之後的時間。可以將區域性變數定義成static型別從而獲得這樣的物件。區域性靜態物件(local static object)在程式的執行路徑第一次經過物件定義語句是初始化,並且直到程式終止才被銷毀,在此期間及時物件所在的函式結束執行也不會對它有影響。
舉個例子,下面的函式統計它自己被呼叫了多少次:
size_t count_calls()
int main()
和其他變數一樣,形參的型別決定了形參和實參的互動方式。如果形參是引用型別,它將繫結到對應的實參是,否則,將實參的值拷貝後賦給形參。
void reset(int &i)
int j = 42;
reset()j;
cout
<< "j="
比如,我們準備編寫乙個函式比較兩個string物件的長度。因為string物件可能會非常長,所以應該避免直接拷貝它們~
bool isshorter(const
string &s1, const
string &s2)
c++語言允許將變數定義成陣列的引用,基於同樣的道理,形參也可以是陣列的引用。此時,引用形參繫結到對應的實參上,也就是繫結到陣列上:
void print(int ($arr)[10]);
int k[10] = ;
print(&i); //wrong
print(j); //wrong
print(k); //right
在c++語言中實際沒有真正的多維陣列,所謂多維陣列其實是陣列的陣列。
和所以陣列一樣,當將多維陣列傳遞給函式時,真正傳遞的是指向陣列首元素的指標。因為我們處理的是陣列的陣列,所以首元素本身就是乙個陣列,指標就是乙個指向陣列的指標。陣列第二維(以及後面所以維度)的大小都是陣列型別的一部分,不能省略:
void print(int (*matrix)[10]. int rowsize)
再次強調,*matrix兩端括號不可少~
int *matrix[10]; //10個指標構成的陣列
int (*matrix)[10]; //指向含有10個整數的陣列的指標
我們也可以使用陣列的語法定義函式,此時編譯器會一如既往地忽略掉第乙個維度,所以最好不要把它包括在形參列表內:
//等價定義
coid print(int matrix[10], int rowsize)
函式完成後,它所占用的儲存空間也隨之被釋放掉。因此,函式終止意味著區域性變數的引用將指向不再有效地記憶體區域:
//嚴重錯誤:這個函式試圖返回區域性物件的引用
const
string &manip()
c++11新標準規定,函式可以返回花括號包圍的值的列表。類似其他返回結果,此處的列表也用來對表示函式返回的臨時量進行初始化。如果列表為空,臨時量執行值初始化;否則,返回的值由函式的返回型別決定。
vector
process();
else
if (expected == actual)
return ;
else
return ;
}
如果函式返回的是內建型別,則花括號包圍的列表最多包含乙個值,而且該值所佔空間不應該大於目標型別的空間。如果函式返回的是類型別,有類本身定義初始值如何使用。
因為陣列不能被拷貝,所以函式不能返回陣列。不過,函式可以返回陣列的指標或引用。
這個比較麻煩,又乙個簡單的辦法~就是使用型別別名
typedef
int arrt[10]; //arrt是乙個型別別名,它表示的型別是含有10個整數的陣列
using arrt = int[10]; //arrt的等價宣告
arrt* func(int i); //func返回乙個指向含有10個整數的陣列的指標
如果不用別名,我們來看看怎麼辦
我們宣告指向陣列的指標是這樣宣告的:
int (*p2)[10];
同理我們也這樣宣告函式
int (*func(int i))[10];
可以按照以下的順序來逐層理解該宣告的含義: C 之全域性物件,區域性物件,靜態區域性物件
先說兩個概念 作用域 scope 和生命週期 lifetime 作用域 名字的作用域指的是知道該名字的程式文字區域 生命週期 物件的生命週期指在程式執行過程中物件存在的時間 全域性物件,顧名思義是全域性的物件,其作用域是整個程式文字,其物件的宣告週期是整個程式的執行過程 區域性物件 一般說的區域性變...
C 之區域性物件(自動物件和靜態區域性物件)
1 自動物件 預設情況下,區域性變數的生命期侷限於所在函式的每次執行期間。只有當定義它的函式被呼叫時才存在的物件稱為自動物件。自動物件在每次呼叫函式時建立和撤銷。該型別區域性變數儲存在棧上,在動態儲存區。區域性變數所對應的自動物件在函式控制經過變數定義語句時建立。如果在定義時提供了初始化,那麼每次建...
非區域性靜態物件
使用未被初始化的物件無異於蠻幹。建構函式可以確保物件在建立時被初始化,難道不是這樣嗎?是,也不是。在某個特定的被編譯單元 即原始檔 中,可能一切都不成問題 但如果在某個被編譯單元中,乙個物件的初始化要依賴於另乙個被編譯單元中的另乙個物件的值,並且這第二個物件本身也需要初始化,事情就會變得更複雜。例如...