c語言中static關鍵字用法詳解

  • 普通局部變量是再熟悉不過的變量了,在任何一個函數內部定義的變量(不加static修飾符)都屬於這個範疇。編譯器一般不對普通局部變量進行初始化,也就是說它的值在初始時是不確定的,除非對其顯式賦值。

  • 普通局部變量存儲於進程棧空間,使用完畢會立即釋放。

  • 靜態局部變量使用static修飾符定義即使在聲明時未賦初值,編譯器也會把它初始化爲0且靜態局部變量存儲於進程的全局數據區,即使函數返回,它的值也會保持不變

  • static 關鍵字兩種基本用法

  1. static修飾局部變量,成爲一個局部靜態變量

  • static修飾局部變量(靜態局部變量)與普通局部變量相比:

  1. 靜態局部變量作用域與連接屬性與普通局部變量一樣。

  2. 存儲類:靜態局部變量分配在data/bss段普通局部變量在棧上

  3. 生命週期:因爲存儲類的不同,靜態局部變量的生命週期得到延長了,直到程序結束,而普通的局部變量在函數體執行結束之後就直接回收銷燬了,每次執行都會重新分配內存。

  • 所以當局部靜態變量離開作用域後,並沒有銷燬,而是仍然駐留在內存當中,只不過我們不能再對它進行訪問,直到該函數再次被調用,並且值不變。

  • 示例代碼

 

#include <stdio.h>

void test()
{
    int          num = 0;  //普通局部變量
    static int   s_num = 0; //靜態局部變量

    s_num ++;
    num ++;
    printf("num = %d   ", num);
    printf("s_num = %d\n", s_num);

}

int main(int argc, char *argv[])
{
    int          i = 0;

    for (i = 0; i < 10; ++i)
    {
        test();

    }



    return 0;
}
  •   程序運行結果:

 

  2.static修飾全局變量與函數,成爲靜態全局變量與靜態函數

  • static修飾全局變量和函數 與 普通全局變量和普通函數相比
  1. 存儲類、生命週期、作用域都一樣。
  2. 差別在於static修飾全局變量\函數連接屬性是內連接(只能被本c文件使用),普通全局變量\普通函數是外鏈接(可以被出本c文件之外的其他c文件使用)。
  3. 就是說static修飾全局變量\函數不能跨文件訪問調用。

3.涉及到相關概念

 

  1、什麼是存儲類

  • 簡單的說也就是存儲類型,c中變量是在哪裏存放的?內存是怎麼管理的?
  • 所以內存的管理:
  1. 棧:局部變量,函數調用傳參的過程。
  2. 堆:動態存儲區,需要程序員去申請釋放(malloc() new())。
  3. 數據段(data段):顯式初始化非零的全局變量(static修飾顯式初始化非0的局部變量)。
  4. bss段:顯式初始化爲0與未初始化的全局變量(static修飾顯式初始化爲0與未初始化的局部變量)。
  5. text段:代碼(函數)、只讀數據。

 

2、什麼是生命週期

  • 描述變量什麼時候誕生,什麼時候消亡,從誕生到消亡就是這個變量的生命週期。
  1. 局部變量(棧),生命週期即是進入函數,從變量創建到函數返回時變量死亡。
  2. 全局變量(data/bss),生命週期是程序執行到程序結束
  3. 堆變量,生命週期是從我們malloc到free

 

3、什麼是作用域

  • 描述變量的作用的代碼範圍。c的作用域規則是代碼塊作用域,即是一對花括號{}。
  1. 一般的從變量定義到{}結束,即是這個變量的作用域
  2. 全局變量與函數一般是文件作用域,即作用域是整個.c

4、什麼是鏈接屬性

  • 編譯器將很多源文件編譯成很多.o文件後,每個.o文件裏有符號、代碼段、data/bss等等的分段,鏈接器需要通過符號將這些內存鏈接起來。而這些符號就是鏈接屬性。
  • c中有三種鏈接屬性:外鏈接、內鏈接、無鏈接屬性。
  • 外鏈接:外部鏈接,可以在整個程序(跨文件)鏈接。​​​​​​​ 普通的函數與全局變量。
  • 內鏈接:內部連接,只能在當前.c文件進行鏈接。     static修飾的全局變量與函數。
  • 無鏈接:沒有鏈接。                                                        ​​​​​​​普通局部變量 。

 

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