青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

春暖花開
雪化了,花開了,春天來了
posts - 149,comments - 125,trackbacks - 0

今日從網上看到一篇好文章,匯總匯總,又拼湊拼湊,便有了下文。
 

static關鍵字是CC++中都存在的關鍵字, 它主要有三種使用方式, 其中前兩種只指在C語言中使用, 第三種在C++中使用(C,C++中具體細微操作不盡相同,   本文以C++為準).  

(1) 局部靜態(tài)變量 靜態(tài)局部變量有兩個用法,記憶功能和全局生存期.

(2) 外部靜態(tài)變量/函數 用于全局變量,主要作用是限制此全局變量被其他的文件調用

(3) 靜態(tài)數據成員/成員函數 表示這個成員是屬于這個類但是不屬于類中任意特定對象

 

下面就這三種使用方式及注意事項分別說明

 一、局部靜態(tài)變量  
 
C/C++, 局部變量按照存儲形式可分為三種auto, static, register  

 auto類型(普通)局部變量相比, static局部變量有三點不同

  1.   存儲空間分配不同 

  auto類型分配在棧上, 屬于動態(tài)存儲類別, 占動態(tài)存儲區(qū)空間, 函數調用結束后自動釋放, static分配在靜態(tài)存儲區(qū), 在程序整個運行期間都不釋放. 兩者之間的作用域相同, 但生存期不同.  

  2.   static局部變量在所處模塊在初次運行時進行初始化工作, 且只操作一次 

  3.   對于局部靜態(tài)變量, 如果不賦初值, 編譯期會自動賦初值0或空字符, auto類型的初值是不確定的.(對于C++中的class對象例外, class的對象實例如果不初始化, 則會自動調用默認構造函數, 不管是否是static類型)  

 特點: static局部變量的記憶性與生存期的全局性”  

 所謂“記憶性是指在兩次函數調用時, 在第二次調用進入時, 能保持第一次調用退出時的值.    

 示例程序一 

  #include   <iostream>  

  using   namespace   std;  

  void   staticLocalVar()  

  {  

static  int a  = 0; // 運行期時初始化一次,下次再調用時,不進行初始化工作 

cout<<"a="<<a<<endl;  

++a;  

}  

int   main()  

{  

    staticLocalVar();   //  第一次調用,   輸出a=0  

    staticLocalVar();   // 第二次調用,   記憶了第一次退出時的值,   輸出a=1  

    return   0;  

}  

 應用:  利用“記憶性”,   記錄函數調用的次數(示例程序一)

       

利用生存期的“全局性,改善

return a   pointer   /   reference   to   a   local   object”的問題. Local object的問題在于退出函數, 生存期即結束,利用static的作用, 延長變量的生存期.  

 示例程序二:  

  //   IP   address   to   string   format  

  //   Used   in   Ethernet   Frame   and   IP   Header   analysis  

  const   char   *   IpToStr(UINT32   IpAddr)  

  {  

    static   char   strBuff[16];   //   static局部變量,   用于返回地址有效

    const  unsigned   char  *pChIP   =  (const   unsigned   char   *)&IpAddr;

   sprintf(strBuff, "%u.%u.%u.%u", pChIP[0], pChIP[1],  pChIP[2], pChIP[3]);  

    return   strBuff;  

  }  

 注意事項:  

  1. “記憶性”,  程序運行很重要的一點就是可重復性, static變量的記憶性破壞了這種可重復性,   造成不同時刻至運行的結果可能不同.  

  2.  “生存期全局性和唯一性. 普通的local變量的存儲空間分配在stack,  因此每次調用函數時,  分配的空間都可能不一樣, static具有全局唯一性的特點, 每次調用時, 都指向同一塊內存, 這就造成一個很重要的問題   ----   不可重入性!!!  

 

 這樣在多線程程序設計或遞歸程序設計中,  要特別注意這個問題.

 下面針對示例程序二,   分析在多線程情況下的不安全性.(為方便描述,   標上行號

const   char   *   IpToStr(UINT32   IpAddr)  

  {  

  static   char   strBuff[16];   //   static局部變量,   用于返回地址有效

    const  unsigned   char  *pChIP   =  (const   unsigned   char   *)&IpAddr;

   sprintf(strBuff, "%u.%u.%u.%u", pChIP[0], pChIP[1],  pChIP[2], pChIP[3]);  

    return   strBuff;  

  }  

 

   假設現在有兩個線程A,B運行期間都需要調用IpToStr()函數, 32位的IP地址轉換成點分10進制的字符串形式.  

A先獲得執(zhí)行機會, 執(zhí)行IpToStr(), 傳入的參數是0x0B090A0A, 順序執(zhí)行完應該返回的指針存儲區(qū)內容是: “10.10.9.11”, 現執(zhí)行到⑥時, 失去執(zhí)行權, 調度到B線程執(zhí)行, B線程傳入的參數是0xA8A8A8C0,執(zhí)行至⑦, 靜態(tài)存儲區(qū)的內容是192.168.168.168. 當再調度到A執(zhí)行時, 從⑥繼續(xù)執(zhí)行, 由于strBuff的全局唯一性, 內容已經被B線程沖掉, 此時返回的將是192.168.168.168字符串, 不再是10.10.9.11字符串.  

補充:靜態(tài)局部變量屬于靜態(tài)存儲方式,它具有以下特點:
(1)
靜態(tài)局部變量在函數內定義    它的生存期為整個源程序,但是其作用域仍與自動變量相同,只能在定義該變量的函數內使用該變量。退出該函數后,盡管該變量還繼續(xù)存在,但不能使用它。

(2)允許對構造類靜態(tài)局部量賦初值    例如數組,若未賦以初值,則由系統自動賦以0值。
(3)
對基本類型的靜態(tài)局部變量若在說明時未賦以初值,則系統自動賦予0值。而對自動變量不賦初值,則其值是不定的。根據靜態(tài)局部變量的特點, 可以看出它是一種生存期為整個源程序的量。雖然離開定義它的函數后不能使用,但如再次調用定義它的函數時,它又可繼續(xù)使用, 而且保存了前次被調用后留下的值。因此,當多次調用一個函數且要求在調用之間保留某些變量的值時,可考慮采用靜態(tài)局部變量。雖然用全局變量也可以達到上述目的,但全局變量有時會造成意外的副作用,因此仍以采用局部靜態(tài)變量為宜

 

  二、外部靜態(tài)變量/函數 

   Cstatic有了第二種含義:用來表示不能被其它文件訪問的全局變量和函數。 但為了限制全局變量/函數的作用域,  函數或變量前加static使得函數成為靜態(tài)函數。但此處“static”的含義不是指存儲方式,而是指對函數的作用域僅局限于本文件(所以又稱內部函數)。注意此時, 對于外部(全局)變量, 不論是否有static限制, 它的存儲區(qū)域都是在靜態(tài)存儲區(qū), 生存期都是全局的. 此時的static只是起作用域限制作用, 限定作用域在本模塊(文件)內部.  

 使用內部函數的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它文件中的函數同名。

 示例程序三:  

  //file1.cpp  

  static   int   varA;  

  int   varB;  

  extern   void   funA()  

  {  

  ……  

  }  

  static   void   funB()  

  {  

  ……  

  }

 

  //file2.cpp  

  extern   int   varB;   //   使用file1.cpp中定義的全局變量 

  extern   int   varA;   //   錯誤! varAstatic類型,  無法在其他文件中使用 

  extern   vod   funA(); //   使用file1.cpp中定義的函數 

  extern   void   funB(); //   錯誤! 無法使用file1.cpp文件中static函數 

 

補充:全局變量(外部變量)的說明之前再冠以static 就構成了靜態(tài)的全局變量。全局變量本身就是靜態(tài)存儲方式, 靜態(tài)全局變量當然也是靜態(tài)存儲方式。 這兩者在存儲方式上并無不同。這兩者的區(qū)別雖在于非靜態(tài)全局變量的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態(tài)的全局變量在各個源文件中都是有效的。 而靜態(tài)全局變量則限制了其作用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。由于靜態(tài)全局變量的作用域局限于一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。從以上分析可以看出, 把局部變量改變?yōu)殪o態(tài)變量后是改變了它的存儲方式即改變了它的生存期。把全局變量改變?yōu)殪o態(tài)變量后是改變了它的作用域,限制了它的使用范圍。因此static 這個說明符在不同的地方所起的作用是不同的。

 

  三、靜態(tài)數據成員/成員函數(C++特有)  

  C++重用了這個關鍵字,并賦予它與前面不同的第三種含義:表示屬于一個類而不是屬于此類的任何特定對象的變量和函數. 這是與普通成員函數的最大區(qū)別, 也是其應用所在, 比如在對某一個類的對象進行計數時,計數生成多少個類的實例, 就可以用到靜態(tài)數據成員. 在這里面, static既不是限定作用域的, 也不是擴展生存期的作用, 指示變量/函數在此類中的唯一性. 這也是屬于一個類而不是屬于此類的任何特定對象的變量和函數的含義.  因為它是對整個類來說是唯一的, 因此不可能屬于某一個實例對象的. (針對靜態(tài)數據成員而言, 成員函數不管是否是static,在內存中只有一個副本.普通成員函數調用時, 需要傳入this指針,static成員函數調用時, 沒有this指針.   )  

 請看示例程序四

  class   EnemyTarget   {  

  public:  

      EnemyTarget()   {   ++numTargets;   }  

      EnemyTarget(const   EnemyTarget&)   {   ++numTargets;   }  

      ~EnemyTarget()   {   --numTargets;   }  
      static   size_t   numberOfTargets()   {   return   numTargets;   }  

      bool  destroy(); //   returns  success  of  attempt  to  destroy  

// EnemyTarget   object  

      private:  

      static   size_t   numTargets;   //   object   counter  

  };  

  //   class   statics   must   be   defined   outside   the   class;  

  //   initialization   is   to   0   by   default  

  size_t   EnemyTarget::numTargets;  

 在這個例子中,   靜態(tài)數據成員numTargets就是用來計數產生的對象個數的.  

在《c++ 程序設計語言》中,是這樣運用的:
 

Static靜態(tài)成員,它是類的一部分,但卻不是該類的各個對象的一部分。一個static成員只有唯一的一份副本,但不像常規(guī)的非static成員那樣在每個對象里各有一份副本。 與此類似,一個需要訪問類成員,然而卻并不需要針對特定對象去調用的函數,也被稱為一個static成員函數。其好處在于消除了由于依賴全局量而引起的問題

Class Date

{

   Int d, m, y;

   Static Date default_date;

   Public:

      Date(int dd=0, int mm=0, int yy=0);

      //……

      Static void set_default(int, int, int);

};

靜態(tài)成員可以像任何其他成員一樣引用,此外,對于靜態(tài)成員的引用不必提到任何對象,相反,在這里應該成員的名字加上作為限定詞的類的名字。

Void f()

{

 Date::set_default(4, 5, 1945);

}

靜態(tài)成員(包括函數和數據成員)都必須在某個地方另行定義。如

Date Date:::default_date(16, 12, 1770);

Void Date::set_default(int d, int m, int y)

{

 Date::default_date = Date(d, m, y);

}

 

補充:內部函數和外部函數

當一個源程序由多個源文件組成時,C語言根據函數能否被其它源文件中的函數調用,將函數分為內部函數和外部函數。
1
內部函數(又稱靜態(tài)函數)
如果在一個源文件中定義的函數,只能被本文件中的函數調用,而不能被同一程序其它文件中的函數調用,這種函數稱為內部函數。
定義一個內部函數,只需在函數類型前再加一個“static”關鍵字即可,如下所示:
static   
函數類型    函數名(函數參數表)
{……}
關鍵字“static”,譯成中文就是靜態(tài)的,所以內部函數又稱靜態(tài)函數。但此處“static”的含義不是指存儲方式,而是指對函數的作用域僅局限于本文件。
使用內部函數的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它文件中的函數同名,因為同名也沒有關系。

2 外部函數
外部函數的定義:在定義函數時,如果沒有加關鍵字“static”,或冠以關鍵字“extern”,表示此函數是外部函數:
[extern]   
函數類型    函數名(函數參數表)
{……}
調用外部函數時,需要對其進行說明:
[extern]   
函數類型    函數名(參數類型表)[,函數名2(參數類型表2)……]

 

posted on 2008-10-11 10:40 Sandy 閱讀(436) 評論(1)  編輯 收藏 引用

FeedBack:
# re: static 用法總結
2008-10-11 10:45 | gggggggggggggg
nice  回復  更多評論
  

只有注冊用戶登錄后才能發(fā)表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美另类在线观看| 国产一区二区三区免费不卡| 亚洲精品国产精品乱码不99| 妖精视频成人观看www| 亚洲国产综合在线| 影音先锋另类| 亚洲国产精品va在看黑人| 在线观看亚洲一区| 亚洲激情一区| 中国女人久久久| 香蕉久久夜色精品国产| 久久久夜夜夜| 欧美www在线| 亚洲精品久久久久久一区二区| 99视频日韩| 欧美一级播放| 欧美成人国产一区二区| 欧美人与禽猛交乱配| 国产精品爱久久久久久久| 国产啪精品视频| 久久精品人人做人人爽| 在线精品国产欧美| 一本久久综合亚洲鲁鲁| 性欧美大战久久久久久久免费观看| 久久经典综合| 亚洲国产精品激情在线观看| 亚洲在线视频观看| 久久精品亚洲一区| 亚洲精品1区2区| 久久成年人视频| 欧美日韩不卡视频| 在线观看欧美| 欧美一区深夜视频| 亚洲区第一页| 久久久久久久97| 国产精品专区h在线观看| 日韩亚洲一区二区| 免费不卡在线视频| 亚洲免费在线| 欧美午夜激情在线| 亚洲精品一区二区网址| 玖玖玖国产精品| 午夜久久久久久| 欧美性猛交一区二区三区精品| 亚洲黄色一区二区三区| 欧美在线观看视频| 日韩视频中文字幕| 老司机成人网| 国产一区二区无遮挡| 亚洲一区二区三区在线播放| 亚洲国产高清自拍| 久久久久久久999精品视频| 国产精品一区二区三区四区| 亚洲一区三区视频在线观看| 亚洲承认在线| 久久免费高清| 激情久久久久久久| 久久精品在线| 欧美一站二站| 韩国福利一区| 麻豆精品91| 久久中文久久字幕| 精品999日本| 免费日韩av片| 欧美www在线| 91久久久久| 欧美激情成人在线视频| 久热精品视频在线| 亚洲丰满少妇videoshd| 欧美高清不卡在线| 欧美成年人网| 亚洲天堂免费观看| 亚洲欧美精品伊人久久| 国产日韩欧美自拍| 久久亚洲免费| 免费在线看一区| 一本色道久久综合亚洲二区三区| 亚洲图片激情小说| 亚洲一区二区三区精品动漫| 日韩视频免费看| 亚洲国产美女久久久久| 欧美成人性网| 中文无字幕一区二区三区| 99视频有精品| 欧美日韩亚洲一区三区| 亚洲一区国产| 欧美一区二区三区另类| 在线观看视频一区二区| 亚洲激情国产精品| 欧美三级乱码| 久久精品人人做人人爽| 老牛国产精品一区的观看方式| av不卡在线观看| 亚洲欧美日韩成人| 亚洲二区在线观看| 在线午夜精品| 一区免费观看| aa亚洲婷婷| 揄拍成人国产精品视频| 日韩一级精品视频在线观看| 国产一区亚洲| 99视频有精品| 亚洲精选在线| 久久成人国产精品| 亚洲欧美成人一区二区在线电影| 老司机成人网| 久久精品视频在线观看| 国产精品成人一区二区| 亚洲国产福利在线| 伊人男人综合视频网| 亚洲伊人久久综合| 在线一区亚洲| 欧美不卡激情三级在线观看| 久久久久久黄| 国产视频在线观看一区| 国产精品99久久久久久久vr| 亚洲美女av网站| 久久夜色精品国产欧美乱| 久久精品一区二区国产| 国产嫩草一区二区三区在线观看| 亚洲精品永久免费| aⅴ色国产欧美| 欧美国产亚洲精品久久久8v| 久久综合九色综合欧美就去吻 | 久久www免费人成看片高清 | 欧美日韩免费在线观看| 久久久久一本一区二区青青蜜月| 麻豆精品精华液| 亚洲欧美国产高清va在线播| 亚洲第一中文字幕在线观看| 国内久久精品视频| 一区二区三区日韩| 91久久精品国产91久久| 欧美一级大片在线免费观看| 在线观看日韩国产| 久久久久久久高潮| 欧美一区二区视频观看视频| 欧美经典一区二区| 免费一区视频| 狠狠久久婷婷| 香蕉久久精品日日躁夜夜躁| 久久国产天堂福利天堂| 国内一区二区三区在线视频| 老牛嫩草一区二区三区日本| 久久国产精品99精品国产| 快射av在线播放一区| 午夜精品网站| 久久一日本道色综合久久| av成人免费| 男女精品视频| 国产精品视频免费| 国产美女一区| 国产日韩在线亚洲字幕中文| 国产人久久人人人人爽| 极品尤物一区二区三区| 亚洲精品久久| 欧美高清视频在线| 99精品国产在热久久下载| 久久激情视频免费观看| 国产精品欧美久久| 亚洲欧美亚洲| 日韩亚洲一区二区| 欧美日韩亚洲高清| 日韩午夜精品视频| 毛片基地黄久久久久久天堂| 亚洲午夜精品福利| 国产精品免费一区豆花| 亚洲一级二级| 一区二区三区鲁丝不卡| 欧美精品一区二区三区久久久竹菊| 亚洲福利国产| 亚洲国产精品一区| 久久中文精品| 亚洲精品一区二区三区av| 中日韩男男gay无套 | 久久综合福利| 欧美日韩不卡一区| 亚洲午夜激情网页| 免费亚洲网站| 亚洲欧美在线另类| 日韩午夜高潮| 亚洲美女免费视频| 国产手机视频一区二区| 亚洲国产精品一区二区第一页| 翔田千里一区二区| 国产亚洲精品高潮| 欧美国产日本高清在线| 国产精品永久在线| 一区二区三区|亚洲午夜| 久久av免费一区| 亚洲欧美日本视频在线观看| 欧美激情亚洲精品| 午夜欧美精品久久久久久久| 老司机精品福利视频| 久久久蜜桃一区二区人| 国产一区二区三区黄| 亚洲视频免费| 亚洲欧美日韩中文播放| 欧美激情在线狂野欧美精品| 免费在线亚洲欧美|