main.c
#include <stdio.h> #include "zs.h" /* 局部變量是定義在函數、代碼塊、函數形參列表。存儲在棧中,從定義的那一行開始作用域結束釋放。 全局變量:寫在函數,代碼塊,形參列表外的變量,從定義的那一行開始一直直到文件末尾(暫時這樣認為),全局變量如果沒有進行初始化是0,存儲在靜態區中, 隨着程序的結束而結束。 */ /* 全局變量分為兩種: 1.外部全局變量: 可以被其它文件訪問的全局變量我們稱之為外部全局變量(默認情況下所有的全局變量都是外部全局變量。)。 多個同名的外部全局變量指向同一塊存儲空間。 2.內部全局變量: 只能被當前文件訪問的全局變量我們稱之為內部全局變量。只要給全局變量加上static關鍵字就是內部全局變量,多個同名的內部全局變量如果不在同一個文件中,那么指向不同的存儲空間。 */ /* 為了提高數據的安全性, 不讓別人在其它文件中修改我們的全局變量, static修改的全局變量就是內部全局變量, 只能在當前文件中使用 這樣就可以提高我們全局變量的安全性。 如果多個文件中存在同名的內部全局變量, 相互不會影響 如果既有外部全局變量也有內部全局變量, 那么會優先訪問內部全局變量 extern: 用於聲明一個外部全局變量 聲明只需要在使用變量之前聲明就可以了,聲明不會開辟存儲空間 static: 用於定義一個內部全局變量,定義會開辟存儲空間 */ int num; // 外部全局變量,可以定義多個同名的全局變量, int num; int num; static int num; // 內部全局變量 998 int main(int argc, const char * argv[]) { num = 998; test(); printf("mian.c = num = %i\n", num); return 0; }
zs.c
#include "zs.h" /* int num; // 不允許,由於Xcode升級之后檢驗導致的, 在Xcode6以前是可以的 如果直接在zs.c當中定義外部全局變量num, 那么我們說過同名的外部全局變量指向同一塊存儲空間, 那么如果在多個文件中有同名的外部全局變量, 可能導致A文件的數據被B文件不小心修改了 降低了數據的封裝性, 提高了發生錯誤的概率,所以不建議在不同的文件寫同名的全局變量。 */ // extern代表聲明一個全局變量,注意:聲明全局變量和聲明函數一樣,僅僅是告訴系統我們有這個全局變量,但並不會真在的開辟存儲空間。 extern int num; static int num; // 0 666 int num; // 0 666 void test() { extern int num;//聲明也可以寫在函數里面,只要在使用之前就可以。 printf("zs.c = num = %i\n", num); // 0 num = 666; } int num;
zs.h
void test();
-----------------------------------------------------------------------------------------------------------------------------------------------
main.c
// // main.c // static對局部變量的作用 #include <stdio.h> void test() { int a = 0; // 局部變量,棧里面 // 當使用static來修飾局部變量, 那么會延長局部變量的生命周期, 並且會更改局部變量存儲的位置 , 將局部變量從棧轉移到靜態區中 // 只要使用static修改局部變量之后, 當執行到定義局部變量的代碼就會分配存儲空間, 但是只有程序結束才會釋放該存儲空間 static int b = 0;//靜態區 a++; // 1 b++; // 1 2 printf("a = %i\n", a); // 1 printf("b = %i\n", b); // 1 printf("------------\n"); } void demo(int r) { /* 應用場景": 當某個方法的調用頻率非常高, 而該方法中更有些變量的值是固定不變的 那么這個時候就可以使用static來修飾該變量, 讓該變量只開辟一次存儲空間 這樣可以提高程序的效率和性能 */ static double pi = 3.1415926; // 固定 double res = pi * r * r; printf("res = %lf\n", res); } int main(int argc, const char * argv[]) { test();//1,1 test();//1,2 for (int i = 0; i < 100; i++) { demo(i); } return 0; }
-----------------------------------------------------------------------------------------------------------------------------------------------
main.c
// // main.c // extern和static對函數的作用 #include <stdio.h> #include "zs.h" //導入頭文件就可以 void demo(); //由於demo函數沒有加static默認所有文件都可以訪問,所以在main中使用之前聲明demo就可以了。不聲明也可以訪問。 /* 函數也分為內部函數和外部函數, 默認情況下所有的函數都是外部函數, 可以被其它文件訪問的函數稱之為外部函數, 只能在當前文件中范文的函數稱之為內部函數。 */ int main(int argc, const char * argv[]) { test(); demo(); return 0; } extend用在全局變量,表示聲明一個全局變量不會開辟空間。 extend用於函數表示外部全局函數(一般不寫,函數默認都是外部的)。 static用在全局變量表示定義一個內部全局變量,只能在本文件中使用。 static用在局部變量表示把局部變量放在靜態區,多次引用是同一個。 static用在函數表示內部函數,只在本文件中使用。
zs.h
// // zs.h // day10 void test(); extern void test(); // 在.h中聲明一個內部函數沒有任何意義,因為別人看得到但是用不了。 static void demo();
zs.c
// // zs.c // day10 #include "zs.h" // 聲明內部函數一般用於內部函數定義在后面, 而想在定義之前使用內部函數 static void demo(); // 只要在函數的返回值前面加上一個extern就可以讓函數變為一個外部函數, 由於默認就是外部函數, 所以在開發中一般情況extern沒人寫 // 如果extern寫在函數的實現中, 代表定義一個外部函數 // 如果extern寫在函數的聲明中, 代表聲明一個外部函數 extern void test() { printf("test printf\n"); demo(); } // 不加static默認所有文件都可以訪問。static讓函數變為內部函數, 其它文件就不能訪問了。 // 如果static寫在函數的實現中, 代表定義一個內部函數 // 如果static寫在函數的聲明中, 代表聲明一個內部函數 static void demo() { printf("demo printf\n"); }