一 內聯函數:
與一般函數相比,編碼的方式相同,不同的地方在於函數的調用機制。
這是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;
}
使用場合:
在不同類型的數據有相同操作的時候,用函數模板,如果不同數據的操作不同,採用函數重載
因爲函數模板只有在業務邏輯一樣,但是數據類型不一樣的情況下才能使用。
未完待續~~~