C语言关键字static与extern的详细解释
參考原文地址(static):https://blog.csdn.net/keyeagle/article/details/6708077
參考原文地址(extern):https://www.cnblogs.com/Lunais/p/5991135.html
C語言中的static與extern是C語言32個關(guān)鍵字中的比較重要的兩個內(nèi)容,也是我近期在學習C++過程中理解較為晦澀的部分,為此,參考了一些優(yōu)質(zhì)資料,在此做個總結(jié)。
C語言代碼是以文件為單位來組織的,在一個源程序的所有源文件中,一個外部變量(注意不是局部變量)或者函數(shù)只能在一個源程序中定義一次,如果有重復定義的話編譯器就會報錯。伴隨著不同源文件變量和函數(shù)之間的相互引用以及相互獨立的關(guān)系,產(chǎn)生了extern和static關(guān)鍵字。
修飾符extern用在變量或者函數(shù)的聲明前,用來說明“此變量/函數(shù)是在別處定義的,要在此處引用”。
一、static修飾全局變量
一個程序在內(nèi)存中的布局:棧(局部變量,動態(tài)分配)、堆(用戶自行申請、釋放,通過指針訪問)、bss段(存放進程中未初始化的全局變量)、data段(存放進程中初始化的全局變量)、text段(存放程序執(zhí)行的二進制文件)、其他段(未知)。
靜態(tài)全局變量:當進程中一個全局變量被static修飾后(被聲明為static),則該全局變量被稱為靜態(tài)全局變量。
靜態(tài)全局變量的存儲位置不變,在bss段(未初始化)或者data段(初始化),但它的作用域是僅在它的源文件內(nèi),其它源文件都無法訪問它。所以,當全局變量被static修飾后,就會限定在當前源文件(.c)內(nèi)使用。
全局變量:隱式被static修飾的全局變量,作用域也是僅在它的源文件內(nèi),不能被其它源文件訪問。但與靜態(tài)全局變量(顯式被static修飾的全局變量)不同的是全局變量在其它源文件中可以通過extern聲明后訪問,而靜態(tài)全局變量則無法訪問。
file1.h文件,聲明printer函數(shù)
//file1.hvoid printer(void);
file1.c文件,定義了 靜態(tài)全局變量name、全局變量address,以及printer函數(shù)
file2.c文件,可以成功調(diào)用printer函數(shù),也可以通過extern聲明訪問全局變量address,但是無法訪問name(即使被extern聲明)
二、static修飾局部變量
局部變量可以被存放在棧(動態(tài)分配,每次調(diào)用,位置都可能不同,作用域是局部)、堆(申請內(nèi)存,要記得釋放,作用域可以是整個源文件)當中。
靜態(tài)局部變量:局部變量被static修飾后,則稱為靜態(tài)局部變量。靜態(tài)局部變量則被存放在data段內(nèi)(定義時,如果用戶沒有初始化,編譯器會自動將其初始化為0),而且整個進程周期中,只定義和初始化一次,每次調(diào)用局部函數(shù)時,靜態(tài)局部變量都會維持最后一次修改的值,作用域是局部代碼段。
file3.c文件,在函數(shù)printer內(nèi)分別定義了普通局部變量(i)和靜態(tài)局部變量(j)。
file.c文件執(zhí)行結(jié)果如下:
可見,普通局部變量(i)每次調(diào)用函數(shù)的訪問的值都不一樣,而且隨機;靜態(tài)局部變量,定義初始化為0,并每次訪問都是上一次函數(shù)調(diào)用修改的值。
三、static修飾函數(shù)
static函數(shù):被關(guān)鍵字static修飾的函數(shù)。static函數(shù)作用域是源文件,即其他源文件無法調(diào)用該函數(shù),類似C++中的private函數(shù)。而對于普通函數(shù)而言,其他源文件只要添加了該函數(shù)的頭文件(.h),其他源文件就可以調(diào)用該函數(shù)。
當你的程序中有很多個源文件的時候,你肯定會讓某個源文件只提供一些外界需要的接口,其他的函數(shù)可能是為了實現(xiàn)這些接口而編寫,這些其他的函數(shù)你可能并不希望被外界(非本源文件)所看到,這時候就可以用static修飾這些“其他的函數(shù)”。
file4.h文件,聲明了普通函數(shù)(func1)和靜態(tài)函數(shù)(func2)
file4.c文件,定義了普通函數(shù)(func1)和靜態(tài)函數(shù)(func2)
file5.c文件,通過添加file4.h,可以調(diào)用func1(),但無法調(diào)用func2()。但是,func1()可以調(diào)用func2()。
可見,靜態(tài)函數(shù)只能被它的源文件調(diào)用,而無法被其它源文件調(diào)用(即使添加了對應(yīng)的頭文件)。
而且,static函數(shù)可以很好地解決不同源文件中函數(shù)同名的問題,因為一個源文件對于其他源文件中的static函數(shù)是不可見的。
四、extern修飾變量的聲明
extern聲明變量:表明該變量在其他源文件里已經(jīng)被定義,此處需要使用。extern聲明的變量必須是在其他源文件內(nèi)的非靜態(tài)的全局變量(保證作用域不受限制,可以聲明)。
舉例在file1.h/file1.c/file2.c中。
五、extern修飾函數(shù)的聲明
extern聲明函數(shù):表明該函數(shù)在其他源文件里已經(jīng)被定義,此處需要使用。extern聲明的變量必須是在其他源文件內(nèi)的非靜態(tài)的函數(shù)(保證作用域不受限制)。
那么我們有兩種方式可以其他源文件內(nèi)的非靜態(tài)函數(shù),一種是添加該函數(shù)聲明頭文件(加載該頭文件的全部函數(shù),編譯較慢),另一種是使用extern修飾(調(diào)用哪個函數(shù),就聲明哪個函數(shù),編譯較快,效率較高)。
舉例在file4.h/file4.c/file5.c中。
?
總結(jié)
以上是生活随笔為你收集整理的C语言关键字static与extern的详细解释的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 教你怎么在vi和vim上查找字符串
- 下一篇: 硬编码 and 软编码