用static聲明限定外部變量與函數(shù),可以將其后聲明的對象的作用域限定為被編譯源文件的剩余部分。要降對象指定為靜態(tài)存儲,可以在正常的聲明之前加上關(guān)鍵字static作為前綴。
一個聲明中最多只能有一個存儲類說明符。如果沒有指定存儲類說明符,則將按照下列規(guī)則進(jìn)行:
在函數(shù)內(nèi)部聲明的對象被認(rèn)為是auto類型;
在函數(shù)內(nèi)部聲明的函數(shù)被認(rèn)為是extern類型;
在函數(shù)外部聲明的對象與函數(shù)將被認(rèn)為是static類型,且具有外部連接。
如果一個對象或函數(shù)的第一個外部聲明包含static說明符,則該標(biāo)識符具有內(nèi)部連接,否則具有外部連接。
說明符staitc將聲明的對象說明為靜態(tài)存儲類。這種對象可以用在函數(shù)內(nèi)部或函數(shù)外部。在函數(shù)內(nèi)部,該說明符將引起存儲空間的分配,具有定義的作用。static類型的對象僅在程序開始執(zhí)行前初始化一次。
如果一個對象的外部聲明帶有初值,則該聲明就是一個定義。如果一個外部對象聲明不帶有初值,并且不包含extern說明符,則它是一個臨時定義。如果對象的定義出現(xiàn)在翻譯單元中,則所有臨時定義都將僅僅被認(rèn)為是多余的聲明;如果該翻譯單元中不存在該對象的定義,則該臨時定義將轉(zhuǎn)變?yōu)橐粋€初值為0的定義。
在C語言中,全局變量和靜態(tài)變量都是存儲在靜態(tài)存儲區(qū)的。針對未初始化的全局變量(或靜態(tài)變量)都被系統(tǒng)默認(rèn)初始化為0。
c99標(biāo)準(zhǔn),在6.7.8/10中有談到變量初值(未初始化的靜態(tài)存儲對象一律清零)
If an object that has automatic storage duration is not initialized explicitly, its value isindeterminate. If an object that has static storage duration is not initialized explicitly,then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to theserules.
通過static限定外部對象,可以達(dá)到隱藏外部對象的目的。
特點(diǎn):
a.在全局區(qū)分配內(nèi)存;
b.該變量在本文件內(nèi)從定義開始到文件結(jié)束可見;
static也可用于聲明內(nèi)部變量。static類型的內(nèi)部變量通自動變量一樣,是某個特定函數(shù)的局部變量,只能在該函數(shù)中使用,但它與自動變量不同的是,不管其所在的函數(shù)是否被調(diào)用,它一直存在,而不像自動變量那樣,隨著所在函數(shù)的被調(diào)用和退出而存在和消失。換句話說,static類型的內(nèi)部變量是一種只能在某個特定函數(shù)中使用但一直占據(jù)存儲空間的變量。
特點(diǎn):
a.該變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存;
b.它始終駐留在全局?jǐn)?shù)據(jù)區(qū),直到程序運(yùn)行結(jié)束;
c. 其作用域?yàn)榫植孔饔糜?,?dāng)定義它的函數(shù)或語句塊結(jié)束時,其作用域隨之結(jié)束;
Demo:
#include static int nGlobal;void func1(void){ static int nLocal = 0; nLocal++; printf("nLocal:%d/r/n",nLocal);}void func2(void){ nGlobal = 0; nGlobal++; printf("nGlobal:%d/r/n", nGlobal);}void func3(void){ int nTmp = 0; nTmp++; printf("nTmp:%d/r/n",nTmp);}int main(){ int i = 0; for(i = 0; i < 10; i++) { func1(); func2(); func3(); } return 0;}
打印:
nLocal:1nGlobal:1nTmp:1nLocal:2nGlobal:1nTmp:1nLocal:3nGlobal:1nTmp:1nLocal:4nGlobal:1nTmp:1nLocal:5nGlobal:1nTmp:1nLocal:6nGlobal:1nTmp:1nLocal:7nGlobal:1nTmp:1nLocal:8nGlobal:1nTmp:1nLocal:9nGlobal:1nTmp:1nLocal:10nGlobal:1nTmp:1
外部的static聲明通常多用于變量,當(dāng)然,它也可用于聲明函數(shù)。通常情況下,函數(shù)名字是全局可訪問的,對整個程序的各個部分而言都可見。但是,如果把函數(shù)聲明為static類型,則該函數(shù)名除了對該函數(shù)聲明所在的文件可見外,其它文件都無法訪問。
“static”使函數(shù)的作用域僅局限于本文件(所以又稱內(nèi)部函數(shù))。使用內(nèi)部函數(shù)的好處是:不同的人編寫不同的函數(shù)時,不用擔(dān)心自己定義的函數(shù),是否會與其它文件中的函數(shù)同名。
特點(diǎn):
a.靜態(tài)函數(shù)只能在本源文件中使用;
b.在文件作用域中聲明的inline函數(shù)默認(rèn)為static類型;
Demo1:正常函數(shù)調(diào)用,以test()為例
test.c
#include void Test();void Test(){ printf("This is test()/n");}
main.c
#include extern Test();int main(){ Test(); return 0;}
打?。?br />
Demo2:使用static修飾后的test()函數(shù)
test.c
#include static void Test();static void Test(){ printf("This is test()/n");}
main.c
#include extern Test();int main(){ Test(); return 0;}
編譯報錯:
1>------ 已啟動生成: 項目: ConsoleApplication1, 配置: Debug Win32 ------1>test.c1>main.obj : error LNK2019: 無法解析的外部符號 _Test,該符號在函數(shù) _main 中被引用1>C:/Users/mints/Documents/Visual Studio 2017/Projects/ConsoleApplication1/Debug/ConsoleApplication1.exe : fatal error LNK1120: 1 個無法解析的外部命令1>已完成生成項目“ConsoleApplication1.vcxproj”的操作 - 失敗。========== 生成: 成功 0 個,失敗 1 個,最新 0 個,跳過 0 個 ==========
對static的作用做一句話總結(jié)。首先static的最主要功能是隱藏,其次因?yàn)閟tatic變量存放在靜態(tài)存儲區(qū),所以它具備默認(rèn)值0(針對未初始化的全局變量和局部靜態(tài)變量而言)和持久性。
存儲類分為兩類:自動存儲類(automatic)和靜態(tài)存儲類(static)。聲明對象時使用的一些關(guān)鍵字和聲明的上下文共同決定了對象的存儲類。
自動存儲類對應(yīng)一個程序塊來說是局部的,在退出程序塊時該對象將消失。如果沒有使用存儲類說明符,或者如果使用了auto限定符,則程序塊中的聲明生成的都是自動存儲類對象。聲明為register的對象也是自動存儲類對象,并且將被存儲在機(jī)器的快速寄存器中(如果可能的話)。
靜態(tài)對象可以是某個程序塊的局部對象,也可以是所有程序塊的外部對象。無論是哪一種情況,在退出和再進(jìn)入函數(shù)或程序塊時其值將保持不變。在一個程序塊(包括提供函數(shù)代碼的程序塊)內(nèi),靜態(tài)對象用關(guān)鍵字static聲明。在所有程序塊外部聲明且與函數(shù)定義在同一級的對象總是靜態(tài)的??梢酝ㄟ^static關(guān)鍵字將對象聲明為某個特定翻譯單元的局部對象,這種類型的對象將具有內(nèi)部連接。當(dāng)省略顯式的存儲類或通過關(guān)鍵字extern進(jìn)行聲明時,對象對整個程序來說全局可訪問的,并且具有外部連接。
BSS(Block Started by Symbol)通常是用來存放程序中未初始化的或者初始化為0的全局變量和靜態(tài)變量的一塊內(nèi)存區(qū)域。
特點(diǎn)是:可讀寫的,在程序執(zhí)行之前BSS段會自動清0。
所以,未初始化的全局變量或靜態(tài)變量在程序執(zhí)行之前已經(jīng)成0了。
《The C Programming Language Second Edtion》
https://www.cnblogs.com/ustc-anmin/p/11239257.html
http://c.biancheng.net/cpp/html/436.html
https://www.cnblogs.com/gatsbywang/p/5171416.html
https://www.zhihu.com/question/49111720/answer/114331032
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/121413.html
摘要:想著糾結(jié)來糾結(jié)去也沒有什么用,不如就從零開始吧。剛開始配置環(huán)境的時候,建議對照著學(xué)習(xí)視頻進(jìn)行配置,看書配置容易出錯。本文原創(chuàng)發(fā)布于微信公眾號,編程思維成長正能量,關(guān)注并回復(fù)編程閱讀等關(guān)鍵字獲取免費(fèi)學(xué)習(xí)資料 showImg(https://segmentfault.com/img/remote/1460000016088460); 一直關(guān)注我的朋友們應(yīng)該都知道,很早之前我就打算開始寫 J...
摘要:歡迎進(jìn)入基礎(chǔ)課程博客地址本系列文章將主要針對一些基礎(chǔ)知識點(diǎn)進(jìn)行講解,為平時歸納所總結(jié),不管是剛接觸開發(fā)菜鳥還是業(yè)界資深人士,都希望對廣大同行帶來一些幫助。是同步的,而不是。因此,更適合于單線程環(huán)境,而適合于多線程環(huán)境。 歡迎進(jìn)入JAVA基礎(chǔ)課程 博客地址:https://blog.csdn.net/houjiyu...本系列文章將主要針對JAVA一些基礎(chǔ)知識點(diǎn)進(jìn)行講解,為平時歸納所總...
摘要:歡迎進(jìn)入基礎(chǔ)課程博客地址本系列文章將主要針對一些基礎(chǔ)知識點(diǎn)進(jìn)行講解,為平時歸納所總結(jié),不管是剛接觸開發(fā)菜鳥還是業(yè)界資深人士,都希望對廣大同行帶來一些幫助。是同步的,而不是。因此,更適合于單線程環(huán)境,而適合于多線程環(huán)境。 歡迎進(jìn)入JAVA基礎(chǔ)課程 博客地址:https://blog.csdn.net/houjiyu...本系列文章將主要針對JAVA一些基礎(chǔ)知識點(diǎn)進(jìn)行講解,為平時歸納所總...
閱讀 3178·2023-04-25 17:19
閱讀 625·2021-11-23 09:51
閱讀 1352·2021-11-08 13:19
閱讀 786·2021-09-29 09:34
閱讀 1686·2021-09-28 09:36
閱讀 1501·2021-09-22 14:59
閱讀 2718·2019-08-29 16:38
閱讀 2061·2019-08-26 13:40