一.全局變量
• 定義在函數外面的變量是全局變量
• 全局變量具有全局的生存期和作用域
• 它們與任何函數都無關
•在任何函數內部都可以使用它們
二.全局變量初始化
• 沒有做初始化的全局變量會得到0值
• 指針會得到NULL值
• 只能⽤用編譯時刻已知的值來初始化全局變量
• 它們的初始化發生在main函數之前
#include <stdio.h> int f(void); int gAll = 12; int main(int argc, char const *argv[]) { printf("in %s gAll=%d\n",__func__,gAll); //__func__打印函數名字 f(); printf("agn in %s gAll=%d\n",__func__,gAll); return 0; } int f(void) { printf("in %s gAll=%d\n",__func__,gAll); gAll +=2; printf("agn in %s gAll=%d\n",__func__,gAll); return gAll; }
被隱藏的全局變量
• 如果函數內部存在與全局變量同名的變量,則全局變量被隱藏
三.靜態本地變量
• 在本地變量定義時加上static修飾符就成為靜態本地變量
• 當函數離開的時候,靜態本地變量會繼續存在並保持其值
• 靜態本地變量的初始化只會在第一次進入這個函數時做,以后進入函數時會保持上次離開時的值
• 靜態本地變量實際上是特殊的全局變量
• 它們位於相同的內存區域
• 靜態本地變量具有全局的生存期,函數內的局部作用域
• static在這里的意思是局部作用域(本地可訪問)
#include <stdio.h> int f(void); int gAll =12; int main(int argc,char const *argv[]) { f(); // f(); // f(); return 0; } int f(void) { int k =0; static int all =1; printf("&gAll=%p\n",&gAll); printf("&all=%p\n",&all); //靜態本地變量 其實就是特殊的全局變量 printf("&k=%p\n",&k); printf("in %s all=%d\n",__func__,all); all +=2; printf("agn in %s all =%d\n",__func__,all); return all; }
四.*返回指針的函數
• 返回本地變量的地址是危險的
• 返回全局變量或靜態本地變量的地址是安全的
• 返回在函數內malloc的內存是安全的,但是容易造成問題
• 最好的做法是返回傳入的指針
#include <stdio.h> int *f(void); void g(void); int main(int argc, char const *argv[]) { int *p= f(); printf("*p=%d\n",*p); g(); printf("*p=%d\n",*p); return 0; } int *f(void) { int i=12; printf("&i=%p\n",&i); return &i; } void g(void) { int k=24; printf("&k=%p\n",&k); printf("k=%d\n",k); }
tips
• 不要使用全局變量來在函數間傳遞參數和結果
• 盡量避免使用全局變量
• 豐田汽車的案子
• *使用全局變量和靜態本地變量的函數是線程不安的