參考鏈接:https://www.cnblogs.com/fengxing999/p/11096763.html
函數(shù)參數(shù)傳遞分為3種情況:傳值,傳指針和傳引用。
首先,理解一下實(shí)參與形參的概念。
int func(int x)//x是形參
{
return x*x;
}
int main(void)
{
int a = 10;
func(a);//a是實(shí)參
return 0;
}
上面的代碼中,x是形參,a是實(shí)參。形參x是實(shí)參a的一個(gè)拷貝。
一,傳值
所謂傳值,顧名思義,就是把實(shí)參的值直接傳遞給函數(shù)。因?yàn)樾螀⑹菍?shí)參的拷貝,所以傳值無法改變實(shí)參。在C++里面,如果傳遞的是對(duì)象, 那么,在傳值過程中,還會(huì)隱式的調(diào)用對(duì)象的拷貝構(gòu)造函數(shù),有一定的計(jì)算執(zhí)行開銷(相當(dāng)于創(chuàng)建了一個(gè)臨時(shí)對(duì)象,函數(shù)調(diào)用完成后執(zhí)行臨時(shí)對(duì)象的析構(gòu)函數(shù))。
func(int x)//func采用了傳值的形式
{
x = x+1;
printf("x=%d\n", x);
}
int main(void)
{
int a = 0;
func(a);//傳值不能修改a的值
printf("a=%d\n", a);
return 0;
}
分析:上面的程序采用了傳值的參數(shù)傳遞形式,把a(bǔ)的值0傳遞給了func函數(shù),而由于x是a的一個(gè)拷貝,因此,x=x+1值修改了x的值 并沒有修改a的值。所以上面程序執(zhí)行的結(jié)果,輸出為:
x=1
a=0
二,傳指針
傳指針就是把實(shí)參的地址傳遞給函數(shù)。傳指針可以修改實(shí)參的值,在C++里也不會(huì)存在調(diào)用對(duì)象的拷貝構(gòu)造函數(shù)的問題, 傳指針的效率比傳值要高。所以,如果需要修改實(shí)參的值,就不能傳值,而需要傳指針等。
但是,傳指針比傳值復(fù)雜,指針計(jì)算一旦移動(dòng)出了正常范圍,會(huì)造成程序的非法訪問等。
void func(int *x)//func采用了傳指針的形式
{
*x = *x+1;
printf("*x=%d\n", *x);
}
int main(void)
{
int a = 0;
func(&a);//把實(shí)參a的地址傳遞給了函數(shù)func
printf("a=%d\n", a);
return 0;
}
分析:傳指針可以修改實(shí)參的值。根據(jù)指針的定義,x就是a,所以,x=*x+1,即為a = a+1,所以上面的代碼輸出結(jié)果為:
*x=1
a=1
三,傳引用
所謂引用其實(shí)就是變量的一個(gè)別名。傳引用是C++里面引入的一種參數(shù)傳遞方法。傳引用實(shí)際上也是傳遞的實(shí)參的指針,所以能夠修改實(shí)參的值。 但是,引用的特性告訴我們,一旦引用初始化后,這個(gè)引用就不能再改變。所以,傳遞引用實(shí)際上是擁有傳值的方便簡(jiǎn)單,也同時(shí) 具備了傳指針的高效,又沒傳指針的危險(xiǎn),相對(duì)安全。
void func(int &x)//func采用了傳引用的形式
{
x = x+1;
printf("x=%d\n", x);
}
int main(void)
{
int a = 0;
func(a);//把實(shí)參a的引用傳遞給了函數(shù)func
printf("a=%d\n", a);
return 0;
}
分析:func采用傳引用的方法定義,實(shí)參a引用傳遞給函數(shù)func之后,func能夠修改實(shí)參的值。所以上面的程序執(zhí)行結(jié)果為:
x=1
a=1
總之:傳值不能修改實(shí)參,且如果是對(duì)象,效率較低;傳指針能夠修改實(shí)參,效率較高,但容易出錯(cuò);傳引用能夠修改實(shí)參,效率較高,而且不易出錯(cuò)。