變量類型,變量做用域,變量存儲空間,變量生命週期

變量類型編程

常量是不可變的值,能夠用宏來定義,好比 #define PI 3.14windows

變量的值是能夠變化的,因爲編程的不一樣需求,對變量有各類要求,數組

  好比:變量的生命週期,變量的初始狀態,變量的有效區域(做用域),變量的存儲地和存儲區域的大小。安全

爲了知足這些不一樣的編程需求,C語言發明者設置瞭如下變量:多線程

  1 不一樣數據類型的變量。好比 char,int,float等。(變量在內存中佔用地址大小由數據類型決定)架構

  2 全局變量函數

  3 局部變量spa

  4 靜態變量:包括靜態全局變量和靜態局部變量線程

  5 寄存器變量3d

  6 外部變量 

C語言中,除了基本類型外,開發者能夠經過typedef來定義本身須要的數據類型。好比:

  typedef int INT;

  typedef unsigned int UINT;

  typedef struct student

  {

    char *name;

    int age;

  }STUDENT;  

  若是結構體student不用typedef重定義的話,定義結構體變量時:struct student stu1;  

  使用typedef重定義之後,咱們只須要STUDENT stu1;便可。

 

  1 全局變量。在函數外定義,可被全部函數使用。可是在多線程訪問時,須要注意多線程安全問題。

  2 局部變量。在函數內部聲明。只有在函數執行時,局部變量才存在,函數執行完局部變量就消失。

  3 靜態變量。分配在內存中的數據段中,在C程序運行的整個過程當中一直保留,靜態變量能夠定義成靜態全局變量和靜態局部變量。

    ①靜態全局變量在程序的整個運行期間都存儲且內存地址不會改變。

    ②靜態局部變量只在聲明它的函數內有效,且在下一次調用時還保留上次調用結束時的值(只初始化一次)。

  4 寄存器變量。 寄存器變量存放在CPU的寄存器中,使用寄存器變量比內存變量操做速度快得多。

    只有整型和字符型變量能夠定義爲寄存器變量。好比:

    register int i;

    register char c;

    ①因爲CPU中寄存器有限,儘可能減小使用寄存器的數量和佔用時間,用完立刻釋放。

    ②寄存器變量不能定義爲全局變量,也不能定義在結構體和類中。

    ③若是寄存器已經無可用資源,寄存器變量將轉化爲普通局部變量。

 

extern:

  在大型程序中,會將一個大型的程序分紅多個獨立的模塊和文件分別編譯,而後統一連接在一塊兒。爲了解決全局變量和函數的共用問題,

引入了extern關鍵字。只須要在一個文件中定義全局變量和函數,在另外一個文件中要用到這些變量和函數時,只須要將那個文件中的變量和

函數說明覆制過來,而後在前面加上extern就能夠。這樣就等於告訴編譯器,這些變量和函數已經在別的文件中定義。

變量的存儲空間

  代碼和數據,都要加載到內存中,才能被運行和訪問。X86系統中,內存的有效範圍爲4GB。

  ①高2GB內存地址爲內核空間,用來存放內核的代碼和數據

  ②低2GB爲用戶空間,運行進程的用戶態代碼,且低2GB的內存是進程私有空間,一個進程不能跨進程訪問別的進程空間的用戶態地址。

如圖所示,程序在內存中分爲以下幾部分:

1 .text 代碼段,這段是存放代碼的

2 .rdata 只讀數據段,不能修改,存放常量,字符常量,const常量。

3 .data 數據段 存放已經初始化好的全局變量和靜態變量

4  .bss 存放未初始化的全局變量和靜態變量

  PS:.rdata,.data,.bss都是存放數據的段。.rdata段和.data段的值都在編譯的時候就肯定了,而且將值編譯進了

  可執行文件,通過反彙編就能夠找到。已初始化的全局變量放在.data段,未初始化的變量放在bss段。

5 .stack 棧段,棧中存放普通的局部變量(非靜態局部變量),形參,返回地址等。棧的大小有限制:

  windows應用層棧大小默認爲1MB;普通內核棧的大小是固定的,由系統根據CPU架構決定,X86系統上12KB,X64系統24KB,安騰系統32KB

  Linux應用層棧大小默認爲10MB,內核棧大小4KB或8KB

6 堆: 能夠存聽任意數據

綜上:

①全局初始化變量存放在靜態存儲區的.data段

②全局未初始化變量存放在靜態存儲區的.bss段

③局部變量存放在棧

④全局靜態變量和局部靜態變量存放在靜態存儲區的.data段和.bss段

⑤常量存放在靜態區的.rdata段。.rdata區域是隻讀內存,不能修改

⑥寄存器變量存放在寄存器中 (若是寄存器資源不夠,仍是放在內存中)

 

變量的做用域

變量的做用域指變量能在代碼什麼地方能夠被訪問到。

1 全局變量: 全部程序中的代碼都能訪問。

  若是全局變量在一個源文件中定義,在另外一個源文件中訪問,須要用extern關鍵字導入。多線程訪問全局變量注意安全問題

2 靜態全局變量: 在同一個源文件中能夠訪問,不一樣源文件不可訪問,也不能用extern來導入。

3 局部變量:只能在函數內部訪問

4 靜態局部變量:只能函數內部訪問

5 寄存器變量:只能在函數內部訪問

變量的生命週期

變量的生命週期是指變量在程序運行期間的有效時間

1 全局變量:整個程序運行期間有效

2 靜態全局變量:整個程序運行期間有效

3 局部變量:函數範圍內或代碼塊範圍內有效

4 靜態局部變量:整個程序運行期間有效

5 寄存器變量:函數範圍內或代碼塊範圍內有效

  

習題:分析下列程序中每一個變量的存儲位置,做用域,與生命週期 
int a = 0; 
char *p1; 
static int x = 10; 
void main(void) 

    int b = 0; 
    char s[] = "123"; 
    char *p2; 
    char *p3 = "hello, world"; 
    static int c =0; 
    p1 = (char *)malloc(128); 
    p2 = (char *)malloc(256); 
    free(p1); 
    free(p2); 


分析與解答:下面給出了上面各變量的類型,存儲,做用域和生命週期的詳細的概括:
int a = 0; //全局初始化變量 
char *p1; //全局未初始化變量 
static int x = 10;//全局初始化靜態變量 
void main(void) 

    int b = 0; //局部變量 
    char s[] = "123"; //s局部變量,字符數組,用"123"字符串常量進行初始化 
    char *p2; //局部變量 
    char *p3 = "hello, world"; //p3局部變量,字符指針,指向"hello, world"字符串常量 
    static int c =0; //靜態局部變量,已初始化 
    p1 = (char *)malloc(128); //p1,p2指向堆 
    p2 = (char *)malloc(256); 
    free(p1); //顯示釋放p1,p2指向的堆內存 
    free(p2); 

相關文章
相關標籤/搜索