效能測試 學習筆記
1.c++ pp page 250
儲存持續性:資料保留在記憶體中的時間;(注:自動儲存持續性:在函式定義中宣告的變數(包括函式引數)的儲存持續性為自動的。它們在程式開始執行其所屬的函式或程式碼塊時被建立,而不是程式執行到定義語句時才被建立)
作用域描述了名稱在檔案(翻譯單元)的多大範圍內可見。全域性作用域(檔案作用域)的變數在定義位置到檔案結尾之間都可用。自動變數的作用域為區域性。靜態變數的作用域是全域性還是區域性取決於它是被如何定義的。在名稱空間中宣告的變數的作用域為整個名稱空間。
連結性描述了名稱如何在不同單元間共享,連結性分為外部(可在檔案間共享)、內部(可在整個檔案內共享)和沒有連結性(自動變數無連結性,不能共享)。
2.自動儲存持續性
1)預設情況下,函式中宣告的函式引數和變數的儲存持續性為自動,作用域為區域性,沒有連結性。當程式開始執行這些變數所屬的程式碼塊時,將為其分配記憶體;當函式結束時,這些變數將消失。(注意,執行到程式碼塊時,將為變數分配記憶體,但其作用域的起點為其宣告位置)
2)自動變數和棧 p252
程式在執行時對自動變數進行管理;常用的方法是留出一段記憶體,並將其視為棧。
在函式傳遞引數時也使用棧。
3.靜態持續變數 p253
1)c++為靜態儲存持續性變數提供了3中連結性:外部連結性(可在其他檔案中訪問)、內部連結性(只能在當前檔案中訪問)和無連結性(只能在當前函式或程式碼塊中訪問)。
編譯器將分配固定的記憶體塊來儲存所有的靜態變數,這些變數在整個程式執行期間一直存在。
... int global = 1000;//靜態儲存持續性,外部連結性 static int one_file = 50;//靜態儲存持續性,內部連結性 int main() { ... } void funct1(int n) { static int count = 0;靜態儲存持續性,無連結性 int llama = 0; ... }
上述程式碼中,count 與 自動變數llama不同,在funct1()函式沒有執行時,lemma是自動變數,自然不在記憶體中;但count不管funct1()是否執行,其都在記憶體中。(程式執行期間一直存在)\
2)靜態變數的初始化分為零初始化,常量表達式初始化和動態初始化。
零初始化指變數被設定為0;所有的靜態變數剛開始都被零初始化,不管程式設計師是否顯示的初始化了它。
如果使用常量表達式初始化了變數,且編譯器僅根據檔案內容(包括被包含的標頭檔案)就可計算表示式,編譯器將執行常量表達式初始化。
零初始化和常量表達式初始化被統稱為靜態初始化。靜態初始化意味著編譯器在處理檔案(翻譯單元)時初始化變數。
如果沒有足夠的資訊,變數將被動態初始化。動態初始化意味著變數將在編譯後初始化。
#include <cmath> int x;//零初始化 int y = 5;//常量表達式初始化 long z = 13*13;//常量表達式初始化 const double pi = 4.0 * atan(1.0);//要呼叫函式atan(),這需要等到該函式被連結且程式執行時,因此是動態初始化。
靜態變數即靜態儲存持續性變數。
4.靜態儲存持續性、外部連結性 p254
連結性為外部的變數簡稱為外部變數,它們的儲存持續性為靜態,作用域為整個檔案(外部變數的作用域也是整個檔案)。外部變數也被稱為全域性變數。
1)單定義規則
c++提供了兩種變數宣告:定義宣告(或簡稱為“定義”),它給變數分配儲存空間。另一種是引用宣告(簡稱為“宣告”),它不給變數分配儲存空間。
引用宣告使用關鍵字extern,且不進行初始化。否則其為定義宣告,導致分配儲存空間。
單定義規則指要在多個檔案中使用外部變數,只需在一個檔案中包含該變數的定義,但在使用該變數的所有其他檔案中,都必須使用關鍵字extern宣告它。
//file1.cpp int cats = 20;//定義宣告 ... //file2.cpp extern int cats;//引用宣告
2)如果在函式中聲明瞭一個與外部變數同名的變數,區域性變數將隱藏全域性變數。
如果要使用該全域性變數,應在該全域性變數之前加上標準名稱空間std中的作用域解析運算子(::)。
//file.cpp int cats = 20; ... //file2.cpp extern int cats; int main() { int cats = 10; cout<<cats<<endl;//output 10 cout<<std::cats<<endl;//output 20 return 0; }
5.靜態儲存持續性,內部連結性 p257
將static限定符用於作用域為整個檔案的變數時,該變數的連結性將為內部的。
如果檔案定義了一個連結性為內部的靜態儲存持續性的變數,其名稱與另一個檔案中宣告的常規外部變數相同,則在該檔案中,連結性為內部的靜態儲存持續性的變數將隱藏常規外部變數。
//file1.cpp int errors = 20; ... //file2.cpp static int errors = 5; void froobish() { cout<<errors;//output 5 ... }
上述程式碼中,file2.cpp中的連結性為內部的靜態儲存持續性變數遮蔽file1.cpp中的常規外部變數。
且上述程式碼未違反單定義規則,因為單定義規則是指常規外部變數只能在多個檔案中有一個定義,但file2.cpp中的error的連結性未內部,並非要提供外部定義。
6.靜態儲存持續性,無連結性--區域性變數 p258
在程式碼塊中使用static時,將導致區域性變數的儲存持續性為靜態的。該變數雖然只在該程式碼塊中可用,但該變數在整個程式執行期間一直存在,即當沒有執行該程式碼塊時,該變數仍然存在於記憶體中。
因此在兩次函式呼叫之間,靜態區域性變數的值保持不變。
即,靜態區域性變數只在程式啟動時進行一次初始化,以後再呼叫時,將不會像自動變數那樣再次被初始化。
7.說明符和限定符 p260
儲存說明符 auto register static extern thread_local mutable
cv-限定符:const volatile
const:(p260)
預設情況下全域性變數(外部變數被稱為全域性變數p254)的連結性為外部的,但const全域性變數的連結性為內部的。即,全域性const定義就像使用了static說明符一樣。
如果處於某種原因,程式設計師希望某個常量的連結性為外部的,則可以使用extern關鍵字來覆蓋預設的內部連結性:
extern const int states = 50;//連結性為外部
在這種情況下,必須在所有使用該常量的檔案中使用extern關鍵字來宣告它。
在函式或程式碼塊中宣告const時,其作用域為程式碼塊。
8.函式和連結性 p261
所有的函式的儲存持續性自動為靜態的,即在整個程式執行期間都一直存在。
預設情況下,函式的連結性為外部的,既可以在檔案間共享。可以在函式原型中使用extern關鍵字來指出函式實在另一個檔案中定義的。
還可以使用static關鍵字將函式的連結性設定為內部的,使之只能在一個檔案中使用。必須同時在原型和函式定義中使用該關鍵字:
static int private(double x); ... static int private(double x) { ... }