C++函數(進階)

一 內聯函數:
     與一般函數相比,編碼的方式相同,不同的地方在於函數的調用機制。
     這是C++爲了提高函數的運行效率所創建。
     內聯函數的聲明: inline 返回值類型 函數名(參數列表)。
     其運行的機制就是在於,當調用內聯函數時,直接將函數的代碼複製到調用的函數的地方
     這個方法適合小型函數的使用,否則大型函數的直接複製,將很浪費時間和資源。

此處C++的內聯函數類似於C語言中的宏定義的功能,如:
    #define N 6 相當於在以後使用 N 時,都會自動替換成 6
    #define sum(num)  num + num 相當於以後再調用 sum(num) 時,等於調用 num + num 
   

  如圖,內聯函數的聲明和調用方法如下所示:  

 

 

 

內聯函數的定義方法:  在函數聲明是加 inline, 或者是在函數實現時加 inline

 

 

二  reference 引用 相當於爲對象起了一個別名
    int value = 99;
    int& refvalue = value; refvalue指向value是其另一個名字,所以以後操作refvalue的時候,等於操作value

    注意:定義引用的時候,必須進行初始化,不可以直接引用常量
         錯誤:int& refvalue = 5; 
    如果想要引用常量,可以定義爲:
         const int& refvalue = 6;

    當使用引用變量時,相當於直接使用原始數據,而不是副本,相當於 const 指針
    
引用和指針的使用實例:

    # include <iostream>
    using namespace std;
    
    void Swap1(int&, int&);
    void Swap2(int*, int*);
    int main()
    {
        int num1  = 5, int num2 = 50;
        Swap1(&num1, &num2);
        Swap2(num1, num2);
        return 0;
    }

    void Swap1(int& num1, int& num2)  使用引用來作爲參數進行交換
    {
        int temp;
        temp = num1;
        num1 = num2;
        num2 = temp;

        return;
    }
    void Swap2(int* num1, int* num2)  使用指針作爲參數進行交換
    {
        int temp;
        temp = *num1;
        *num1 = *num2;
        *num2 = *num1;

        return; 
    }


    使用引用的好處:1 可以更加簡便的書寫代碼  2 直接傳遞對象, 而不是複製一個副本 
三  函數的返回值是引用類型

    1. 不要返回局部變量的引用,因爲變量有自己的生存週期,
       當函數結束時,函數內部聲明的變量就會被回收。所謂的內存回收,並不是銷燬內存中原有的數據,
       而是指,這塊內存不在歸本函數使用,其他的函數可以對這塊內存進行修改,
       就像,租房子的時間到了,要把房子進行歸還,新住進來的人將會改變房子中的內容。

    2. 函數可以沒有返回值 當函數返回爲引用類型是,必須是參數列表中的某個參數,
       假設函數的聲明: int &sum(int& num1, int& num2) 
       不能返回        return num1 + num2; 只能返回 num1 或者是 num2
    
    3. 如果定義的函數返回類型爲引用類型, 爲了保險,要在函數的聲明部分加 const
       const int& sun(int&, int&); 防止出現 sum(num1, num2) = 88; 這樣的模糊定義 
       
    #include <iostream>
    #include "reference.hpp"
    using namespace std;

    int &sum(int&, int&);

    int main()
    {
        int num1 = 5, num2 = 10;
        int& result = sum(num1, num2);
        cout << "result = " << result << endl;

        return 0;
    }

    int &sum(int& num1, int& num2)  當函數沒有設置返回值的時候,默認返回最後一個變量的引用
    {
        num1 = 5;
        num2 = 6;  可以沒有返回值
    }
四. 按值傳遞、按指針傳遞和按引用傳遞,在函數使用方面三者怎麼選擇。
    
    1. 使用引用傳遞的時候,可以修改對象的內容
    2. 數據對象較大時,傳遞引用可以增加效率
    3. 當函數中不需要進行對象內容的修改時
        如果數據對象很小,則建議按值進行傳遞
        傳遞數組的時候,只能用指針傳遞
        數據對象很大時,建議使用 const 指針或引用 以提高運行的效率
    4. 需要修改數據對象是
        數據對象是基本類型或者是結構的時候,可以使用指針或者是引用(基本類型建議指針)
        數據必須使用指針
        類的對象作爲數據對象時,最好使用引用傳遞
五、 使用默認參數
    void sum(int num = 10);
    void sum(int sum)  此處不能再賦值 錯誤寫法:void sum(int sum = 10); 
    {
        cout << sum <<endl;
    }
    注意: 1 使用默認函數時,聲明和實現部分只能有一個賦值
          2 參數列表有多個參數時,在給默認參數進行賦值時,只能從右往左進行賦值
              正確的寫法: void sum(int a, int b = 10, int c = 10);
              正確的調用: sum(1); sum(1, 2); sum(1, 2, 3);
              錯誤的寫法: void sum(int a = 10, int b, int c = 10);
六 函數的重載  
    所謂函數的重載就是 多個函數,函數名相同,但是參數列表不同,比如:
    void num(int num1, int num2);   void num(double num1, double num2);
    voie num(int num1);             void num(double num1);
    
    注意: void sum(int&) 和 void sum(int) 是一樣的,因爲在調用的時候,都是一樣的
        比如:  void sum(10); 這樣的話就會報錯,因爲編譯器不知道你調用的到底是哪個函數

    實際上,在函數內部進行調用的時候,是根據特徵標來進行函數的調用
    比如 void sum(int); 和 void sum(float);是函數的重載
    但在執行的時候,編譯器 重載決議 將 void sum(int); 編譯爲 void sum_int
    同理將 void sum(float); 編譯爲 void sum_float 
    所以實際上 void sum(int&) 和 void sum(int) 在編譯時,都會編譯爲
    void sum_int
    
七 利用函數的重載進行對不同類型的數組排序
    
  main函數部分:
  
    #include <iostream>    
    #include "sort.hpp"

    using namespace std;

    int main()
    {
        int intArry[6] = {11, 66, 55, 44, 33, 22};
        double doubleArray[6] = {11.1, 44.4, 55.5, 66.6, 22.2, 33.3};

        Show(intArry, 6);   顯示排序前的數組
        Sort(intArry, 6);   對數組進行排序
        Show(intArry, 6);   再次顯示

        Show(doubleArray, 6);  
        Sort(doubleArray, 6);
        Show(doubleArray, 6);

        return 0;
    }

排序的 sort.hpp 部分:

    #ifndef SORT_HPP_INCLUDED
    #define SORT_HPP_INCLUDED
    #include <iostream>
    using namespace std;

    void Sort(int [], int);   利用函數的重載進行排序
    void Sort(double [], int);

    void Show(int [], int);   利用函數的重載進行顯示
    void Show(double [], int);


    #endif // SORT_HPP_INCLUDED

排序的 sort.cpp 部分:

    #include <iostream>
    #include "sort.hpp"

    using namespace std;

    void Sort(int Array[], int Length)   對int型的函數進行排序 
    {
        for(int i = 0; i < Length - 1; i++)
            {    
            for(int j = 0; j < Length - 1 - i; j++)
            {
                if(Array[j] > Array[j + 1])
                {
                    int temp;
                    temp = Array[j];
                    Array[j] = Array[j + 1];
                    Array[j + 1] = temp;
                }
            }
        }
        return;
    }

    void Sort(double Array[], int Length)   對double型的函數進行排序
    {
        for(int i = 0; i < Length - 1; i++)
        {
            for(int j = 0; j < Length - 1 - i; j++)
            {
                if(Array[j] > Array[j + 1])
                {
                    double temp;
                    temp = Array[j];
                    Array[j] = Array[j + 1];
                    Array[j + 1] = temp;
                }
            }
        }

        return;
    }

    void Show(int Array[], int Length)    對int型的函數進行排序
    {
        for(int i = 0; i < Length; i++)
        {
            cout << Array[i] << '\t';
        }
        cout << endl;
        return;
    }


    void Show(double Array[], int Length)   對double型的函數進行顯示
    {
        for(int i = 0; i < Length; i++)
        {
            cout << Array[i] << '\t';
        }
        cout << endl;
        return;
    }    

  函數重載的意義:用同一個函數名,實現對不同數據類型的數組進行排序和顯示
  缺點: 代碼的重複率過高,不簡潔

 

八  函數模板 
    一般函數模板的聲明:template <typename T> void sum(T num1);
    其中T是一個虛擬的數據類型,會根據傳入的實參而改變。
    
    所謂函數模板,實際上就是建立一個通用函數
    1. 函數定義時,不指定具體的數據類型(使用虛擬類型來代替)
    2. 函數在調用的時候,編譯器會根據傳入的實參來反推數據類型--類型的參數化
    
    注意:在聲明模板函數的時候,模板函數的聲明和實現必須都放在同一個文件夾中,不能分文件操作。
     
    模板函數的優點: 與函數的重載相比,減少了代碼量,只需書寫一個函數模板就可以實現
                    對不同數據類型的操作

    比如,用函數模板實現對不同數據類型的數組進行顯示 :

        #include <iostream>
        #include "sort.hpp"
        using namespace std;
        
        template <typename T>
        void TShow(T TArray[], int Length)
        {
            for(int i = 0; i < Length; i++)
            {
                cout << TArray[i] << '\t';
            }
            cout << endl;
        }
        
        int main()
        {
            int intArray[] = {11, 66, 55, 44, 33, 22};
            double doubleArray[] = {11.1, 44.4, 55.5, 66.6, 22.2, 33.3};
            
            TShow(intArray, sizeof(intArray) / sizeof(intArray[0]));
            TShow(doubleArray, sizeof(doubleArray) / sizeof(doubleArray[0]));
            return 0;
        }


    使用場合:

        在不同類型的數據有相同操作的時候,用函數模板,如果不同數據的操作不同,採用函數重載
        因爲函數模板只有在業務邏輯一樣,但是數據類型不一樣的情況下才能使用。
    

未完待續~~~

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章