-
普通局部變量是再熟悉不過的變量了,在任何一個函數內部定義的變量(不加static修飾符)都屬於這個範疇。編譯器一般不對普通局部變量進行初始化,也就是說它的值在初始時是不確定的,除非對其顯式賦值。
-
普通局部變量存儲於進程棧空間,使用完畢會立即釋放。
-
靜態局部變量使用static修飾符定義,即使在聲明時未賦初值,編譯器也會把它初始化爲0。且靜態局部變量存儲於進程的全局數據區,即使函數返回,它的值也會保持不變。
-
static 關鍵字兩種基本用法
-
static修飾局部變量,成爲一個局部靜態變量
-
static修飾局部變量(靜態局部變量)與普通局部變量相比:
-
靜態局部變量作用域與連接屬性與普通局部變量一樣。
-
存儲類:靜態局部變量分配在data/bss段,普通局部變量在棧上。
-
生命週期:因爲存儲類的不同,靜態局部變量的生命週期得到延長了,直到程序結束,而普通的局部變量在函數體執行結束之後就直接回收銷燬了,每次執行都會重新分配內存。
-
所以當局部靜態變量離開作用域後,並沒有銷燬,而是仍然駐留在內存當中,只不過我們不能再對它進行訪問,直到該函數再次被調用,並且值不變。
-
示例代碼
#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修飾全局變量和函數 與 普通全局變量和普通函數相比
- 存儲類、生命週期、作用域都一樣。
- 差別在於static修飾全局變量\函數連接屬性是內連接(只能被本c文件使用),普通全局變量\普通函數是外鏈接(可以被出本c文件之外的其他c文件使用)。
- 就是說static修飾全局變量\函數不能跨文件訪問調用。
3.涉及到相關概念
1、什麼是存儲類
- 簡單的說也就是存儲類型,c中變量是在哪裏存放的?內存是怎麼管理的?
- 所以內存的管理:
- 棧:局部變量,函數調用傳參的過程。
- 堆:動態存儲區,需要程序員去申請釋放(malloc() new())。
- 數據段(data段):顯式初始化非零的全局變量(static修飾顯式初始化非0的局部變量)。
- bss段:顯式初始化爲0與未初始化的全局變量(static修飾顯式初始化爲0與未初始化的局部變量)。
- text段:代碼(函數)、只讀數據。
2、什麼是生命週期
- 描述變量什麼時候誕生,什麼時候消亡,從誕生到消亡就是這個變量的生命週期。
- 局部變量(棧),生命週期即是進入函數,從變量創建到函數返回時變量死亡。
- 全局變量(data/bss),生命週期是程序執行到程序結束
- 堆變量,生命週期是從我們malloc到free
3、什麼是作用域
- 描述變量的作用的代碼範圍。c的作用域規則是代碼塊作用域,即是一對花括號{}。
- 一般的從變量定義到{}結束,即是這個變量的作用域
- 全局變量與函數一般是文件作用域,即作用域是整個.c
4、什麼是鏈接屬性
- 編譯器將很多源文件編譯成很多.o文件後,每個.o文件裏有符號、代碼段、data/bss等等的分段,鏈接器需要通過符號將這些內存鏈接起來。而這些符號就是鏈接屬性。
- c中有三種鏈接屬性:外鏈接、內鏈接、無鏈接屬性。
- 外鏈接:外部鏈接,可以在整個程序(跨文件)鏈接。 普通的函數與全局變量。
- 內鏈接:內部連接,只能在當前.c文件進行鏈接。 static修飾的全局變量與函數。
- 無鏈接:沒有鏈接。 普通局部變量 。