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