目錄
- 1、變量的作用域
- 1. 變量的作用域分類
- 2. Unary Scope Resolution (一元作用域解析運算符)
- 2、重載函數
- 3、帶有默認參數值的函數
- 4、重載函數 VS 帶有默認參數值的函數
- 5、內聯函數(Inline Function)
- 1. 普通函數的優缺點
- 2. 使用內聯函數
- 3. 定義內聯函數
- 4. 內聯函數的使用
- 5. 將內聯函數的聲明和定義分離
- 6. 內聯函數使用限制
1、變量的作用域
1. 變量的作用域分類
a. 全局作用域:全局變量
b. 局部作用域:局部變量
局部作用域可以分為:文件作用域、函數作用域以及函數內部的塊作用域。
如果外部代碼塊與其內嵌代碼塊有同名的變量,那么會產生同名覆蓋這種現象。此時要遵循“就近原則”來判斷哪個同名變量起作用
例如下面func2中,for循環中又定義了一個i,在運行sum+=i;
時根據就近原則,選擇for定義的i,而不是一開始定義的i。
在cout中的i是一開始定義的i,因為已經跳出for循環了。
2. Unary Scope Resolution (一元作用域解析運算符)
If a local variable name is the same as a global variable name, you can access the global variable using ::globalVariable. (局部變量名與全局變量名相同時,可使用 :: 訪問全局變量,要定義在主函數外部)
The :: operator is known as the unary scope resolution.(:: 這個運算符被稱為一元作用域解析運算符)
#include <iostream>
int v1 = 10;
int main() {int v1 = 5;std::cout << "local variable v1 is " << v1 << std::endl;std::cout << "global variable v1 is " << ::v1 << std::endl;return 0;
}
2、重載函數
重載函數是在同一個名字空間中存在兩個或者多個具有相同名字的函數所構成的語法現象。
調用重載函數的語句,是由編譯器在編譯期確定的。
編譯器判斷某個函數調用語句所對應的重載函數時,判斷依據是函數參數的類型、個數和次序。
如果編譯器無法判定,就會報告二義性錯誤。
3、帶有默認參數值的函數
函數的參數可以指定默認值。
指定默認值時,要保證帶有默認值的參數要位于函數參數列表的右側。
如下:
調用帶有默認參數值的函數時,如果不指定帶有默認值的參數,則該參數自動被賦為默認值。且調用的時候應該實參前置。
C++規定(C++03/C++11): A default argument shall not be redefined by a later declaration (not even to the same value). (函數重定義/聲明時,不允許重定義默認參數)
int Add (int a, int b = 3); // 原型聲明
int Add (int a, int b = 3) { // 錯誤!不能重定義默認參數值,
// 盡管與原型聲明相同
}
如下:
#include <iostream>
void printArea(double radius = 1);
int main()
{printArea();printArea(4);return 0;
}
void printArea(double radius)
{std::cout << "Area is " << radius*radius*3.14 << std::endl;
}
4、重載函數 VS 帶有默認參數值的函數
此時不能判斷調用的是哪個函數。
5、內聯函數(Inline Function)
1. 普通函數的優缺點
1.1. Pros(優點): 易讀易維護
1.2. Cons (缺點): 調用時有開銷
函數調用時:參數及部分CPU寄存器的內容進棧,控制流跳轉
函數返回時:返回值及寄存器值出棧,控制流跳轉
2. 使用內聯函數
目的:減小函數調用開銷
方法:代碼插入到調用處
結果:導致程序變大
3. 定義內聯函數
定義函數時,在函數類型前面加上 inline 關鍵字,則該函數就成為內聯函數。
一般而言,內聯函數的聲明和定義都在一起。我們很少將內聯函數的聲明和定義分開編寫。
// 定義內聯函數inline int max (int a, int b) {return (a > b ? a : b);}
// Calling (調用內聯函數)int x = max (3, 5);int y = max (0, 8);// Inline expansion(內聯展開)int x = (3 > 5 ? 3 : 5);int y = (0 > 8 ? 0 : 8);
4. 內聯函數的使用
編譯器在遇到內聯函數的調用時,會將內聯函數的函數體展開到調用位置,從而避免函數調用的開銷。
一般來說,內聯函數只有在需要考慮程序運行性能的環境中才使用。
程序員所用的 inline 關鍵字,只是對編譯器的一個請求。內聯函數是否展開,是由編譯器決定的。
5. 將內聯函數的聲明和定義分離
在C++標準7.1.2.4節有如下說明
An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its definition appears in the translation unit. —end note ]
內聯函數應在每個翻譯單元中定義。在該翻譯單元中它遵循“單一定義規則(ODR)”,并且所有該內聯函數定義必須完全相同。[注釋:在翻譯單元中可能會在內聯函數定義出現之前就有調用該內聯函數的語句]
因此,內聯函數聲明和定義分類的用法如下:
#include <iostream>inline void foo();int main() {foo();}inline void foo() {std::cout << "Hi\n";}
6. 內聯函數使用限制
適用于頻繁調用的短函數 不適用于多處調用的長函數
內聯函數只是一種編譯機制
inline是對編譯器的請求,而不是命令
大多數編譯器并不把帶有循環、遞歸、靜態變量或者代碼較多的函數進行內聯編譯