天天看點

C++菜鳥學習筆記系列(18)——函數參數傳遞C++菜鳥學習筆記系列(18)

C++菜鳥學習筆記系列(18)

本期主題:函數參數傳遞

形參的初始化機理和變量初始化一樣,與之類似的,形參的類型決定了形參和實參互動的方式。如果形參是引用類型時,我們說它對應的實參被引用傳遞或者函數被傳引用調用。和其他引用一樣,引用形參是他綁定對象的别名,也就是說引用形參是它對應的實參的别名。

當實參的值被拷貝給形參時,形參和實參是兩個互相獨立的對象,我們說這樣的實參被值傳遞或者函數被傳值調用。

(1)傳值參數

當初始化一個非引用類型的變量時,初始值被拷貝給變量。此時,對變量的改動不會影響初始值。

我們來看一個小例子:

/*
author: wxc_1998
date: 2018/10/31
*/
#include <iostream>

using namespace std;

int reset(int i);

void main()
{
	int val1,val2;
	cout << "please inpute a integer:" << endl;
	cin >> val1;
	val2 = reset(val1);
	cout << "the original value is: " << val1 << endl;
	cout << "we reset " << val1 << " to " << val2 << endl;

	cout << "please input any key to continue!" << endl;
	cin.clear();
	cin.sync();
	cin.get();
}

int reset(int i)
{
	i = 0;
	return i;
}
           

我們可以看到變量val1的值在經過reset函數的處理之後并沒有發生改變。

(2)傳引用參數

我們在C++菜鳥學習筆記系列(4)——引用、指針中也曾經介紹過對于傳引用操作實際上就是作用在引用所綁定的對象上。引用形參也是類似的,通過使用引用形參,允許函數改變一個或多個實參的值。

下面我們把上一部分中介紹的reset函數改寫一下:

void reset(int &i)
{
	i = 0;
}
           

這樣我們調用reset函數時,形參i僅僅是實參val1的一個别名,我們在函數中對形參i所做的全部操作實質上都是直接作用在實參val1上的。

當然我們也可以使用指針形參實作類似的效果,但是與之不同的是如果我們使用了指針形參,那麼我們在調用函數時需要使用取位址符獲得實參的位址。

例如:

void reset(int *i)
{
	*i = 0;
}
           

這時我們需要通過

reset( &val )
           

調用函數。

與第一種介紹的傳值參數相比,傳引用參數更加高效,例如在拷貝大的類型對象及容器對象時,這一優點會展現的更加明顯,還有一些類型并不支援拷貝操作,這時就隻能通過引用形參通路該類型的對象。

引用形參還有一個非常重要的優點是我們可以通過引用形參傳回額外的資訊(彌補return函數隻能傳回一個參數的不足)。

下面我們來看一個關于引用形參使用的小例子:

/*
author: wxc_1998
date: 2018/10/31
*/
#include <iostream>
#include <string>

using namespace std;

int find_c(const string &str,const char c, int &occurs);

void main()
{
	string s;
	char c;
	int count = 0, f = 0;
	cout << "please input a world: "<< endl;
	cin >> s;
	cout << "please input the char of you want to find in " << s << endl;
	cin >> c;
	f = find_c(s, c, count);
	cout << "the first location of " << c << " is " << f+1 << endl;
	cout << c << " have been found " << count << " times in " << s << endl; 
	 
	cout << "please input any key to continue!" << endl;
 	cin.clear();
 	cin.sync();
 	cin.get();
}

int find_c(const string &str, char c, int &occurs)
{
	int ff = str.size();
	for (int i = 0; i != str.size(); ++ i)
	{
		if (str[i] == c)
		{
			if (ff == str.size())
			{
				ff = i;
			}
			++ occurs;
		}
	}
	return ff;
}
           
小提示:如果函數無須改變引用形參的值,最好将其聲明為常量引用。(關于這個大家自己百度了解)

(3)數組形參

數組的兩個特殊性質對我們定義和使用作用在數組上的函數有影響:

1.不允許拷貝數組。
 2.使用數組時會把其轉換成指針。
           

第一個特性讓我們無法以值傳遞的方式使用數組參數,第二個特性決定了我們在為函數傳遞一個數組時,實際上是傳遞了一個指向數組首元素的指針。

數組的引用形參:在我們使用數組的引用作為形參時,要注意符号的優先級,例如:

void prin (doule &a[10]);// error
void prin (doule (&a) [10]);//right
           

第一種錯誤的把a聲明成立引用的數組,第二種才是正确的具有10個雙精度的double類型數組的引用。

傳遞多元數組:我們在前面也曾經說過,C++中并沒有真正的多元數組,所謂的多元數組隻是數組的數組。

因為我們處理的是數組的數組,是以将多元數組傳遞給函數時,真正傳給函數的是指向一個數組的指針。數組的第二個次元及其後的所有次元的大小都是數組類型的一部分不能省略。

好了,這次我們就寫到這裡了,下次再見!

注:雖然這篇部落格的内容十分簡單,但是大家若有轉載還請标明出處!

繼續閱讀