最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
怎么區(qū)分作用域,存儲(chǔ)器,鏈接屬性

本篇內(nèi)容介紹了“怎么區(qū)分作用域,存儲(chǔ)器,鏈接屬性”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)是網(wǎng)站建設(shè)專家,致力于互聯(lián)網(wǎng)品牌建設(shè)與網(wǎng)絡(luò)營(yíng)銷,專業(yè)領(lǐng)域包括成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、電商網(wǎng)站制作開發(fā)、微信小程序、微信營(yíng)銷、系統(tǒng)平臺(tái)開發(fā),與其他網(wǎng)站設(shè)計(jì)及系統(tǒng)開發(fā)公司不同,我們的整合解決方案結(jié)合了恒基網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗(yàn)和互聯(lián)網(wǎng)整合營(yíng)銷的理念,并將策略和執(zhí)行緊密結(jié)合,且不斷評(píng)估并優(yōu)化我們的方案,為客戶提供全方位的互聯(lián)網(wǎng)品牌整合方案!

作用域

C語(yǔ)言中,作用域用來(lái)描述標(biāo)識(shí)符能夠被哪些區(qū)域訪問(wèn)。

而常見作用域有以下幾種:

  • 塊作用域,可見范圍是從定義處到包含該定義的塊結(jié)尾

  • 函數(shù)作用域,goto語(yǔ)句的標(biāo)簽就具有函數(shù)作用域

  • 文件作用域,從定義處到定義該文件的末尾都可見。定義在函數(shù)之外的變量,就具有文件作用域了。

  • 函數(shù)原型作用域,從形參定義處到原型聲明結(jié)束

為了便于說(shuō)明,我們來(lái)看一個(gè)例子,就很容易理解了:

/**************************** 作者:守望先生 來(lái)源:公眾號(hào)編程珠璣 個(gè)人博客:https://www.yanbinghu.com ***************************************/ #include  int num1 = 222;         //定位在函數(shù)外,具有文件作用域 static int num2 = 111;  //定義在函數(shù)外,具有文件作用域 int swap(int *a,int *b); //這里的a,b是函數(shù)原型作用域 int swap(int *a,int *b) {     if(NULL== a || NULL == b)         goto error;         else     {         int temp = *a;  //定義在函數(shù)內(nèi),塊作用域         *a = *b;         *b = temp;         return 0;     }     //printf("temp is %d\n",temp);   //因?yàn)閠emp具有塊作用域,因此在這里不能直接使用     error://goto語(yǔ)句的標(biāo)簽,函數(shù)作用域,因此在前面就可以引用         {             printf("input para is NULL\n");             return -1;         } } int main(void) {     printf("num1=%d,num2=%d\n",num1,num2);     swap(&num1,&num2);  //num1 num2具有文件作用域,可以在main函數(shù)中直接使用     printf("num1=%d,num2=%d",num1,num2);     return 0; }

可以看到,error標(biāo)簽具有函數(shù)作用域,整個(gè)函數(shù)內(nèi)都可見,而temp具有塊作用域,因此在大括號(hào)外部,不能直接使用它。而num1和num2具有文件作用域,因此main函數(shù)可以直接使用它。

鏈接屬性

在《hello程序是如何變成可執(zhí)行文件的》我們說(shuō)到了編譯的過(guò)程,最后一個(gè)步驟就是鏈接。鏈接屬性決定了在不同作用域的同名標(biāo)識(shí)符能否綁定到同一個(gè)對(duì)象或者函數(shù)。或者說(shuō),不同作用域的標(biāo)識(shí)符在編譯后是否是同一個(gè)實(shí)體。

c變量有三種鏈接屬性:

  • 外部鏈接,extern修飾的,或者沒(méi)有static修飾的具有文件作用域的變量具有外部鏈接屬性

  • 內(nèi)部鏈接,static修飾的具有文件作用域的變量具有內(nèi)部鏈接屬性

  • 無(wú)鏈接,塊作用域,函數(shù)作用域和函數(shù)原型作用域的變量無(wú)鏈接屬性

再稍作解釋,沒(méi)有static修飾,且具有文件作用域的變量,他們?cè)阪溄訒r(shí),多個(gè)同名標(biāo)識(shí)符的變量最終都綁定到同一個(gè)實(shí)體。而static修飾的具有文件作用域的變量就不一樣了,不同文件內(nèi),即便標(biāo)識(shí)符名字相同,它們也綁定到了不同的實(shí)體。

因此,如果我們希望某個(gè)變量或函數(shù)只在某一個(gè)文件使用,那么使用static修飾是一個(gè)很好的做法。

同樣的,來(lái)看一個(gè)例子。

/**************************** 作者:守望先生 來(lái)源:公眾號(hào)編程珠璣 個(gè)人博客:https://www.yanbinghu.com ***************************************/ #include  int a = 5;   //文件作用域,外部鏈接屬性,其他文件可通過(guò)extern int a的方式使用該文件的a static b = 6;  //文件作用域,內(nèi)部鏈接屬性,即便其他文件也有同名標(biāo)識(shí)符,它們也是不同的 int main(void) {     int sum = 0 ; //無(wú)鏈接屬性     sum = a + b;     printf("sum is %d\n",sum);     return 0; }

從代碼中可以看到,a和b都具有文件作用域,a具有外部鏈接屬性,而b具有內(nèi)部鏈接屬性,sum具有塊作用域,因此無(wú)鏈接屬性。

存儲(chǔ)期

實(shí)際上作用域和鏈接屬性都描述了標(biāo)識(shí)符的可見性,而存儲(chǔ)期則描述了這些標(biāo)識(shí)符對(duì)應(yīng)的對(duì)象的生存期。存儲(chǔ)期,也分下面幾種:

  • 靜態(tài)存儲(chǔ)期,程序執(zhí)行期間一直都在,文件作用域的變量具有靜態(tài)存儲(chǔ)期

  • 自動(dòng)存儲(chǔ)期,它(變長(zhǎng)數(shù)組除外)從塊開始,到塊末尾,因此,塊作用域的變量具有自動(dòng)存儲(chǔ)期,它在棧中存儲(chǔ),需要顯式初始化。

  • 動(dòng)態(tài)分配存儲(chǔ)期,即通過(guò)malloc分配內(nèi)存的變量。它在堆中存儲(chǔ),需要顯式初始。

  • 線程存儲(chǔ)期,從名字可以知道, 它與線程相關(guān),使用關(guān)鍵字_Thread_local聲明的變量具有線程存儲(chǔ)期,它從聲明到線程結(jié)束一直存在。

  • 關(guān)于初始化,可參考《C語(yǔ)言入坑指南-被遺忘的初始化》。

同樣地,我們通過(guò)下面的代碼來(lái)更好地理解存儲(chǔ)期

/**************************** 作者:守望先生 來(lái)源:公眾號(hào)編程珠璣 個(gè)人博客:https://www.yanbinghu.com ***************************************/ #include  int num1 = 222;         //靜態(tài)存儲(chǔ)期 static int num2 = 111;  //靜態(tài)存儲(chǔ)期 int add(int a,int b) {     static int tempSum = 0;  //靜態(tài)存儲(chǔ)期     tempSum = tempSum + a + b;     return tempSum; } int main(void) {     printf("num1=%d,num2=%d\n",num1,num2);     int sum = 0;  //自動(dòng)存儲(chǔ)期     sum = add(num1,num2);     printf("first time sum=%d\n",sum);//sum = 333     sum = add(num1,num2);     printf("second time sum=%d\n",sum); //sum = 666     return 0; }

另外,如果我們通過(guò)nm命令查看編譯出來(lái)的程序文件的符號(hào)表,我們可以找到num1,num2,tempSum,而沒(méi)有sum,前者所用的內(nèi)存數(shù)量在編譯時(shí)就確定了。

$ gcc -g -o lifetime lifetime.c  $ nm lifetime|grep num1 0000000000601038 D num1 $ nm lifetime|grep num2 000000000060103c d num2 $ nm lifetime|grep tempSum 0000000000601044 b tempSum.2289 $ nm lifetime|grep sum $

什么全局變量,局部變量,靜態(tài)局部變量,靜態(tài)全局變量

到這里,我們就可以很容易區(qū)分上面的變量類型了。實(shí)際上這里只是換了一種說(shuō)法:

全局:具有文件作用域的變量

靜態(tài):具有靜態(tài)存儲(chǔ)期或內(nèi)部鏈接屬性

局部:具有函數(shù)或塊作用域的變量

因而結(jié)合起來(lái),也就很好理解了。

  • 局部變量:函數(shù)或塊作用域的變量

  • 靜態(tài)局部變量:函數(shù)或塊作用域,靜態(tài)存儲(chǔ)期

  • 全局變量:具有文件作用域的變量

  • 靜態(tài)全局變量:內(nèi)部鏈接屬性的,具有文件作用域的變量

當(dāng)然,這僅僅是為了區(qū)分它們,這并不是它們的嚴(yán)格定義。更好的方法,是通過(guò)代碼來(lái)理解:

#include  int num1 = 222;         //全局變量 static int num2 = 111;  //靜態(tài)全局變量 int add(int a,int b) {     static int tempSum = 0;  //靜態(tài)局部變量     tempSum = tempSum + a + b;     return tempSum; } int main(void) {     printf("num1=%d,num2=%d\n",num1,num2);     int sum = 0;  //局部變量     sum = add(num1,num2);     printf("first time sum=%d\n",sum);//sum = 333     return 0; }

“怎么區(qū)分作用域,存儲(chǔ)器,鏈接屬性”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


分享標(biāo)題:怎么區(qū)分作用域,存儲(chǔ)器,鏈接屬性
文章轉(zhuǎn)載:http://fisionsoft.com.cn/article/pcjosd.html