c語言的作用域有兩種,**塊作用域和檔案作用域。**塊作用域是指由花括號限定的作用域,花括號以外的作用域就是檔案作用域。這裡指的花括號可以是函式的花括號,if,while,for,namespace的花括號,遵循的基本規則是花括號以里可以看到本花括號以外的東西,但是相反則不可以。
int main()
x=2;
}
比如這段**編譯器會報錯「未宣告的識別符號x」。
在**塊以外生命的函式或者變數屬於檔案作用域,當未加限定時,他們是全域性可見的。即可以在別的檔案中去訪問他們,當然需要在使用他們的檔案中加入對它們的宣告。我們可以使用static來限定檔案作用域中的變數和函式的可見範圍,如此做可以讓他們只在定義他們的檔案中可見。
另外對**塊作用域正確與否的檢測是在編譯階段完成的,由於編譯階段只能看到本檔案的內容,所以檔案作用域中的變數是否在其他檔案中正確定義編譯器是不得而知的,如果使用的變數在別的檔案中並沒有定義,那麼在連線的時候會報錯。
明確一點,強符號和弱符號是對鏈結而言的,這兩個概念一般只會被用在檔案定義域中。c/c++允許在檔案定義域中定義兩個同樣名字的變數,當然這其中需要遵循一定的規則。
對於c/c++而言,編譯器預設函式已初始化的全域性變數為強符號,而未初始化的全域性變數為弱符號。開發者可以對符號進行指定,使用__attribute__((weak))來將乙個強符號轉變為弱符號。
int __attribute__((weak)) x=0;
看到這裡可能會讓人一頭霧水,不明白這樣的性質有什麼實際價值。其實這個性質最大的作用是用在函式庫中,我們可以把函式庫中的某個函式定義為弱符號,這樣使用者可以在自己的檔案中重新定義乙個重名的函式去替代庫函式中的函式,因為如果不加以刻意宣告,使用者定義的屬於強符號,遵循上邊的規則,鏈結器會優先使用強符號。我們通過乙個例子來感受一下。
當我們把main.c中的weak_func注釋掉
這種特性讓我們很方便的對乙個庫的功能進行剪裁和組合。
弱符號與強符號,弱引用與強引用
對c c 而言,編譯器預設函式和初始化了的全域性變數為強符號。未初始化的全域性變數為弱符號。此處弱符號與強符號均是針對定義來說的,不是針對符號的引用。也可以通過gcc的 attribute weak 來定義任何乙個強符號為弱符號。cpp view plain copy extern in ext i...
弱符號與強符號概念
from c語言的強符號和弱符號是c初學者經常容易犯錯的地方。而且很多時候,特別是多人配合開發的程式,它引起的問題往往非常行為怪異而且難以定位。什麼是強符號和弱符號?在c語言中,函式和初始化的全域性變數是強符號,未初始化的全域性變數時弱符號。強符號和弱符號的定義是聯結器用來處理多重定義符號的,它的規...
c c 強符號與弱符號
編譯器預設函式和初始化了的全域性變數為強符號,未初始化的全域性變數為弱符號,也可以通過gcc attribute weak 來定義任何乙個強符號變為弱符號。gcc 中,我們也可以通過使用 attribute weakref 這個擴充套件關鍵字來宣告乙個對外部函式的引用為弱引用。attribute w...