Stroustrup 在自傳中說自己在哲學上深受 Kierkegaard (吉爾凱高爾)的影響,而討厭黑格爾。所以看 Stroustrup 的書,很少感受到抽象理論的重要性。這也影響了C++的文化:許多C++程序員很會寫代碼,但是概念說不清楚,感覺生活很難( :)。 這多多少少怪C++的鼻祖 Stroustrup 本人。
閒話少說,關於C++變量的屬性問題,是C++最根本的問題。然而我還沒有讀過一本書能從抽象,理論高度說清楚的。今天我就試圖談談C++變量的屬性。我認為,每個C++變量有六個無法分離的屬性(把名和類合並),理解了,你就入了C++的門:
C++中沒有“未知類”變量
C++的變量用名字的唯一性來辨識,同一scope中沒有同名的變量
數據段(data segment)變量
堆棧(stack) 變量
堆疊(heap) 變量:(只能是分變量)
1。默認名空間( :: namespace)
2。命名空間( named namespace)
3。無名空間(anonymous namespace):文件變量
4。型 (static class variable or type variable)
5。實例(instance class member variable)
6。函數內 - 靜態 (static variable in a function)
7。函數內(或代碼塊內)- 動態 (auto variable or stack variable)
程序初始至結束:global
代碼塊(code block): auto
New/delete: free
第一次使用至程序結束: static in function
直接內容
直接變量
間接內容
指針變量
引用變量
總(whole variable)變量
分(part variable) 變量:即成員變量
前四個屬性都有著述,而第五,六個屬性似乎無人或鮮有人提出。
關於“總分性”,該詞這是我在查Mereology翻譯時找到的唯一較好的翻譯。我幾乎找不到有前人論述的信息(知道的請告訴我)。
他的意思是“總體”與“部分”的關系。翻譯成總部也不好,總分亦不完美,但是比總部稍稍謙虛點:)
有了這個概念,我們可以進一步區分兩種變量:
A. 獨立變量:是個總體,不屬於任何變量,或可稱為“母變量”
B. 成員變量:是個部分體,隸屬一個總變量,或可稱為“子變量”
為什麼總分性對於一個變量很重要呢?因為:
1) 一個存儲屬性為 Heap 的變量只能為子變量。
A* pA = new A; //line1
pA是指針變量,它本身不在heap中,它只是“指向Heap地址”。
如果A定義為: class A { B b;},那麼line1導致了子變量b的存儲屬性是Heap.
從另一個角度說,Heap中的母變量總是無名的,它只有通過指針間接地存在。
2) 子變量的存儲屬性決定於母變量的存儲屬性
比如 class A { }; class B { A *pA; };foo(){B b;}
b 作為母變量,存儲屬性是堆棧,而它的子變量 pA,也在堆棧中。如果B *b = new B,那麼 pA 的屬性就是 Heap。
3)子變量在運行時可以被優化成其母變量的“域”,所以它的讀/寫是通過它的母變量進行的,不用單獨“取址”(即按名取址),性能較母變量稍好。
比如b.f1可以被優化為b+offsetof(f1), f1在運行時被“抹去名字”。
理解C++變量的六大屬性,是深入理解C++變量,也是C++語義的重要一環。由於“總分性”的概念不為專家強調,這裡專門著文小序,以期拋磚引玉。
p是一個指針,他的值是內存中一塊內存的地址,如FF80H,*P則表示那塊地址中所存儲的值(如FF80H那個地址所存儲的值為234),所以當p = 1時,指的是將p改指向的地址為0001H;而*p意味著將那塊地址中所存的值改為1.
全局變量是使用相同的內存塊在整個類中存儲一個值.
全局變量的存在主要有以下一些原因:
1,使用全局變量會占用更多的內存(因為其生命期長),不過在計算機配置很高的今天,這個不成為什麼問題,除非使用的是巨大對象的全局變量,能避免就一定要避免。
2,使用全局變量程序運行時速度更快一些(因為內存不需要再分配),同樣現在也快不了多少。
3,對於局部變量的名字空間污染,這個在不使用太多變量時是可以避免的。
總之,全局變量可以使用,但是全局變量使用時應注意的是盡可能使期名字易於理解,而且不能太短,避免名字空間的污染;避免使用巨大對象的全局變量。
局部變量:在程序中,只在特定的過程或函數中可以訪問的變量,是相對與全局變量而言的。
全局變量也稱為外部變量,是在函數的外部定義的,它的作用域為從變量定義處開始,到本程序文件的末尾。全局變量全部存放在靜態存儲區,在程序開始執行時給全局變量分配存儲區,程序行完畢就釋放。
局部變量可以和全局變量重名,但是局部變量會屏蔽全局變量。在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。