概念
作用域:塊作用域勤揩,函數(shù)作用域殖告,文件作用域
鏈接:
外部鏈接:多文件中使用
內(nèi)部鏈接:只在一個翻譯單元(文件)內(nèi)使用
無鏈接 :具有塊,
函數(shù),函數(shù)原型作用域的變量
存儲期:靜態(tài)作用域和非靜態(tài)作用域
自動變量:
1.自動儲存期沿量,
2.塊作用域,
3.無鏈接
4.auto關鍵字(顯式)
void doSome(){
int d = 3;
};
int main(int argc, const char * argv[]) {
int a = 0;
for (int i = 0 ; i < 10 ; i++) {
int b = 1;
}
{
auto int c = 2;
}
return 0;
}
// a,b,c,d都是自動變量
靜態(tài)內(nèi)部鏈接:
1.static顯式聲明冤荆,
2.靜態(tài)儲存期朴则,
3.內(nèi)部鏈接,
4.文件作用域.
static int statc_a = 2; //只能在main.c中訪問
int main(int argc, const char * argv[]) {
printf("%d",statc_a);
return 0;
}
靜態(tài)外部鏈接:
1.靜態(tài)儲存期钓简,
2.外部鏈接乌妒,
3.文件作用域.
/* sub.h */
#include "sub.h"
int sub_a = 2;
/* main.c */
#include <stdio.h>
int main(int argc, const char * argv[]) {
extern int sub_a;
printf("sub_a : %d\n",sub_a);
return 0;
}
/*
sub_a : 2
Program ended with exit code: 0
*/
//編譯器會找到sub_a這個變量的。
這樣使用靜態(tài)外部鏈接的存儲類別變量是有問題的外邓,如果全局的變量名有重復的就會報錯,比如在main.c中又定義了一個相同名字的sub_a 撤蚊,編譯無法通過,顯示鏈接錯誤损话。
#include <stdio.h>
int sub_a = 2;
int main(int argc, const char * argv[]) {
extern int sub_a;
printf("sub_a : %d\n",sub_a);
return 0;
}
//clang: error: linker command failed with exit code 1 (use -v to see invocation)
一個比較規(guī)范辦法是使用頭文件,在頭文件中申明需要外部使用的變量extern
/* .h */
#include <stdio.h>
extern int sub_a;
#endif /* sub_h */
/* main.c */
#include <stdio.h>
#include "sub.h"
int main(int argc, const char * argv[]) {
printf("sub_a : %d\n",sub_a);
int sub_a = 3;
printf("sub_a : %d\n",sub_a);
return 0;
}
//但是依然并不能完全解決我們上面產(chǎn)生的問題侦啸。
靜態(tài)無鏈接
1.靜態(tài)儲存期,
2.無連接丧枪,
3.塊作用域
PS:靜態(tài)變量只能初始化一次光涂,并且定義時候必須賦值。
static:在聲明局部變量時,使用關鍵字 static 將局部變量指定為“靜態(tài)局部變量”,這樣在函數(shù)調(diào)用結(jié)束后不消失而保留原值棒动,即占用的存儲單元不釋放,在下一次函數(shù)調(diào)用時齐佳,該變量已有值就是上次函數(shù)調(diào)用結(jié)束時的值。
static的作用?
1.在塊作用域內(nèi)將變量的存儲期變成靜態(tài)
void add(){
static int static_a = 1;
int a = 1;
printf("static_a:%d---a:%d\n",static_a,a);
static_a++;
a++;
}
//調(diào)用三次
static_a:1---a:1
static_a:2---a:1
static_a:3---a:1
2,將文件作用域內(nèi)的變量從外部鏈接變成內(nèi)部鏈接
/* sub.c */
#include "sub.h"
static int static_sub_a = 3;
int sub_a = 2;
/* main.c */
int main(int argc, const char * argv[]) {
extern int sub_a;
extern int static_sub_a;
printf("%d\n",static_sub_a);
printf("%d\n",sub_a);
return 0;
}
//報錯 "_static_sub_a", referenced from: 外部無法訪問static_sub_a