莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          C語言的5種存儲類以及關鍵字volatile、restrict

          Posted on 2007-08-04 15:34 dennis 閱讀(9485) 評論(1)  編輯  收藏 所屬分類: linux & C
              《C Primer Plus》讀到12章,我的C語言復習進展的挺不錯。這一章介紹存儲類、連接和內存管理,可以說是重中之重。
          C的5種存儲類:
          自動——在一個代碼塊內(或在一個函數頭部作為參量)聲明的變量,無論有沒有存儲類修飾符auton,都屬于自動存儲類。該類具有自動存儲時期、代碼塊的作用域和空鏈接(no linkage),如未初始化,它的值是不確定的(java要求局部變量必須初始化)

          寄存器——在一個代碼塊內(或在一個函數頭部作為參量)使用修飾符register聲明的變量屬于寄存器存儲類。該類與自動存儲類相似,具有自動存儲時期、代碼塊作用域和空連接,聲明為register僅僅是一個請求,而非命令,因此變量仍然可能是普通的自動變量,但是仍然無法獲取地址。。如果沒有被初始化,它的值也是未定的。

          靜態、空鏈接——在一個代碼塊內使用存儲類修飾符static聲明的局部變量屬于靜態空連接存儲類。該類具有靜態存儲時期、代碼塊作用域和空鏈接,僅在編譯時初始化一次。如未明確初始化,它的字節將被設定為0.

          靜態、外部鏈接——在所有函數外部定義、未使用static修飾的變量屬于靜態、外部鏈接存儲類。改類具有靜態存儲時期、文件作用域和外部鏈接,僅在編譯時初始化一次。如未明確初始化,它的字節也被設定為0.

          靜態、內部鏈接——與靜態、外部鏈接存儲類不同的是,它使用static聲明,也定義在所有函數外部,但是具有內部鏈接(僅能被與它在同一個文件的函數使用),僅在編譯時初始化一次。如未明確初始化,它的字節也被設定為0.

          兩個關鍵字:volatile和restrict,兩者都是為了方便編譯器的優化。

          volatile告訴編譯器該被變量除了可被程序修改意外還可能被其他代理修改,因此,當要求使用volatile 聲明的變量的值的時候,系統總是重新從它所在的內存讀取數據,而不是使用寄存器中的緩存。比如
          val1=x;
          val2=x;
          如果沒有聲明volatile,系統在給val2賦值的時候可能直接從寄存器讀取x(假定聰明的編譯器優化了),而不是從內存的初始位置,那么在兩次賦值之間,x完全有可能被被某些編譯器未知的因素更改(比如:操作系統、硬件或者其它線程等)。如果聲明為volatile,編譯器將不使用緩存,而是每次都從內存重新讀取x。

          而restrict是c99引入的,它只可以用于限定指針,并表明指針是訪問一個數據對象的唯一且初始的方式,考慮下面的例子:
          int ar[10];
          int * restrict restar=(int *)malloc(10*sizeof(int));
          int *par=ar;

          這里說明restar是訪問由malloc()分配的內存的唯一且初始的方式。par就不是了。
          那么:
          for(n=0;n<10;n++)
          {
             par[n]+=5;
             restar[n]+=5;
             ar[n]*=2;
             par[n]+=3;
             restar[n]+=3;
          }
          因為restar是訪問分配的內存的唯一且初始的方式,那么編譯器可以將上述對restar的操作進行優化:
             restar[n]+=8;

          而par并不是訪問數組ar的唯一方式,因此并不能進行下面的優化:
             par[n]+=8;
          因為在par[n]+=3前,ar[n]*=2進行了改變。使用了關鍵字restric,編譯器就可以放心地進行優化了。這個關鍵字據說來源于古老的FORTRAN。有興趣的看看這個


          評論

          # re: C語言的5種存儲類以及關鍵字volatile、restrict[未登錄]  回復  更多評論   

          2008-03-15 01:19 by kevin
          寫的 不錯,上面的也都舉例就好了..
          主站蜘蛛池模板: 丰原市| 东乡县| 灵山县| 金门县| 新蔡县| 正宁县| 焦作市| 浦北县| 永德县| 乌拉特中旗| 甘孜| 太仆寺旗| 内黄县| 谢通门县| 乌什县| 冀州市| 垣曲县| 桐庐县| 阜新市| 贞丰县| 广汉市| 商水县| 邹平县| 阿荣旗| 禹州市| 扎囊县| 南召县| 卓资县| 万年县| 北辰区| 阳朔县| 永济市| 江陵县| 连州市| 昌江| 论坛| 鸡东县| 怀化市| 阳山县| 阳信县| 上思县|