1. 程式人生 > >C++函式與引數

C++函式與引數

傳值引數:(值傳遞)

#include<iostream>
using namespace std;
int  func(int x, int y)
{
	return x + y;
}
int main()
{
	int a, b, sum;
	cin >> a >> b;
	sum = func(a, b);
	cout << sum << endl;
	return 0;
}

程式中:a,b為實參;x,y為形參;當執行func函式的時候將函式的實參複製給形參(傳值引數);複製過程由形參型別的複製建構函式來實現;實參和形參型別不同的時候進行型別轉換(自動型別轉換非前置型別轉換);函式呼叫不會修改與形參對應的實參的值;

模板函式:

模板函式實現一段通用函式,實現不同形參型別的功能

#include<iostream>
using namespace std;

template<class T>
T func(T x, T y)
{
	return x + y;
}
int main()
{
	int a, b, sum;
	float a1, b1, sum1;
	cin >> a >> b;
	sum = func(a, b);
	cout << sum << endl;
	cin >> a1 >> b1;
	sum1 = func(a1, b1);
	cout << sum1 << endl;
	return 0;
}

引用函式:

引用就是某一變數(目標)的一個別名,對引用的操作與對變數直接操作完全一樣

引用的宣告方法:型別識別符號 &引用名=目標變數名;

(1)&在此不是求地址運算,而是起標識作用。

(2)型別識別符號是指目標變數的型別。

(3)宣告引用時,必須同時對其進行初始化。

(4)引用宣告完畢後,相當於目標變數名有兩個名稱,即該目標原名稱和引用名,且不能再把該引用名作為其他變數名的別名。ra=1; 等價於 a=1;

(5)宣告一個引用,不是新定義了一個變數,它只表示該引用名是目標變數名的一個別名,它本身不是一種資料型別,因此引用本身不佔儲存單元,系統也不給引用分配儲存單元。故:對引用求地址,就是對目標變數求地址。&ra與&a相等。

(6)不能建立陣列的引用。因為陣列是一個由若干個元素所組成的集合,所以無法建立一個數組的別名。

#include<iostream>
using namespace std;

int func(int &x, int &y)
{
	return x + y;
}
int main(void)
{
	int a, b, sum;
	cin >> a >> b;
	sum = func(a, b);
	cout << sum << endl;
	return 0;
}

在傳值引數中,傳值的時候實參需要將實參的值複製給形參,函式結束的時候會呼叫解構函式進行釋放,使用形參會增加程式的執行時間;而在引用引數中,函式沒有複製實參的值,也沒有呼叫解構函式;呼叫函式中可以改變實參的值(可以利用關鍵字const指明函式不可修改的引用引數[常量引用引數])。

#include<iostream>
using namespace std;

int func(int &x, int &y)
{
	x = 4;
	return x + y;
}
int main()
{
	int a, b, sum;
	cin >> a >> b;
	sum = func(a, b);
	cout << a << b << endl;
	cout << sum << endl;
	return 0;
}

(1)傳遞引用給函式與傳遞指標的效果是一樣的。這時,被調函式的形參就成為原來主調函式中的實參變數或物件的一個別名來使用,所以在被調函式中對形參變數的操作就是對其相應的目標物件(在主調函式中)的操作。

(2)使用引用傳遞函式的引數,在記憶體中並沒有產生實參的副本,它是直接對實參操作;而使用一般變數傳遞函式的引數,當發生函式呼叫時,需要給形參分配儲存單元,形參變數是實參變數的副本;如果傳遞的是物件,還將呼叫拷貝建構函式。因此,當引數傳遞的資料較大時,用引用比用一般變數傳遞引數的效率和所佔空間都好。

(3)使用指標作為函式的引數雖然也能達到與使用引用的效果,但是,在被調函式中同樣要給形參分配儲存單元,且需要重複使用"*指標變數名"的形式進行運算,這很容易產生錯誤且程式的閱讀性較差;另一方面,在主調函式的呼叫點處,必須用變數的地址作為實參。而引用更容易使用,更清晰。

#include<iostream>
using namespace std;
template<class T>
T func(T &x, T &y)
{
	return x + y;
}
int main()
{
	int a, b, sum;
	float a1, b1, sum1;
	cin >> a >> b;
	sum = func(a, b);
	cout << sum << endl;
	cin >> a1 >> b1;
	sum1 = func(a1, b1);
	cout << sum1 << endl;
	return 0;
}

返回值:

返回值可以是一個值、一個引用、一個常量引用、一個指標

當返回值是一個值,返回的物件被複制到呼叫環境中,傳值呼叫在呼叫返回結束後臨時變數(返回的臨時變數、其他臨時變數、區域性變數、傳值引數)所佔用的空間被釋放,其值不在有效;

利用引用傳遞:給返回值型別後面增加一個字尾&,返回值常量引用賦值必須賦值給const常量

#include<iostream>
using namespace std;

int& func(int &x, int &y ,int &z)
{
	z = x + y;
	return z;
}
int main()
{
	int a, b, sum;
	cin >> a >> b;
	sum = func(a, b,sum);
	cout << "sum =" << sum << endl;
	return 0;
}

過載函式:

C++一個函式的簽名是由這個函式的函式名、形參型別以及形參的個數確定的

C++函式過載就是定義多個同名函式,但是函式簽名不同

函式呼叫時語句中的簽名與函式定義的簽名進行匹配

C語言不能進行過載是因為函式簽名機制與C++不同,只有函式名決定