在講變量之前,我們先來了解一下程序在內存中的分段
當程序開始運行後,會加載到內存中,會把內存分成若干個段(60),每一段的功能、權限不同。
代碼段(txt)
程序中的二進制指令在此段,只讀權限。
代碼段就是程序中的可執行部分,直觀理解代碼段就是函數堆疊組成的。、
只讀段(可以把它和代碼段合併看成一段)
存儲常量、字符串字面值。
數據段(也被稱爲數據區、靜態數據區、靜態區)
數據段就是程序中的數據,直觀理解就是C語言程序中的全局變量。(注意:全局變量纔算是程序的數據,局部變量不算程序的數據,只能算是函數的數據)
bss段(又叫ZI(zero initial)段)
bss段的特點就是被初始化爲0,bss段本質上也是屬於數據段,bss段就是被初始化爲0的數據段。
注意區分:數據段(.data)和bss段的區別和聯繫:二者本來沒有本質區別,都是用來存放C程序中的全局變量的。區別在於把顯示初始化爲非零的全局變量存在.data段中,而把顯式初始化爲0或者並未顯式初始化(C語言規定未顯式初始化的全局變量值默認爲0)的全局變量存在bss段。
全局段:存儲全局變量。
棧:局部變量,由操作系統管理,自動申請、釋放。
堆:由程序員收到管理。
明白了內存在程序中的分段,我們就可以開始瞭解變量了。
變量的屬性:
- 存儲位置:變量使用的那一段內存
- 作用域:變量的使用範圍
- 生命週期:創建時間~銷燬時間
變量的分類:
全局變量:定義在函數外。
-
存儲位置:未初始化存儲在bss、被初始化了存儲data
-
作用域:整個程序。比如在a.c定於全局變量,在b.c中也可以使用
-
生命週期:main函數執行前就被定義出,程序運行結束後再釋放
局部變量:定義在函數內。
-
存儲位置:棧
-
作用域:所在的函數內
-
生命週期:從定義語句開始~函數執行結束,函數沒調用一次就會進行一遍定義、釋放。
塊變量:定義在if、for、while等語句塊內。
-
存儲位置:棧
-
作用域:所在語句塊的大括號內
-
生命週期:從定義語句開始~函數執行結束。
修飾變量的關鍵字:
auto(自動變量)
-
用來定義自申請內存、自動釋放內存的變量(局部、塊變量)。
-
不加就代表加,與signed一樣。 凡未加存儲類型說明的變量均爲自動變量,自動變量可以省去auto。
注意:全局變量前不能使用。
int a,b,c;
等價於
auto a,b,c;
注意:
自動變量的作用域僅限於定義該變量的個體內。
const
-
是對變量提供一種保護,但它不是常量。
-
變量一旦初始化後,就不能再修改它的值。
-
const修飾被初始化過的全局變量纔是真正的常量,一旦修改就出現段錯誤,因爲編譯器把這種全局變量的存儲位置劃分給了text。
static
限制作用域(全局變量、函數),改變存儲位置、延長生命週期(局部、塊變量)
- 修飾變量:
-
全局變量:限制全局變量的作用域,只能在它所在的.c內使用
-
局部、塊變量:改變存儲位置,由棧改爲bss或data,但作用域沒有變,並且會延長生命週期。只執行初始化一次,並且會延長生命週期,直到程序運行結束以後才釋放。
#include <stdio.h>
void func(){
for(int i = 0;i < 5;i++){
static num = 0;//只初始化一次
num ++;
printf("%d",num);
}
}
int mian(){
func();
}
//輸出結果爲1,2,3,4,5;
-
修飾函數:
-
const int func(void); const修飾的是函數返回值。
-
static int func(void); static修飾的是函數。
由普通函數(外部函數)變量成內部函數,只能在.c文件內調用
register(寄存器變量)
各類變量都存放在存儲器捏,當對一個變量頻繁讀寫時,必然要反覆訪問存儲器,從而花費大量的存取時間。c提供了寄存器變量,這種變量存放在CPU的寄存器中,使用時不需要訪問內存,直接從寄存器中讀寫,可提高效率。
對於循環次數多的循環控制變量可定義爲寄存器變量。
#include <stdio.h>
int mian()
{
register i,s = 0;
for(i = 0;i <200 ;i++){
s = s + i;
printf("s=%d\n",s);
}
}
-
計算機的存儲介質:硬盤-》固態硬盤-》內存-》緩存-》寄存器。
-
申請把變量存儲的存儲位置改成寄存器,因爲寄存器不一定成功。
-
寄存器變量不能取地址,&變量名。
volatile
-
不穩定、易變的
-
如果一個變量的值沒有被顯示的修改,編譯器不會再起從內存中讀取他的值,而是直接使用上次的讀取結果(優化)。
-
volatile的功能就是告訴編譯器變量的值隨時可能發生變化,不要優化它的讀取過程(每次用到變量時都取內存中獲取它的值)。
int num = 10;
num == num;// 永遠爲真
volatile int num = 10;
num == num;// 也可能爲假
extern
聲明變量,多文件中共享全局變量時使用,誰使用誰聲明
定義:創建變量名,分配存儲空間。
聲明:創建變量名。
a.c中定義一個全局變量,b.c中如果想使用共享一個變量。