【C++】C++中的函數的基本使用

目錄結構:ios

contents structure [-]

1.簡介

一般函數包括形參,函數名,函數主體,函數返回值。下面的案例展現了c++函數使用的基本語法規則:c++

int add(int,int);//add函數的聲明

int main(int argc,char *argv[]){
  int res = add(1,1);
return 0;
}
//add函數的定義
int add(int a,int b){
return a+b;
}

也能夠不用寫add函數的聲明,直接把的add函數的定義寫在main函數的上面:數組

int add(int a,int b){//add函數的定義
return a+b;
}
int main(int argc,char *argv[]){
  int res = add(1,1);
return 0;
}

 

2.可變形參的函數

c++支持可變形參的函數,可使用initializer_list來實現或是省略符來實現。函數

2.1 initializer_list形參

若是函數的實參數量未知,可是所有的實參類型都相同,那麼就可使用initializer_list類型的形參。在使用initilizer_list類型以前,必需先引用<initilizer_list>頭文件。

initializer_list是一種模板類型,應此在使用時必需說明所含元素的類型,例如:spa

initializer_list<string> ls; //initializer_list元素中的類型是string
initializer_list<int> li; //initializer_list元素中的類型是int


注意:initializer_list對象中的元素值永遠是常量,咱們沒法改變initializer_list對象中元素的值。命令行

#include <iostream>
#include <initializer_list>
using namespace std;

void error_msg(initializer_list il){
    for(auto beg=il.begin(); beg != il.end(); beg++)
        cout << *beg << " ";
    cout << endl;
}
int main(int argc,char *argv[]){
  error_msg({"error message 1","error message 2"});//調用error_msg函數
return 0;
}

2.2 省略符形參

省略符形參只能用在形參列表的最後一個位置

例如:指針

#include <iostream> /*cout,endl*/
#include <cstdarg> /*va_list,va_start,va_end*/

int sum(int count, ...) {  //格式:count表明參數個數, ...表明n個參數
    va_list ap;  //聲明一個va_list變量
    va_start(ap, count);  //第二個參數表示形參的個數而且只能是參數列表中最後一個被命名了的參數。

    int sum = 0;
    for (int i = 0; i < count; i++) {
        sum += va_arg(ap, int);   //第二個參數表示形參類型
    }

    va_end(ap);  //用於清理
 
    return sum;
}
int main(int argc,char **argv){
    cout << sum(5,1.1,2.2,3.3,4.4,5.5) << endl;
return 0;
}

3.main函數處理命令行選項

main函數是應用程序的入口函數,它有以下幾種形式:c++11

int main(){}
int main(int argv,char *argv[]){}
int main(int argv,char **argv){}

第一種形式main函數不接收任何參數。

第二種形式main函數,其中第一個形參argc表示數組的大小;第二個形參argv表示一個數組,它的元素是指向C風格字符串的指針。code

int main(int argc,char *argv[]){
    for(decltype(argc) index=0; index<argc; index++)
        cout << argv[index] << " ";
    cout << endl;
return 0;
}

第三種形式main函數,argv是一個指針,指向一個char*類型。對象

int main(int argc,char **argv){
    for(decltype(argc) index=0; index<argc; index++)
        cout << (*argv++) << " ";
    cout << endl;
return 0;
}

若將上面的程序命名爲test.cpp,在編譯成功後,使用以下命令運行:./test how are you
輸出結果爲:

./test how are you

從結果中能夠看出,"./test"並非咱們想輸出的(咱們本意是想輸出"how are you")。應此須要注意,main函數中,實際的參數應該從下標1開始。

 

4.函數指針與函數引用

函數指針,顧名思義就是指向函數的指針。同理,函數引用就是引用函數的引用。

例如:

bool (*pf)(const string&,const string&);

pf前面有一個*,所以pf是指針;右側是形參列表,代表pf指向函數;再觀察左側,發現函數的返回值類型是布爾值。所以pf就是一個指向函數的指針,其中函數具備兩個const string&形參,返回值是bool類型。

注意:
若是pf是這樣的話

bool *pf(const string&,const string&)

那麼pf就不是函數指針了,這種狀況下pf表示爲一個函數,函數具備兩個const string&類型的形參,和一個bool指針類型的返回值。

當把函數名做爲一個值使用時,該函數自動地轉化爲指針。同時還能直接使用指向函數的指針調用該函數,無須提早解引用。

#include <iostream> /*cout,endl*/
using namespace std;
int compare(const string& a,const string& b){
    return a.compare(b);
}
int compare(const int& a,const int& b){
    return a - b;
}
//定義一個函數,其形參爲另外一個函數
void test1(int (*p)(const string&,const string&)){
    p("hello","world");
};
//test2和test1是等價聲明,函數類型會自動轉化爲指向函數的指針
void test2(int p(const string&,const string&)){
    p("hello","world");
};

//test3返回一個函數指針,該指針具備兩個int類型的形參,返回值類型爲void
void (*test3())(int,int){
}
//test4和test3是等價聲明
auto test4()-> void (*)(int,int){
}

void (*test5( int (*p)(const int&,const int&) ))(int,int){
    p(1,2);
    return 0;
}


int main(int argc,char **argv){
    int (*pf)(const string&,const string&);//聲明一個函數指針
    pf=0;//pf不指向任何函數
    pf = compare;//pf指向 int compare(const string&,const string&)
    
    int res = pf("hello","world");//調用pf所知指函數,無需提早解引用
    
    int (&rpf)(const int&,const int&) = compare;//聲明一個引用,初始化爲compare(compare有兩個重載函數,這裏引用形參爲兩個的const int&的函數)
    
    int res = rpf(1,2);//調用rpf所引用的函數
    
    test1(compare);//傳遞方法做爲實參,也能夠參數函數指針做爲實參。
    
    void (*p)(int,int) = test3();//返回一個函數指針

    p = test5(rpf);//接受一個函數指針,返回一個函數指針。rpf會自動轉化爲函數指針
return 0;
}

 

5.inline內聯函數

inline函數被稱爲內聯函數,就是將它在每一個調用的節點上「內聯地」展開。

在函數定義的時候加上inline關鍵字,這樣就成爲內聯函數了。

#include <iostream>
#include <string>
using namespace std;
//shoterString函數接受兩個const string類型參數,返回一個const string&類型的數據,同時該函數是內聯函數。
inline const string & shoterString(const String s1,const String s2){
    return (s1.size() < s2.size() ? s1 : s2);
}
int main(int argc,char *argv[]){
    string s1 = "hello";
    string s2 = "world";
    //編譯時轉化爲cout << (s1.size() < s2.size() ? s1 : s2) << endl;
    cout << shoterString(s1,s2) << endl;
}

通常來講,內聯機制用於規模較小,流程直接,頻繁調用的函數。不少編譯器都不支持內聯遞歸函數。

 

6.Constexpr函數

constexpr是c++11新標準添加的關鍵字,該關鍵字主要用於提供程序的運行效率,使用constexpr指定的值和函數可以在編譯時進行計算,好比下面的product()將會在編譯時被計算:

constexpr int product(int x, int y)
{
    return (x * y);
}
int main()
{
    //在編譯後,會直接轉化爲 const int x = 200;
    const int x = product(10, 20);
    cout << x;
    return 0;
}

輸出結果爲:

200

使用constexpr函數有如下幾點約束:1.在c++11中,一個constexpr函數只能有一個return語句。c++14標準中,容許超過一個return語句。2.constexpr函數應該只引用常量全局變量3.constexpr函數可以調用其餘constexpr函數,不能調用非constexpr函數。4.constexpr函數不能返回void類型,還有一些操做符好比(++v,--v)都不容許出如今constexpr函數。

相關文章
相關標籤/搜索