c語言中static 用法總結

來源:互聯網
上載者:User

一、c程式儲存空間布局

    C程式一直由下列部分組成:

    1)本文段——CPU執行的機器指令部分;一個程式只有一個副本;唯讀,防止程式由於意外事故而修改自身指令;

    2)初始化資料區段(資料區段)——在程式中所有賦了初值的全域變數,存放在這裡。

    3)非初始化資料區段(bss段)——在程式中沒有初始化的全域變數;核心將此段初始化為0.

    4)棧——增長方向:自頂向下增長;自動變數以及每次函數調用時所需要儲存的資訊(返回地址;環境資訊)。

    5)堆——動態儲存裝置分。

|-----------|
|                  |
|-----------|
|     棧          |
|-----------|
|     |             |
|    \|/            |
|                  |
|                  |
|    /|\            |
|     |             |
|-----------|
|     堆          |
|-----------|
| 未初始化   |
|-----------|
|    初始化   |
|-----------|
|   本文段    |
|-----------|

    二、 面向過程程式設計中的static

    1. 全域靜態變數

    在全域變數之前加上關鍵字static,全域變數就被定義成為一個全域靜態變數。

    1)記憶體中的位置:靜態儲存區(靜態儲存區在整個程式運行期間都存在)

    2)初始化:未經初始化的全域靜態變數會被程式自動初始化為0(自動對象的值是任意的,除非他被顯示初始化)

    3)範圍:全域靜態變數在聲明他的檔案之外是不可見的。準確地講從定義之處開始到檔案結尾。

    看下面關於範圍的程式:

//teststatic1.c
void display();
extern int n;
int main()
{
n = 20;
printf("%d\n",n);
display();
return 0;
}

//teststatic2.c
static int n; //定義全域靜態變數,自動初始化為0,僅在本檔案中可見
void display()
{
n++;
printf("%d\n",n);
}

    檔案分別編譯通過,但link的時候teststatic1.c中的變數n找不到定義,產生錯誤。

    定義全域靜態變數的好處:

    <1>不會被其他檔案所訪問,修改

    <2>其他檔案中可以使用相同名字的變數,不會發生衝突。

    2. 局部靜態變數

    在局部變數之前加上關鍵字static,局部變數就被定義成為一個局部靜態變數。

    1)記憶體中的位置:靜態儲存區

    2)初始化:未經初始化的全域靜態變數會被程式自動初始化為0(自動對象的值是任意的,除非他被顯示初始化)

    3)範圍:範圍仍為局部範圍,當定義它的函數或者語句塊結束的時候,範圍隨之結束。

    註:當static用來修飾局部變數的時候,它就改變了局部變數的儲存位置,從原來的棧中存放改為靜態儲存區。但是局部靜態變數在離開範圍之後,並沒有被銷毀,而是仍然駐留在記憶體當中,直到程式結束,只不過我們不能再對他進行訪問

    當static用來修飾全域變數的時候,它就改變了全域變數的範圍(在聲明他的檔案之外是不可見的),但是沒有改變它的存放位置,還是在靜態儲存區中

    3. 靜態函數

    在函數的傳回型別前加上關鍵字static,函數就被定義成為靜態函數。

    函數的定義和聲明預設情況下是extern的,但靜態函數只是在聲明他的檔案當中可見,不能被其他檔案所用。

    例如:

 //teststatic1.c
void display();
static void staticdis();
int main()
{
display();
staticdis();
renturn 0;
}

//teststatic2.c
void display()
{
staticdis();
printf("display() has been called \n");
}

static void staticdis()
{
printf("staticDis() has been called\n");
}

   檔案分別編譯通過,但是串連的時候找不到函數staticdis()的定義,產生錯誤。

    定義靜態函數的好處:

    <1> 其他檔案中可以定義相同名字的函數,不會發生衝突

    <2> 靜態函數不能被其他檔案所用。

    儲存說明符auto,register,extern,static,對應兩種儲存期:自動儲存期和靜態儲存期。

    auto和register對應自動儲存期。具有自動儲存期的變數在進入聲明該變數的程式塊時被建立,它在該程式塊活動時存在,退出該程式塊時撤銷。

    關鍵字extern和static用來說明具有靜態儲存期的變數和函數。用static聲明的局部變數具有靜態儲存持續期(static storage duration),或靜態範圍(static extent)。雖然他的值在函數調用之間保持有效,但是其名字的可視性仍限制在其局部域內。靜態局部對象在程式執行到該對象的聲明處時被首次初始化。

    由於static變數的以上特性,可實現一些特定功能。

    1. 統計次數功能

    聲明函數的一個局部變數,並設為static類型,作為一個計數器,這樣函數每次被調用的時候就可以進行計數。這是統計函數被調用次數的最好的辦法,因為這個變數是和函數息息相關的,而函數可能在多個不同的地方被調用,所以從調用者的角度來統計比較困難。代碼如下:

void count();
int main()
{
  int i;
  for (i = 1; i <= 3; i++)
   count();
  return 0;
}

void count()
{
  static num = 0;
  num++;
  printf(" I have been called %d",num,"times\n");
}

   輸出結果為:

    I have been called 1 times.

    I have been called 2 times.

    I have been called 3 times.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.