C++中函數的用法小結。本站提示廣大學習愛好者:(C++中函數的用法小結)文章只能為提供參考,不一定能成為您想要的結果。以下是C++中函數的用法小結正文
函數在C++中的應用,不過2種處所,一處是函數的界說,一處是函數的挪用。而函數的界說則異常簡略,由三個部門構成:函數的前往類型、函數名和函數的形參表。固然,這裡分歧的函數界說可以還會稍有分歧,好比類的成員函數、內聯函數等。這裡我們重要評論辯論函數的挪用時須要留意的一些成績。
1、參數傳遞
我們將函數界說或聲明裡的參數叫形參,而在挪用函數時傳入的參數叫實參。那末依據形參類型的分歧,有幾下情勢的參數傳遞。
1,非援用形參
1)通俗的內置類型
通俗非援用類型的參數經由過程復制對應的實參完成形參的初始化。當用實參的正本初始化形參時,函數並沒有拜訪挪用所傳遞的實參的自己,是以函數弗成能改實參的值。好比上面的交流兩個數的法式:
void swap(int v1, int v2)
{
int temp = v1;
v2 = v1;
v1 = temp;
}
swap(a, b);// 挪用swap
下面法式中,實參為a與b,然則在挪用時,v1與v2接收的是a與b的正本,所以現實上a與b的值沒有變更。
2)指針形參
函數的形參可所以指針,此時將復制實參指針,其實這類跟1)道理相似,函數內並沒有法轉變實參的指針值。只是函數可以經由過程復制到的地址轉變實參指針所指向的值。
void swap(int* v1, int* v2)
{
int temp = *v2;
*v2 = *v1;
*v1 = temp;
}
int main()
{
int a = 10,b = 20;
int *p1 = &a,*p2 = &b;
swap(p1,p2);
return 0;
}
下面法式中界說的swap的形參為指針類型,main中挪用swap,現實上swap其實不能轉變p1與p2的值,只是轉變了它們所指向的值。
3)const 形參
關於通俗的非援用類型用const潤飾現實上是沒成心義的,由於原來函數就不會轉變實參的值。像上面的界說,現實中編譯器會疏忽const的界說,而將其視為int型。
void fcn(const int i);
2,援用形參
1)在下面的法式中我們看到,假如想交流兩個變量的值,經由過程挪用通俗的非援用類型形參的函數,其實不能完成。用它們的指針可以,同時我們也能夠用援用。
void swap(int& v1, int& v2)
{
int temp = v2;
v2 = v1;
v1 = temp;
}
int main()
{
int a = 10,b = 20;
swap(a,b);
return 0;
}
在現實挪用swap時,v1與v2現實相當於a與b的另外一個名字。
2)在有的時刻我們須要向函數傳遞年夜型對象,須要應用援用形參,假如直接應用復制實參的情勢可以,然則它的效力太低了,乃至有些對象是沒法復制的。然則應用援用形參時,我們不願望函數轉變了實參傳入的值,我們便可以應用const來限制形參。上面法式用來斷定哪一個字符串更長,顯著我們不願望函數會轉變字符串的內容,我們便可以用const援用型的形參。
bool isLonger(const string &s1, const string &s2)
{
return s1.size() > s2.size();
}
所以,假如應用援用形參的唯一的目標是防止復制實參時,則應將形參界說為const援用。
3)在應用援用形參函數時,有兩點值得留意:
不要用const限制的實參或字面值來挪用非const援用形參函數。由於如許函數內,可以轉變實參的值,這不正當。
非const援用形參只能與完整同類型的非const對象聯系關系。
4)傳遞指向指針的援用
以下有上面的法式:
void swap(int* &v1, int* &v2)
{
int* temp = v2;
v2 = v1;
v1 = temp;
}
int main()
{
int a = 10,b = 20;
int* p1 = &a, *p2 = &b;
swap(p1,p2);
return 0;
}
下面的法式仍然不克不及轉變a與b的值,然則它轉變了p1與p2的值,如今p1指向了b,而p2指向了a。
3,其他類型的形參
1)vector和其他類型的形參:普通在這類類型作為形參時,為了不復制應當斟酌形參聲明為援用類型。C++法式員偏向於傳遞容器中須要處置的元素的迭代器來傳遞容器。
2)數組形參:因為數組不克不及復制,所以不克不及直接編寫數組類型的形參函數,普通經由過程傳遞指向數組的元素的指針來處置數組。值得留意的是在經由過程援用傳遞數組時,在挪用函數時形介入實參的類型要婚配。
void printValues(int (&ar)[10]);
int main()
{
int i = 0, j[2] = { 0, 1 };
int k[10] = {0,1,2,3,4,5,6,7,8,9};
printValues(i); //error int不克不及初始化 int(&)[10]
printValues(j); //error int[2] 不克不及初始化 int(&)[10]
printValues(k); // ok
return 0;
}
2、函數的前往值
1)沒有前往值
許多函數並沒有前往值,特別是如今C++作風,習氣於把須要的成果作為援用形參。這類型函數普通沒有return語句,有時刻有return是使函數半途中止履行。
2)前往非援用類型
這類情形在函數挪用處,法式會用一個暫時變量復制函數的前往值。
3)前往援用
當函數前往援用類型時,並沒有復制前往值。相反,前往的是對象自己。
在前往援用這類情形下,留意不要前往部分變量的援用,由於部分變量在函數體內界說,當函數履行完後就燒毀了,所謂的援用也就沒成心義了。同理,不要前往指向部分變量的指針。
3、重載函數
湧現在雷同感化域中的兩個函數,假如具有雷同的名字而形參分歧,則稱為重載函數。
1)留意辨別函數重載與反復聲明
有些看起來分歧的形參,實質是雷同的。上面代碼中的都是反復聲明的例子
typedef double newDouble;
int func(double i);
int func(newDouble i); // 沒有新類型
int func1(int, int = 1); //只是供給默許參數
int func1(int ,int);
int func2(int);
int func2(const int); //關於通俗非援用形參用cosnt潤飾是沒成心義的
2)重載與感化域
部分聲明的函數,將屏障一切全局感化的同名函數。上面例子顯示,即便全局感化的函數加倍婚配挪用的實參類型,然則依然挪用的是部分的函數。
void print(int);
int main()
{
void print(double);
print(42);
return 0;
}
下面法式中,將挪用void print(double)函數,固然42是int型。
3)重載肯定的三個步調
假如界說了浩瀚的函數重載,將存在函數挪用究竟與哪一個重載函數相婚配的成績。我們經由過程上面的示例代碼來講明成績:
void f(); // 1
void f(int);// 2
void f(double);// 3
void f(int, int);// 4
void f(double, double);// 5
第一步:肯定候選函數
假設我們挪用f(4.2),那末先找到同名函數,而且在感化域內可見,下面例子中5個函數都知足。
第二步:選擇可行的函數
必需知足2個前提:一是函數形介入該挪用實參個數雷同;第二,每一個實參的類型必需與對應的類型婚配,或許可以被隱式轉換為對應的形參類型。這裡我們再挪用f(4.2)時,消除了1、4、5號函數,只剩下2與3。個中2號函數可以經由過程類型轉換來知足。
第三步:尋覓最好婚配
在經由第二步肯定後,剩下2與3函數,那末2須要停止類型轉換,明顯3是最好婚配了。
然則假如如許挪用f(42,4.2)。這時候候就會湧現二義性,編譯器將提醒。
還有一種要留意的就是有默許參數的函數,好比我們界說6號函數為void f(double,int =1);那末在挪用f(4.2)時就會有二義性。
可基於函數的援用形參是指向const對象照樣指向非const對象完成函數重載。