1. 程式人生 > 其它 >沒有與引數列表匹配的 過載函式 getline 例項_C++程式設計基礎: 10. 函式

沒有與引數列表匹配的 過載函式 getline 例項_C++程式設計基礎: 10. 函式

技術標籤:沒有與引數列表匹配的 過載函式 getline 例項

a72eaab46503aba5583bb13c9839ca29.gif

本系列文章是配合我釋出的《C++程式設計基礎》系列視訊教程的知識點總結和補充。

用程式來實現一個專案時往往會有很長的程式碼,使用函式將實現某個功能的相關程式碼組織起來,可以幫助我們很好的梳理程式碼結構,提高程式的可讀性、簡化程式,也便於對程式改進升級。

函式的宣告

在C++裡,不像Java,函式的實現要在被呼叫之前,如果寫在了程式呼叫的後面,編譯無法通過,因此需要在前面宣告函式的原型。

宣告一個函式時,首先是返回值的型別,如果沒有返回值,用void代替。接著是自定義一個函式名,跟著一對小括號,裡面包含引數的序列,每個引數之間以逗號分隔,如果引數有預設值,可以在宣告時設定。宣告時括號後面要有分號。

voidprintSeparateLine();
stringuppercase_A(stringstr);

函式的定義

函式的定義也就是對函式的具體實現,這時具體實現的程式碼要在小括號後面用大括號括起,如果這個函式有返回值,函式定義裡要有最後會被執行的return語句,即關鍵字return後面跟著和宣告的返回值資料型別一致的資料。如果函式沒有返回值,應在返回值資料型別的位置寫關鍵字void來替代,函式內無需包含return語句。

voidprintSeparateLine(){
std::cout<<"--------------------"<<std::endl;
}

stringuppercase_A(stringstr){
for(inti=0;iif(str[i]=='a'){
str[i]='A';
}
}
returnstr;
}

在函式中不能包含另一個函式定義,但是它可以呼叫其他的函式,也可以自己呼叫自己,即可以實現遞迴。

形參和實參

在宣告、定義中括在函式名後面小括號裡的這些引數叫做形參,在程式中呼叫函式時需要提供實參。

例如在程式裡呼叫uppercase_A時:

str_new=uppercase_A(str_old);

其中str_old是一個物件例項,作為一個實參傳遞給了uppercase_A這個函式。

函式的過載

有些時候一些函式名稱和返回值型別均相同,但需要傳遞的引數個數或型別可以不同,稱之為函式的過載。

例如,宣告兩個都叫做printSeparateLine的函式:

voidprintSeparateLine();
voidprintSeparateLine(intl,charc);

具體實現:

voidprintSeparateLine(){
std::cout<<"--------------------"<<std::endl;
}

voidprintSeparateLine(intl,charc){
for(inti=0;iif(i==l-1){
std::cout<std::endl;
}else{std::cout<}
}
}

程式中的呼叫:

printSeparateLine();
printSeparateLine(20,'*');

為函式引數宣告預設值

宣告時可以為引數提供預設值,有預設值的引數即成為了可選引數,呼叫時可以省略相應引數,例如下面的例子中,在宣告函式的原型時,將函式printSeparateLine的第二個字元型別的引數預設值設為了'-':

voidprintSeparateLine(intl,charc='-');

程式中的呼叫,可以省略提供第二個引數:

printSeparateLine(20);

行內函數

當程式執行到一個函式而要去呼叫它時,要暫停手裡的工作先去另一個地方處理函式的具體操作,之後再回來繼續工作,雖然這發生在很短的時間裡,但若函式只是很簡單的幾行操作,卻要這樣來來回回,尤其放在一個迴圈當中,更是會大大增加函式呼叫的開銷,因此,對於只是實現簡單操作的函式,宣告其為行內函數,在函式宣告前加上關鍵字inline,即告訴編譯器,程式裡這個函數出現時,在它所在的位置展開,從而減少函式呼叫的開銷。

inlinevoidprintSeparateLine();
inlinevoidprintSeparateLine(){
std::cout<<"--------------------"<<std::endl;
}

但這種方法對稍複雜的函式就不再適用了,在其中不應包含像switch、while這樣複雜的結構控制語句,也不該出現遞迴,否則會被當成普通函式來處理,所以一般情況下並不推薦使用行內函數,除非是一段使用頻率很高且很短的程式碼,才會考慮宣告為行內函數。

接上一次實現猜數字的小程式,在本次課中,增加了為其列印分隔線的兩個同名函式printSeparateLine(函式的過載)以及實現了一個返回值為字串型別的函式uppercase_A來演示如何獲得來自輸入流cin中的一行字串,並將其中出現的小寫'a'變為大寫'A',這裡使用到了標準庫裡的函式getline,它屬於std名字空間,第一個變數是一個輸入流,第二個變數是用來儲存輸入流裡一行內容的string型別資料(它可能還有另一種3個引數的函式結構,這裡用不到)。

以下是這段程式碼(一些編譯環境,可能還需要在前面新增#include )

#include
inlinevoidprintSeparateLine();
voidprintSeparateLine(intl,charc='-');
usingstd::string;

stringuppercase_A(stringstr);

intmain(intargc,constchar*argv[]){
usingstd::cout;
usingstd::endl;
usingstd::cin;

intx;

stringstr_old,str_new;
cout<<"Pleaseinputastring:"<<endl;
std::getline(cin,str_old);
str_new=uppercase_A(str_old);
cout<<"str_new:"<endl;cout<<"str_old:"<endl;
srand((int)time(0));intrandomInt=rand()%100+1;cout<<"Arandominteger(1to100)hasbeencreated."<<endl;
printSeparateLine(20,'*');do{cout<<"Pleaseguessthenumber:"<<endl;if(cin>>x&&cin.get()=='\n'){if(x==randomInt){cout<<"That'sright!Thenumberis"<endl;break;
}else{if(xcout<<"Therandomnumberishigher."<<endl;
}else{cout<<"Therandomnumberislower."<<endl;
}
}
}else{cin.clear();cin.ignore(INT_MAX,'\n');cout<<"Pleaseinputaninteger!"<<endl;
}
printSeparateLine();
}while(true);return0;
}inlinevoidprintSeparateLine(){std::cout<<"--------------------"<<std::endl;
}voidprintSeparateLine(intl,charc){for(inti=0;iif(i==l-1){std::cout<std::endl;
}else{std::cout<}
}
}stringuppercase_A(stringstr){for(inti=0;iif(str[i]=='a'){
str[i]='A';
}
}returnstr;
}
歡迎點選右下方↓↓"在看"↓↓來分享 fcfafad259f89761b9bbb4be01cfa3be.gif