C/C++中Static的作用

在c語言中

   1.先來介紹它的第一條也是最重要的一條:隱藏原則  這是被static所修飾的函數和變量共同遵循的原則

   當我們同時編譯多個文件時,所有未加static前綴的全局變量和函數都具有全局可見性。注意是未加static的全局的函數和全局的變量具有全局性即它們可以被其他.c文件訪問。爲理解這句話,我舉例來說明。我們要同時編譯兩個源文件,一個是test.c,另一個是main.c

    /* test.c */ 

    char t = 'T';  // 全局變量

    void hello()   

    { 

     printf("hello\n");

    }

    /* main.c 爲了說明問題就不再寫test.h 文件 啦*/

    int main(void)

    {

     extern char t; // 外部變量必須先聲明後使用 

     hello();       //  外部函數不需要

     printf("%c", t);

     ....

    }

程序的運行結果是:Hello T

你可能會問:爲什麼在test.c中定義的全局變量t和函數hello能在main.c中使用?前面說過,所有未加static前綴的全局變量和函數都具有全局可見性,其它的源文件也能訪問。此例中,t是全局變量,hello是函數,並且都沒有加static前綴,因此對於另外的源文件main.c是可見的。

如果加了static,就會對其它源文件隱藏。例如在t和hello的定義前加上static,main.c就看不到它們了。利用這一特性可以在不同的文件中定義同名函數和同名變量,而不必擔心命名衝突。

static可以用作函數和變量的前綴,對於函數來講,static的作用僅限於隱藏,而對於變量,static還有下面兩個作用

2.static的第二個作用是保持變量內容的持久

存儲在靜態數據區的變量會在程序剛開始運行時就完成初始化,也是唯一的一次初始化。共有兩種變量存儲在靜態存儲區:全局變量和static變量,只不過和全局變量比起來,static可以控制變量的可見範圍,說到底static還是用來隱藏的。對比全局變量和全局靜態變量尤其明顯,二者都存儲在靜態區初始化和持久性相同,唯一不同的是否可以被其他文件訪問;靜態局部變量由於本身就具備隱藏性所以static修飾的局部變量初始化和持久性顯得會明顯

int fun(void)
  {   static int c = 10; // 事實上此賦值語句從來沒有執行過(個人覺的這句話有點問題,應該是隻在第一次調用fun()函數的時候進行初始化。
      return c--;
  }
  int c = 1;
  void main()
  {
    printf("global\t\t local static \n");
    for(; c <= 10; ++c)
        printf(%d\t\t%d\n", c, fun());
  }

程序的運行結果是:global local static
                     1      10
                     2      9
                     3      8
                     4      7
                     5      6
                     6      5
                     7      4
                     8      3
                     9      2
                     10    1

3 static的第三個作用是默認初始化爲0 其實全局變量也具備這一屬性,因爲都存儲在靜態數據區

在靜態數據區,內存中所有的字節默認值都是0x00,某些時候這一特點可以減少程序員的工作量。比如初始化一個稀疏矩陣,我們可以一個一個地把所有元素都置0,然後把不是0的幾個元素賦值。如果定義成靜態的,就省去了一開始置0的操作;再比如要把一個字符數組當字符串來用,但又覺得每次在字符組末尾加‘\0’太麻煩。如果把字符串定義成靜態的,就省去了這個麻煩,因爲那裏本來就是‘\0’

 最後對static的三條作用做一句話總結。首先static的最主要功能是隱藏,其次因爲static變量存放在靜態存儲區,所以它具備持久性和默認值0

                                                                                在C++中

  除了具備C語言的以上三個原則外,位於C++ 類內的static原則: 被static修飾的類內的變量和函數是屬於類的而不是該類實例的

   在一個.cpp文件中可能會出現下面情況:

  /* IPCThreadState.h 在頭文件中聲明類IPCThreadState*/

  class IPCThreadState
  {
   public:
       static  IPCThreadState*     self(); // 方法聲明而且有static修飾

       int                 getCallingPid();

   ........

   ........

   }

  /* IPCThreadState.cpp 在該源文件中定義類IPCThreadState*/

  // 以下這些全局函數和變量沒有聲明在IPCThreadState.h中即不是類的成員函數和變量 所以他們遵循前邊C語言中的原則

  static const char* getReturnString(size_t idx);  // 聲明

   

     static const char* getReturnString(size_t idx)                                                 // 定義

    {

        ..........

    }


  static bool gHaveTLS = false;
  static bool gShutdown = false;
  static bool gDisableBackgroundScheduling = false;

// 是類的成員函數 且是static 所以該函數是屬於類IPCThreadState的 服務類的所有實例
IPCThreadState* IPCThreadState::self()   // 定義
{
   。。。
}

// 是類的成員函數 沒有static是普通類成員 該函數屬於類的某一個實例

int IPCThreadState::getCallingPid()
{
    return mCallingPid;
}

   總之, 在類中的static 的數據成員和成員函數 是屬於類的 這就是面向對象程序裏邊static的原則

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章