老生常談C++中實(shí)參形參的傳遞問(wèn)題
函數(shù)中參數(shù)的傳遞
這里說(shuō)的傳遞當(dāng)然是指 實(shí)參是如何傳遞給形參的啦
還挺復(fù)雜的~~~~~~~~⊙﹏⊙b汗,這里講述了4種參數(shù)傳遞的情況和注意事項(xiàng):
1.非引用形參
這是最普通,也是最簡(jiǎn)單的形參傳遞了。
參數(shù)傳遞,即是使用實(shí)參副本(注意啊,是副本,不是實(shí)參本身)來(lái)初始化形參;
因此,在函數(shù)體內(nèi)對(duì)形參的修改不會(huì)影響實(shí)參的值。
如果形參是指針類(lèi)型的,那么函數(shù)體內(nèi)是否可以修改指針?biāo)赶虻膶?duì)象的值呢?
如果您產(chǎn)生這樣的疑問(wèn),表示您很有想法~~~
答案是~~~需要分情況討論。
如果函數(shù)的形參是非const類(lèi)型的指針,則函數(shù)可以通過(guò)指針實(shí)現(xiàn)賦值,修改指針?biāo)赶驅(qū)ο蟮闹怠?/p>
所以,如果需要保護(hù)指針指向的值,則形參需定義為指向const對(duì)象的指針(注意了,這里的指針依然是非const型的,只是其指向的對(duì)象是const型的):
void use_ptr(const int *p)
{
     //use_ptr這個(gè)函數(shù)可以讀指針p所指向的對(duì)象,但是不可以修改該對(duì)象的值
}
const形參
如果函數(shù)使用的是非引用非const形參,則既可以給該它傳遞const實(shí)參,也可傳遞非const實(shí)參。
如果函數(shù)使用的是非引用const形參,也是既可以給該它傳遞const實(shí)參,也可傳遞非const實(shí)參。那么這兩者的差別是什么呢?對(duì)于后者,函數(shù)連實(shí)參的局部副本都不可以改變了。下面是第二種情況的一個(gè)例子: void fcn(const int i) {}
復(fù)制實(shí)參的局限性:復(fù)制實(shí)參不是在所有的情況下都適合,不是一復(fù)制實(shí)參的情況如下:
1.當(dāng)需要在函數(shù)中修改實(shí)參的值時(shí)
2.當(dāng)需要以大型對(duì)象作為實(shí)參傳遞時(shí)。對(duì)實(shí)際的應(yīng)用而言,復(fù)制對(duì)象所付出的時(shí)間和存儲(chǔ)空間代價(jià)往往過(guò)大
3.當(dāng)沒(méi)有辦法實(shí)現(xiàn)對(duì)象的復(fù)制時(shí)
對(duì)于上述幾種情況,有效的解決辦法是將形參定義為引用或指針類(lèi)型。
(終于說(shuō)完這個(gè)最簡(jiǎn)單的傳遞方式了,╮(╯▽╰)╭)
2.引用形參
引用形參的用法:
1.讓函數(shù)修改實(shí)參的值
2.向主調(diào)函數(shù)返回額外的結(jié)果(本來(lái)return就可以返回一個(gè)值給主調(diào)函數(shù),而且引用參數(shù)可以改變實(shí)參的值,所以相當(dāng)于返回了額外的結(jié)果)
3.利用const引用避免復(fù)制(當(dāng)向函數(shù)傳遞大型對(duì)象時(shí),需要使用引用來(lái)提高效率,如果使用引用形參的唯一目的是避免復(fù)制實(shí)參,則應(yīng)將形參定義為const引用)
這是一個(gè)不適宜復(fù)制實(shí)參的例子,該函數(shù)希望交換兩個(gè)實(shí)參的值
    void swap (int v1,int v2)
    {
      int tmp=v1;
      v2=v1;
      v1=tmp;
    }
這個(gè)例子期望改變實(shí)參本身的值,但是swap無(wú)法影響實(shí)參本身,執(zhí)行swap時(shí),指示交換了其實(shí)參的局部副本,對(duì)實(shí)參根本沒(méi)有改變。解決的方法是:將形參定義為引用類(lèi)型。
void swap (int &v1,int &v2)
{
      int tmp=v1;
      v2=v1;
      v1=tmp;
}
當(dāng)調(diào)用swap(i,j)時(shí),i和j的值才真正實(shí)現(xiàn)了交換。
更靈活的指向const的引用
應(yīng)該將不需要修改的引用形參定義為const引用。普通的非const引用形參在使用時(shí)不大靈活。非const引用形參既不能用const對(duì)象初始化,也不能用字面值或者產(chǎn)生右值的表達(dá)式實(shí)參初始化。(如果函數(shù)的形參是非const引用形參,表示在函數(shù)體內(nèi)可能會(huì)修改該形參值,即會(huì)修改實(shí)參的值,因此不可以用const對(duì)象來(lái)做實(shí)參傳遞給這樣的函數(shù),所以不靈活。)
傳遞指向指針的引用
如果想編寫(xiě)一個(gè)與前面交換兩個(gè)整數(shù)的swap類(lèi)似的函數(shù),實(shí)現(xiàn)兩個(gè)指針的交換。已知需用*定義指針,用&定義引用,問(wèn)題在于,如何將這兩個(gè)操作符結(jié)合起來(lái)一獲得指向指針的引用。
//交換兩個(gè)指向整形的指針的值
void ptrswap(int *&v1,int *&v2)
{
       int=*tmp=v2;
       v2=v1;
       v1=tmp;
 }
形參int *&v1的定義,應(yīng)該從右至左的理解:v1是一個(gè)引用,與指向int型對(duì)象的指針相關(guān)聯(lián)。也就是說(shuō),v1只是傳遞ptrswap函數(shù)的任意指針的別名。
3.vector和其他容器類(lèi)型的形參
由于復(fù)制vector會(huì)使得效率降低,多以如果形參是vector的話,我們常常將該形參聲明為引用,避免復(fù)制。另一種方法在C++中更為常用,就是通過(guò)傳遞指向容器中需要處理的元素的迭代器來(lái)傳遞容器。
4.數(shù)組形參
由于數(shù)組是不可以復(fù)制的,所以不可以定義使用數(shù)組類(lèi)型形參的函數(shù)。如果函數(shù)需要使用數(shù)組作為形參,那么就要通過(guò)操縱指向數(shù)組中元素的指針來(lái)處理數(shù)組。
以下定義都是正確的:
void printValues(int*){}
void printValues(int[]){}
void printValues(int[10]){}
注意了,雖然不能直接傳遞數(shù)組,但是函數(shù)的形參可以寫(xiě)成數(shù)組的形式。上面三種定義是等價(jià)的,形參類(lèi)洗個(gè)都是int*。
通常,將數(shù)組形參直接定義為指針要比使用數(shù)組語(yǔ)法定義更好。這樣就明確地表示,函數(shù)操縱的是指向數(shù)組元素的指針,而不是數(shù)組本身。由于忽略了數(shù)組長(zhǎng)度,形參定義中如果包含了數(shù)組長(zhǎng)度則特別容易引起誤解。
對(duì)于非引用型形參來(lái)說(shuō),編譯器檢查數(shù)組形參關(guān)聯(lián)的實(shí)參時(shí),它只會(huì)檢查實(shí)參是不是指針、指針的形參和數(shù)組元素的類(lèi)型是否匹配,而不會(huì)檢查數(shù)組的長(zhǎng)度,所以即使實(shí)參數(shù)組的長(zhǎng)度與形參不匹配時(shí),編譯也可以通過(guò),但是在調(diào)用時(shí)會(huì)出錯(cuò)。
但是對(duì)于引用型形參來(lái)說(shuō),編譯器還會(huì)檢查是西安數(shù)組的大小與形參的大小是否匹配,所以如果實(shí)參數(shù)組的長(zhǎng)度與形參不匹配,編譯時(shí)就會(huì)報(bào)錯(cuò)。
如何確保函數(shù)的操作不超出數(shù)組實(shí)參的邊界?
方法有三:
1.在數(shù)組本身放置一個(gè)標(biāo)記來(lái)檢測(cè)數(shù)組的結(jié)束。C風(fēng)格字符串就是采用這個(gè)方法的一個(gè)例子,它是一個(gè)字符數(shù)組,并且以空字符null作為結(jié)束的標(biāo)記。處理C風(fēng)格字符串的程序就是使用這個(gè)標(biāo)記停止數(shù)組元素的處理。
2.使用標(biāo)準(zhǔn)庫(kù)規(guī)范,傳遞指向數(shù)組第一個(gè)和最后一個(gè)元素的下一個(gè)位置的指針。void printValues(const int *beg, const int *end){},如果定義int j[2]={0,1},在調(diào)用該函數(shù)時(shí),printValues(j,j+2).
3.顯式傳遞表示數(shù)組大小的形參。void printValues(const int ia[], size_t size){}
5.可變形參
C++中的省略符形參是為了編譯使用了varargs的C語(yǔ)言程序。
void foo(parm_list,...); void foo(...);
以上這篇老生常談C++中實(shí)參形參的傳遞問(wèn)題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持我們。
上一篇:C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)雙向鏈表簡(jiǎn)單實(shí)例
欄 目:C語(yǔ)言
下一篇:C語(yǔ)言 二叉查找樹(shù)性質(zhì)詳解及實(shí)例代碼
本文標(biāo)題:老生常談C++中實(shí)參形參的傳遞問(wèn)題
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/1708.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
 - 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
 - 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
 - 01-10c++中inline的用法分析
 - 01-10用C++實(shí)現(xiàn)DBSCAN聚類(lèi)算法
 - 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
 - 01-10C++大數(shù)模板(推薦)
 - 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
 - 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式詳解
 - 01-10深入理解C/C++混合編程
 


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
 - 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
 - 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
 - 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
 - 5c語(yǔ)言計(jì)算三角形面積代碼
 - 6什么是 WSH(腳本宿主)的詳細(xì)解釋
 - 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
 - 8正則表達(dá)式匹配各種特殊字符
 - 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
 - 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
 
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
 - 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
 - 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
 - 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
 - 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
 - 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
 - 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
 - 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
 - 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
 - 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
 
隨機(jī)閱讀
- 01-10delphi制作wav文件的方法
 - 01-10C#中split用法實(shí)例總結(jié)
 - 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
 - 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
 - 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
 - 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
 - 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
 - 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
 - 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
 - 04-02jquery與jsp,用jquery
 


