c++ 参数传递
參數(shù)傳遞:
形參(parameter)和實參(argument):
int num (int a, int b); int num (int a, int b){return a+b; }//在函數(shù)的聲明或者定義里,由由0個或多個形參組成的列表。int main(){int n=1,m=1;cout<<num(n,m);//我們用調(diào)用運(yùn)算符來執(zhí)行函數(shù),調(diào)用運(yùn)算符形式是個圓括號,圓括號內(nèi)是由逗號隔開的實參列表。我們用實參初始化函數(shù)的形參。 }形參的類型決定了形參實參交互的方式,如形參是引用類型,他將綁定到對應(yīng)的實參上,引用形參是它對應(yīng)實參的別名。否則,將實參的值拷貝后賦給形參。
當(dāng)形參是引用類型,我們說,它對應(yīng)的實參被引用傳遞(passed by reference)或者函數(shù)被傳引用調(diào)用(called by reference)。
當(dāng)實參的值被拷貝給形參時,我們說,這樣的實參被值傳遞(passed by value)或者函數(shù)被傳值調(diào)用(called by value)。
傳值參數(shù):
初始化一個非引用類型變量,初始值被拷貝給變量,對變量的改動不會影響初始值。
int n = 0; int i = n; i =1; cout << n;//輸出0,i的值改變,n的值不變。指針形參:指針的行為和其他非引用類型一樣,當(dāng)執(zhí)行指針拷貝操作,拷貝的是指針的值。拷貝之后,兩個指針是不同的指針。因為通過指針,我們可以間接訪問它所指對象,所以通過指針可以修改它所指對象的值。
void reset(int *ip){*ip = 0;//只改變了指針?biāo)笇ο蟮闹怠?/span>ip = 0;//這里改變的只是ip的局部拷貝,實參并未改變 } int i = 1; reset(&i);//改變i的值而非i的地址 cout << "i = " << i <<endl;//輸出i=0。 —————————————————————————————————————— //實參類似于下面:(q) int i = 1; int *q = &i; //形參類似于下面:(p) int n = 0; int *p = &n; //實參調(diào)用形參類似與下面: p = q;//p指向了i *p = 2;//通過p改變了i,但是此時q并未改變。傳引用參數(shù):
對于引用的操作,實際上是作用在引用所引的對象上。通過引用形參,允許函數(shù)改變一個或多個實參的值。
void reset (int &i){//形參i僅僅是實參j的又一個名字,在reset內(nèi)部對i的使用即是對實參j的使用。i = 0;//改變了i所引對象的值。 } int j=1; reset(j);//j采用傳引用方式,因此他的值被改變。 cout<<j<<endl;//輸出j=0。傳引用參數(shù):當(dāng)形參是頂層const時,傳給他常量對象或者非常量對象都是可以的。
const int ci = 1; int i = ci;//正確,當(dāng)拷貝ci時,忽略了它的頂層const。 int *const p = &i;//const是頂層的,不能給p賦值。 *p = 0;//正確,通過p改變對象內(nèi)容是允許的。//在c++中,允許定義若干具有相同名字的函數(shù),不過前提是不同函數(shù)的形參列表應(yīng)該具有明顯區(qū)別。 void fcn(const int i){}//調(diào)用fcn函數(shù)時,既可以傳入const int也可以傳入int。 void fcn(int i){}//此時再寫一個函數(shù)定義,會報錯誤,因為重復(fù)定義了fcn(int)。傳引用參數(shù):我們可以用非常量初始化一個底層const對象,但無法用一個底層const對象初始化一個非常量。如果形參是一個非常量,那么實參不能是一個底層const對象
同樣的初始化規(guī)則應(yīng)用到參數(shù)傳遞上:
void reset(int *ip){...}void reset(int &i){...}string::size_type find_char(const string &s,char c,string::size_type &occurs){...}int i = 0;const int ci = i;string::size_type ctr = 0;reset(&i);//正確,調(diào)用形參類型是int*的reset函數(shù)。reset(&ci);//錯誤,不能用指向const int對象的指針初始化int*。reset(i);//正確,調(diào)用形參類型是int&的reset函數(shù)。reset(ci);//錯誤,不能把普通引用綁定到const對象ci上。reset(42);//錯誤,不能把普通引用綁定到字面值上。reset(ctr);//錯誤,類型不匹配find_char("hello world!",'o',ctr);//正確,find_char第一個形參是對常量的引用。盡量使用常量引用:
把函數(shù)不會改變的形參定義成普通的引用會給函數(shù)調(diào)用者一種誤導(dǎo),即函數(shù)可以修改它實參的值。此外,使用引用而非常量引用也會極大限制函數(shù)所能接受實參類型。不能把const對象、字面值、或者需要類型轉(zhuǎn)換的對象傳遞給普通的引用形參。
string::size_type find_char(string &s,char c,string::size_type &occurs){...} find_char("hello world!",'o',ctr);//編譯時發(fā)生錯誤,因為不能把普通引用綁定到const對象上。應(yīng)該把string &s修改為const string &sbool is_sentence(const string &s){string ::size_type ctr = 0;return find_char(s,'.',ctr) == s.size() - 1 && ctr == 1;//編譯時發(fā)生錯誤,因為s是常量引用,但find_char被定義成只接受普通引用。修改的話,需要改正find_char的形參,應(yīng)該把find_char形參的string &s修改為const string &s }總結(jié)
- 上一篇: Linux Makefile
- 下一篇: c++primer 3.2,3.3练习题