STATIC關鍵字
static關鍵字內核中到處都在用。還有以前上課時老師講的goto儘量不用,結果內核中也大量使用~
static 修飾函數
當修飾函數時,代表這個函數的可見域爲當前文件。在其他文件中想訪問此函數則不行了.
這樣的意義在於可以很好的解決不同文件中同名函數的問題,讓此函數變得當前文件私有,其他文件不可見.
static int func(void)
{
}
static 修飾變量
1.static 修飾全局變量:靜態全局變量
這邊的意義在於將此全局變量限定於本文件內有效,其他文件不可見。也就是說同樣限定了它的作用域爲本文件。
static int a=1;
void main()
{
printf("%d.",a);
}
2.static修飾局部變量:靜態局部變量
void test(void)
{
static int i=0;
i++;
printf("%d.\n",i);
}
void main()
{
while(1)
{
test();
}
}
test函數中 如果變量i沒有被static修飾,那麼每次打印的值都是0.
如果被static修飾,那麼則是0,1,2,3,4……..
局部變量:
普通的局部變量在棧空間上分配,這個局部變量所在的函數被多次調用時,每次調用這個局部變量在棧上的位置都不一定相同。局部變量也可在堆上動態分配,但是記得使用完這個堆空間後要釋放.
靜態局部變量:
在內存中的位置: data段,全局數據區,聲明週期爲整個程序運行期間.
作用域:當前文件的 局部變量所屬的函數.其他文件肯定不可見。當前文件的其他函數也不可見.
值:靜態局部變量如果沒有被用戶初始化,則會被編譯器自動賦值爲0,以後每次調用靜態局部變量的時候都用上次調用後的值。這個比較好理解,每次函數調用靜態局部變量的時候都修改它然後離開,下次讀的時候從全局存儲區讀出的靜態局部變量就是上次修改後的值。
extern關鍵字
在windows下用keil c version2時經常有這樣的寫法:
void main()
{
test();
}
void test(void)
{
}
如果這樣寫是會報錯的,而應該:
void test(void)
{
}
void main()
{
test();
}
或者:
void test(void);
void main()
{
test();
}
void test(void)
{
}
這樣纔是OK的,當然這和編譯器的行爲有關.
下來來講extern關鍵字.
extern用來聲明一個函數或者變量在其他文件中。也就是說extern的使用會擴大函數或者變量的作用域.
例如:
1.c中
int a=3;
int b;
void func1(void)
{
}
void func2(void)
{
}
那麼如果想要在2.c文件中訪問1.c文件中的變量a和函數 func1的話:
extern int a;
extern void func1(void);
void main()
{
printf("%d.\n",a);
func1();
}
const關鍵字
定義一個變量,卻不想被別人修改,只讀模式,不能改。則用const修飾.
const int a=1;
int const a=1;
這樣都是可以的.
const int a=5;
a=8;
這樣是不行的,會報錯。const修飾的變量不允許被再次修改.
int a1=4;
int a2=5;
int a3=6;
const int *b1=&a1;
int const *b2=&a2;
int * const b3=&a3;
1) b1的指針可以被賦值。但是*b1不能被賦值.如果此時進行如下操作
a1=8;
b1 =&a2;
printf("*b1:%d,a2:%d,a1:%d.\n",*b1,a2,a1);
這些操作均是允許的,結果*b1 =5,a2=5,a1=8
2)b2的指針可以被賦值,但是*b2不能被賦值。b2和b1是等價的.
3)b3的指針不能被賦值 b3=&a1是不允許的.
*b3=100;
printf("*b3:%d.\n",*b3);
這樣的操作是允許的.
volatile 關鍵字
正常的,編譯器都有自帶優化代碼的能力.volatile關鍵字防止編譯器進行優化.
當一些變量在程序運行的過程中因爲某些特定的因素會被不停的改變(操作系統、硬件或者其它線程等).
用volatile修飾保證每次訪問此變量都會從內存中重新抓取.保證每次獲得數據都是正確的,實時的.這樣做阻止了編譯器對其的優化.從而保證對特殊地址訪問的正確性.
訪問內部寄存器的效率高於訪問內存。所以當編譯器進行優化時,可能將內存變量緩存到寄存器中,當訪問這個變量時,實則訪問的是寄存器中緩存的數據.
如果我們要獲取一個外部普通輸入GPIO管腳的狀態,應該從內存中去讀出它的實時值。所以告訴編譯器這個變量是可變的,然後用volatile修飾來讓cpu每次訪問時都從內存中獲取它的值.
register 關鍵字
這個關鍵字請求編譯器儘可能的將變量存在CPU內部寄存器中,而不是通過內存尋址訪問,以提高效率。注意是儘可能,不是絕對.