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