C++(一)——存储持续性、作用域、链接性
存儲持續性、作用域、鏈接性
- 自動存儲持續性:在函數定義中聲明的變量(包括函數參數)的存儲持續性為自動的。它們在程序開始執行其所屬的函數或代碼塊時被創建,在執行完函數或代碼塊時,它們使用的內存被釋放。C++有兩種存儲持續性為自動的變量。
- 靜態存儲持續性:在函數定義外定義的變量和使用關鍵字static定義的變量的存儲持續性都為靜態。它們在程序整個運行過程中都存在。C+ +有3種存儲持續性為靜態的變量。線程存儲持續(C++11) :當前,多核處理器很常見,這些CPU可同時處理多個執行任務。這讓程序能夠將計算放在可并行處理的不同線程中。如果變量是使用關鍵字thread_ local聲明的 ,則其生命周期與所屬的線程一樣長。
- 動態存儲持續性:用new運算符分配的內存將一直存在, 直 到使用delete運算符將其釋放或程序結束為止。這種內存的存儲持續性為動態,有時被稱為自由存儲( free store )或堆( heap )
1.自動存儲持續性
1.1.自動變量的初始化
1.2.自動變量和棧
????????了解典型的C+ +編譯器如何實現自動變量有助于更深入地了解自動變量。由于自動變量的數目隨函數的開始和結束而增減,因此程序必須在運行時對自動變量進行管理。常用的方法是留出一段內存,并將其視為棧,以管理變量的增減。之所以被稱為棧,是由于新數據被象征性地放在原有數據的上面(也就是說,在相鄰的內存單元中,而不是在同一個內存單元中) ,當程序使用完后,將其從棧中刪除。棧的默認長度取決于實現,但編譯器通常提供改變棧長度的選項。程序使用兩個指針來跟蹤棧,一個指針指向棧底一棧的開始位置,另一個指針指向堆項 下一 個可用內存單元。當函數被調用時,其自動變量將被加入到棧中,棧頂指針指向變量后面的下一個可用的內存單元。函數結束時,棧頂指針被重置為函數被調用前的值,從而釋放新變量使用的內存。
????????棧是LIFO (后進先出)的,即最后加入到棧中的變量首先被彈出。這種設計簡化了參數傳遞。函數調用將其參數的值放在棧頂,然后重新設置棧頂指針。被調用的函數根據其形參描述來確定每個參數的地址。
1.3.寄存器變量
2.靜態持續變量
????????和C語言一樣,C++也為靜態存儲持續性變量提供了3種鏈接性:外部鏈接性(可在其他文件中訪問)、內部鏈接性(只能在當前文件中訪問)和無鏈接性(只能在當前函數或代碼塊中訪問)。這3種鏈接性都在整個程序執行期間存在,與自動變量相比,它們的壽命更長。由于靜態變量的數目在程序運行期間是不變的,因此程序不需要使用特殊的裝置(如棧)來管理它們。編譯器將分配固定的內存塊來存儲所有的靜態變量,這些變量在整個程序執行期間一直存在。另外,如果沒有顯式地初始化靜態變量,編譯器將把它設置為0。在默認情況下,靜態數組和結構將每個元素或成員的所有位都設置為0。
例子?
????????正如前面指出的,所有靜態持續變量(上述示例中的global、one_ file和count )在整個程序執行期間都存在。在funct1()中聲 明的變量count的作用域為局部,沒有鏈接性,這意味著只能在funct1()函數中使用它,就像自動變量lam一樣。然而,與llama不同的是,即使在funct1()函數沒有被執行時,count也留在內存中。global和one_ file的作用 域都為整個文件,即在從聲明位置到文件結尾的范圍內都可以被使用。具體地說,可以在main(、funct1()和funct2()中使用它們。 由于one_ file的鏈接性為內部,因此只能在包含上述代碼的文件中使用它;由于global的鏈接性為外部,因此可以在程序的其他文件中使用它。
5種變量存儲方式?
3.靜態持續性,外部鏈接性
????????鏈接性為外部的變量通常簡稱為外部變量,它們的存儲持續性為靜態,作用域為整個文件。外部變量是在函數外部定義的,因此對所有函數而言都是外部的。例如,可以在main()前面或頭文件中定義它們。可以在文件中位于外部變量定義后面的任何函數中使用它,因此外部變量也稱全局變量( 相對于局部的自動變量)。
3.1單定義規則
3.2 全局變量和局部變量
????????既然可以選擇使用全局變量或局部變量,那么到底應使用哪種呢?首先,全局變量很有吸引力,因為所有的函數能訪問全局變量,因此不用傳遞參數。但易于訪問的代價很大——程序不可靠。 計算經驗表明,程序越能避免對數據進行不必要的訪問,就越能保持數據的完整性。通常情況下,應使用局部變量,應在需要知曉時才傳遞數據,而不應不加區分地使用全局變量來使數據可用。讀者將會看到,OOP在數據隔離方面又向前邁進了一步。然而,全局變量也有它們的用處。例如,可以讓多個函數可以使用同一一個數據塊(如月份名數組或原子量數組)。外部存儲尤其適于表示常量數據,因為這樣可以使用關鍵字const來防止數據被修改。
4.靜態持續性,內部鏈接性
????????將static限定符用于作用域為整個文件的變量時,該變量的鏈接性將為內部的。在多文件程序中,內部鏈接性和外部鏈接性之間的差別很有意義。鏈接性為內部的變量只能在其所屬的文件中使用;但常規外部變量都具有外部鏈接性,即可以在其他文件中使用,如前面的示例所示。
注意:在多文件程序中,可以在一個文件(且只能在一一個文件)中定義一個外部變量。使用該變量的其他文件必須使用關鍵字extern聲明它。?
正確示例
?兩個程序的輸出
?5.靜態存儲持續性,無鏈接性
????????至此,介紹了鏈接性分別為內部和外部、作用域為整個文件的變量。接下來介紹靜態持續家族中的第三個成員——無鏈接性的局部變量。 這種變量是這樣創建的,將static限定符用于在代碼塊中定義的變量。在代碼塊中使用static時,將導致局部變量的存儲持續性為靜態的。這意味著雖然該變量只在該代碼塊中可用,但它在該代碼塊不處于活動狀態時仍然存在。因此在兩次函數調用之間,靜態局部變量的值將保持不變。另外,如果初始化了靜態局部變量,則程序只在啟動時進行一次初始化。以后再調用函數時,將不會像自動變量那樣再次被初始化。
?6.函數和鏈接性
????????和變量一樣,函數也有鏈接性,雖然可選擇的范圍比變量小。和C語言一樣,C++不允許在個函數中定義另外一一個函數,因此所有函數的存儲持續性都自動為靜態的,即在整個程序執行期間都一直存在。在默認情況下,函數的鏈接性為外部的,即可以在文件間共享。實際上,可以在函數原型中使用關鍵字extern來指出函數是在另一個文件中定義的,不過這是可選的(要讓程序在另一個文件中查找函數,該文件必須作為程序的組成部分被編譯,或者是由鏈接程序搜索的庫文件)。還可以使用關鍵字static將函數的鏈接性設置為內部的,使之只能在一個文件中使用。必須同時在原型和函數定義中使用該關鍵字:
?????????這意味著該函數只在這個文件中可見,還意味著可以在其他文件中定義同名的的函數。和變量一樣,在定義靜態函數的文件中,靜態函數將覆蓋外部定義,因此即使在外部定義了同名的函數,該文件仍將使用靜態函數。
????????單定義規則也適用于非內聯函數,因此對于每個非內聯函數,程序只能包含一一個定義。對于鏈接性為外部的函數來說,這意味著在多文件程序中,只能有一個文件 (該文件可能是庫文件 ,而不是您提供的 )包含該函數的定義,但使用該函數的每個文件都應包含其函數原型。
????????內聯函數不受這項規則的約束,這允許程序員能夠將內聯函數的定義放在頭文件中。這樣,包含了頭文件的每個文件都有內聯函數的定義。然而,C++要求同一個函數的所有內聯定義都必須相同。
總結
以上是生活随笔為你收集整理的C++(一)——存储持续性、作用域、链接性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RSA算法加密流程
- 下一篇: C++(二)——命名空间(上)