1. 程式人生 > >C++函式引數的基礎知識

C++函式引數的基礎知識

》引數是函式間進行資料交換的主要方式。在C++中,函式之間傳遞引數有傳值和傳地址兩種傳遞方式。此外,C++還提供預設引數機制,可以簡化複雜函式的呼叫。

>傳值

        傳值是將實參值的副本傳遞(拷貝)給被呼叫函式的形參。由於傳值方式是將實參的值複製到形參中,因此實參和形參是兩個不同的變數,有各自的儲存空間,函式形參可以看做是函式的區域性變數。

        傳值的最大好處是函式呼叫不會改變呼叫函式實參變數的內容,可避免不必要的副作用。

>傳地址

         有時確實需要通過函式呼叫來改變實參變數的值,或通過函式呼叫返回多個值(return語句只能返回一個值),這時僅靠傳值方式是不能達到目的的。

         #傳指標方式交換變數值

#include<iostream>
using namespace std;
void swap(int*,int*);
int main(){
	int a=2,b=5;
	swap(&a,&b);          //交換了實參的值!
	cout<<a<<","<<b<<endl;

	system("pause");
	return 0;
}
void swap(int* px,int* py)
{
	int temp;
	temp=*px;             //間接取
	*px=*py;              //間接取,間接存
	*py=temp;             //間接存
}
    

由於swap函式引數傳遞的不是變數的值,而是變數的地址。因此,形參變數px和py存放的是變數a和b的地址,也就是說變數px和py分別指向變數a和b。在swap中,交換的是指標變數px和py所指向的內容,因此,變數a和b的值被交換。

       傳指標屬於顯示的傳遞地址。儘管傳遞指標可以達到目的,但傳遞方式略顯笨拙,而且也不直觀。首先,實參變數需要用取地址運算子&來傳遞變數的地址;其次,形參實際上是實參指標的一個副本,在swap()函式內,還要通過指標運算,如*px=*py等間接取、間接存來交換變數值,不僅難於理解,還容易產生錯誤。

       #引用傳遞函式引數

       例:改寫上面的程式

#include<iostream>
using namespace std;
void swap(int&,int&);
int main(){
	int a=2,b=5;
	swap(a,b);          //在此,編譯器自動將a,b的地址傳遞給swap函式
	cout<<a<<","<<b<<endl;

	system("pause");
	return 0;
}
void swap(int& x,int& y)
{
	int temp;
	temp=x;
	x=y;
	y=temp;
}
        通過引用傳遞函式引數屬於隱式傳地址,當引數宣告為引用,在函式呼叫時,編譯器會自動將實參的地址傳給被呼叫函式。在上面的程式中,函式swap的形參說明成引用,引用實際上是另一個變數的別名。與一般的引用不同(一般是定義時初始化為另一個變數的引用),引用引數是在函式被呼叫時被初始化為實參變數的引用。

        注:函式引用引數僅在函式定義時說明,而帶引用引數的函式的呼叫形式與值引數相同。在C++中,當函式引數需要傳遞地址時,建議使用引用來代替指標(指標方式屬於C語言風格),因為引用比指標更加直觀。

>在這三種情形中,引用引數十分有用:

        (1)要從函式中返回多個值。

        (2)通過函式呼叫要改動實參值

        (3)傳遞地址可以節省拷貝大量資料所需的記憶體空間和時間

        注:當函式引數為大資料型別,而這類物件通常包含有多個數據,當它們作為值引數傳遞時,實參物件拷貝給形參變數(物件中的每個資料都要分別拷貝到形參中)將要佔用許多空間並要消耗時間。因此,好的程式設計時間通常將大資料型別引數,如類型別引數,作為引用引數,這樣將節省引數傳遞的時間和空間。

         但是,也要注意使用引用(或指標)所帶來的副作用。使用引用(或指標)可能會由於疏忽而導致不該修改的實參變數在函式呼叫時被修改。保護實參不被修改的辦法是使用const引用引數,具體做法是使用關鍵字const來修飾引用引數。

>預設引數

         在C++中,可以為形參指定預設值,在函式呼叫時沒有指定與形參相對應的實參時就自動使用預設值。預設引數可以簡化複雜函式的呼叫,使用預設引數,程式設計師只需記住針對確切情形有意義的引數,不需要指定常見情況下使用的引數。

         預設函式通常在函式名第一次出現在程式中的時候指定,如在函式原型中指定預設引數值。指定預設引數的方式從語法上看與變數初始化相似。

                 例如: void myfunc(int x=0,int y=1);

         如果一個函式中有多個引數,則預設引數應從右至左逐個定義。