基本概念: 作用域:起作用的區域,也就是可以工作的范圍。
代碼塊:所謂代碼塊,就是用{}括起來的一段代碼。
數據段:數據段存的是數,像全局變量就是存在數據段的
代碼段:存的是程序代碼,一般是只讀的。
棧(stack):先進后出。C語言中局部變量就分配在棧中。
局部變量
普通的局部變量定義的時候直接定義或者在前面加上auto
void func1(void)
{
int i = 1;
i++;
printf("i = %d.\n", i);
}
局部變量i的解析:
在連續三次調用func1中,每次調用時,在進入函數func1后都會創造一個新的變量i,
並且給它賦初值1,然后i++時加到2,
然后printf輸出時輸出2.然后func1本次調用結束,
結束時同時殺死本次創造的這個i。這就是局部變量i的整個生命周期。
下次再調用該函數func1時,又會重新創造一個i,經歷整個程序運算,
最終在函數運行完退出時再次被殺死。
靜態局部變量(static) 靜態局部變量定義時前面加static關鍵字。
總結:
1、靜態局部變量和普通局部變量不同。靜態局部變量也是定義在函數內部的,靜態局部變量定義時前面要加static關鍵字來標識,靜態局部變量所在的函數在多調用多次時,只有第一次才經歷變量定義和初始化,以后多次在調用時不再定義和初始化,而是維持之前上一次調用時執行后這個變量的值。本次接着來使用。
2、靜態局部變量在第一次函數被調用時創造並初始化,但在函數退出時它不死亡,而是保持其值等待函數下一次被調用。下次調用時不再重新創造和初始化該變量,而是直接用上一次留下的值為基礎來進行操作。
3、靜態局部變量的這種特性,和全局變量非常類似。它們的相同點是都創造和初始化一次,以后調用時值保持上次的不變。不同點在於作用域不同
全局變量 定義在函數外面的變量,就叫全局變量。
普通全局變量 普通全局變量就是平時使用的,定義前不加任何修飾詞。普通全局變量可以在各個文件中使 用,可以在項目內別的.c文件中被看到,所以要確保不能重名。
靜態全局變量 靜態全局變量就是用來解決重名問題的。靜態全局變量定義時在定義前加static關鍵字, 告訴編譯器這個變量只在當前本文件內使用,在別的文件中絕對不會使用。這樣就不用擔心重名問題。所以靜態的全局變量就用在我定義這個全局變量並不是為了給別的文件使用,本來就是給我這個文件自己使用的。
跨文件引用全局變量(extern) 就是說,你在一個程序的多個.c源文件中,可以在一個.c文件中定義全局變量g_a,並且可以在別的另一個.c文件中引用該變量g_a(引用前要聲明)
函數和全局變量在C語言中可以跨文件引用,也就是說他們的連接范圍是全局的,具有文件連接屬性,總之意思就是全局變量和函數是可以跨文件看到的(直接影響就是,我在a.c和b.c中各自定義了一個函數func,名字相同但是內容不同,編譯報錯。)。
局部變量和全局變量的對比:
1、定義同時沒有初始化,則局部變量的值是隨機的,而全局變量的值是默認為0.
2、使用范圍上:全局變量具有文件作用域,而局部變量只有代碼塊作用域。
3、生命周期上:全局變量是在程序開始運行之前的初始化階段就誕生,到整個程序結束退出的時候才死亡;而局部變量在進入局部變量所在的代碼塊時誕生,在該代碼塊退出的時候死亡。
4、變量分配位置:全局變量分配在數據段上,而局部變量分配在棧上。
//static
1 #include <stdio.h> 2 3 4 void func1(void); 5 void func_static(void); 6 void func_static2(void); 7 void func_global(void); 8 void func_register(void); 9 10 int g_a = 1; 11 12 13 int main(void) 14 { 15 //a = 4; // 編譯報錯,未定義 16 g_a = 5; // 可以,因為g_a是全局變量,所以到處都可以用 17 18 func1(); // i = 2 19 func1(); // i = 2 20 func1(); // i = 2 21 22 func_static(); // a = 2 23 func_static(); // a = 3 24 func_static(); // a = 4 25 26 func_static2(); // a = 4; 27 func_static2(); // a = 7; 28 func_static2(); // a = 10; 29 30 func_global(); // g_a = 4; 31 func_global(); // g_a = 7; 32 func_global(); // g_a = 10; 33 34 func_register(); 35 func_register(); 36 func_register(); 37 38 39 40 41 // 因為i是定義在函數func中的局部變量,所以i的作用域為代碼塊作用域,所以i只在func1 42 // 函數內部有效,在func1外面是不能訪問i的。所以這里i會無定義。 43 //i = 5; // error: ‘i’ undeclared (first use in this function) 44 45 return 0; 46 } 47 48 49 void func1(void) 50 { 51 int i = 1; // 普通的局部變量,auto可以省略的 52 //auto int i = 0; // 自動局部變量,其實就是普通局部變量 53 54 i++; 55 56 printf("i = %d.\n", i); 57 } 58 59 void func_static(void) 60 { 61 static int a = 1; // 靜態的局部變量 62 63 a++; 64 65 printf("a = %d.\n", a); 66 } 67 68 void func_static2(void) 69 { 70 static int a = 1; // 靜態的局部變量 71 72 a += 3; 73 74 printf("a = %d.\n", a); 75 } 76 77 void func_global(void) 78 { 79 g_a += 3; 80 81 printf("g_a = %d.\n", g_a); 82 } 83 84 void func_register(void) 85 { 86 register int a = 1; // 靜態的局部變量 87 88 a += 3; 89 90 printf("a = %d.\n", a); 91 }
//globle
1 #include <stdio.h> 2 3 4 int g_i = 13; 5 6 7 // 實驗結論: 8 // 首先,main函數是一個程序運行最開始執行的東西,所有的其他函數都只能在main函數中被 9 // 直接或者間接的調用才能被執行。main函數的執行其實就是整個程序的生命周期,main函數 10 // 一return返回,整個程序就結束了。 11 // 其次,全局變量的定義和初始化是在main函數運行之前發生的。 12 int main(void) 13 { 14 printf("g_i = %d.\n", g_i); 15 16 return 0; 17 }
1 #include <stdio.h> 2 3 4 void func_in_a(void); 5 extern int g_a; // 聲明了一個int變量g_a 6 //extern int g_b; 7 8 void func_in_b(void) 9 { 10 printf("I am func in b.c.\n"); 11 } 12 13 14 int main(void) 15 { 16 printf("I am main in a.c.\n"); 17 printf("I am main in a.c, g_a = %d.\n", g_a); 18 printf("I am main in a.c, g_a = %d.\n", g_b); 19 20 21 //func_in_b(); // 直接調用 22 23 func_in_a(); // 間接調用 24 25 return 0; 26 }
1 #include <stdio.h> 2 3 4 5 void func_in_b(void); 6 7 int g_a = 12; 8 int g_b = 111; 9 10 11 12 13 14 15 void func_in_a(void) 16 { 17 18 g_a = 24; 19 20 printf("I am in func_in_a of a.c, g_a = %d.\n", g_a); 21 func_in_b(); 22 } 23 24 /* 25 // 定義錯誤 26 // C語言中,定義函數都必須在外面,不能在一個函數里面定義別的函數 27 // 所以沒有局部函數,只有全局函數。 28 29 void func1(void) 30 { 31 int a; 32 33 34 void func2() 35 { 36 int b; 37 } 38 } 39 40 */
//最后兩個分別為a.c b.c 文件目錄為

