C語言初學者必須掌握的關鍵字
其實我們小白們在寫程式碼的時候,關鍵字還是用的比較多的,我主要就平常用到的關鍵字進行了下總結,以便於我們更全面的理解其在程式碼中的意圖。讓我們有耐心的看下去吧!!!
C語言關鍵字的總結
static關鍵字C語言
const關鍵字C語言
register關鍵字用法
auto關鍵字
inline行內函數
—————————————————————————————————————————————————————
1、static關鍵字
static可以用來修飾區域性變數、全域性變數、函式
1、區域性變數:
生命週期:原先存在棧中,生命週期語句執行完畢便結束了。現在存放到靜態資料區,生命週期持續到整個程式執行結束。
作用域:並沒有改變作用域,還是僅限於該語句塊。並且只在初次執行的時候進行初始化,下次呼叫時它的值是上一次函式呼叫結束之後的值。每次呼叫後值會被儲存。
例如
#include<stdio.h>
void fun()
{
static int a = 1;a++;
printf("%d\n",a);
}
int main()
{
fun();
fun();
return 0;
}
輸出結果
2、全域性變數:
對於一個全部變數,既可以在本原始檔中被訪問到,也可以在同一個工程的其它原始檔中被訪問(只需用extern進行宣告即可)。
如果加上static,限制該全域性變數的作用域範圍,由原來的整個工程可見變為本原始檔可見。
3、函式:
與修飾全域性變數大同小異,就是改變了函式的作用域。
修飾函式時還有一處不同,就是呼叫靜態函式時,函式指標指向的地址始終是固定的,而普通函式每次返回的地址不一樣。
extern用在變數或者函式的宣告前,用來說明“此變數/函式是在別處定義的,要在此處引用”。另外,用extern會加速程式的編譯過程,這樣能節省時間。
2、const關鍵字
C語言中保留的一個關鍵字,它用來限定一個變數是隻讀的,即不可變的。
1、用const修飾一般變數
用const修飾的變數必須在宣告時進行初始化(用來修飾函式的形參除外)
const int n;//這種宣告方式是錯誤的
const int n = 5;//正確
void fun(const int n);//正確
const char a;//錯誤
char *const p;//錯誤
const char *p;//正確(注意這種為什麼是正確的),因為這裡的const是修飾p所指向的變數,而不是指標變數p本身。
一旦一個變數被const修飾後,在程式中除初始化外對這個變數進行的賦值都是錯誤的。
const int n = 5;
n = 3;//錯誤
2、const與指標搭配使用
重點內容
兩個基礎概念:指標常量和常量指標
指標常量:即指標本身的值是不可改變的,而指標指向的變數的值是可以改變的;
常量指標:即指標指向的變數的值是不可改變的,而指標本身的值是可以改變的;
如果const在’*’左邊,則表示指標指向的變數的值不可變;
如果const在’*’右邊,則表示指標的值是不可變的。
#include<stdio.h>
int main(void)
{
const int a = 3;
int* pa = &a;
*pa = 4;
printf("%d\n",*pa);
printf("%d\n",a);
return 0;
}
輸出結果
注意:
不能顯示地通過賦值語句去改變a的值,但是不代表在程式中不能通過其他方式修改這個值。
3、register關鍵字用法
register:這個關鍵字請求編譯器儘可能的將變數存在CPU 內部暫存器中而不是通過記憶體定址訪問以提高效率。注意是儘可能,不是絕對。
暫存器其實就是一塊一塊小的儲存空間,只不過其存取速度要比記憶體快得多。
資料從記憶體裡拿出來先放到暫存器,然後CPU 再從暫存器裡讀取資料來處理,處理完後同樣把資料通過暫存器存放到記憶體裡,CPU 不直接和記憶體打交道
資料從記憶體裡拿出來先放到暫存器,然後CPU 再從暫存器裡讀取資料來處理,處理完後同樣把資料通過暫存器存放到記憶體裡,CPU 不直接和記憶體打交道。
有個故事,叫皇帝身邊的小太監,挺形象的:
大家都看過電視戲,那些皇帝們要閱讀檔案的時候,大臣總是先將奏章交給皇帝旁邊的小太監,小太監呢再交給皇帝處理。這個小太監只是箇中轉站,並無別的功能。
好,那我們再聯想到我們的CPU。CPU 不就是我們的皇帝麼?大臣就相當於我們的記憶體,資料從他這拿出來。那小太監就是我們的暫存器了(這裡先不考慮CPU 的快取記憶體區)。
這裡要說明的一點是:小太監是主動的從大臣手裡接過奏章,然後主動的交給皇帝,但暫存器沒這麼自覺,它從不主動幹什麼事。一個皇帝可能有好些小太監,那麼一個CPU 也可以有很多暫存器,不同型號的CPU 擁有暫存器的數量不一樣。
為啥要這麼麻煩啊?速度!就是因為速度。暫存器其實就是一塊一塊小的儲存空間,只不過其存取速度要比記憶體快得多。
進水樓臺先得月嘛,它離CPU 很近,CPU 一伸手就拿到資料了,比在那麼大的一塊記憶體裡去尋找某個地址上的資料是不是快多了?那有人問既然它速度那麼快,那我們的記憶體硬碟都改成暫存器得了唄。我要說的是:你真有錢!
一些限制:
———————————————————————–
(1)register變數必須是能被CPU所接受的型別。
這通常意味著register變數必須是一個單個的值,並且長度應該小於或者等於整型的長度。不過,有些機器的暫存器也能存放浮點數。
(2)因為register變數可能不存放在記憶體中,所以不能用“&”來獲取register變數的地址。
(3)只有區域性自動變數和形式引數可以作為暫存器變數,其它(如全域性變數)不行。
在呼叫一個函式時佔用一些暫存器以存放暫存器變數的值,函式呼叫結束後釋放暫存器。此後,在呼叫另外一個函式時又可以利用這些暫存器來存放該函式的暫存器變數。
(4)區域性靜態變數不能定義為暫存器變數。不能寫成:register static int a, b, c;
(5)由於暫存器的數量有限(不同的cpu暫存器數目不一),不能定義任意多個暫存器變數,而且某些暫存器只能接受特定型別的資料(如指標和浮點數),因此真正起作用的register修飾符的數目和型別都依賴於執行程式的機器,而任何多餘的register修飾符都將被編譯程式所忽略。
注意:
早期的C編譯程式不會把變數儲存在暫存器中,除非你命令它這樣做,這時register修飾符是C語言的一種很有價值的補充。
然而,隨著編譯程式設計技術的進步,在決定哪些變數應該被存到暫存器中時,現在的C編譯環境能比程式設計師做出更好的決定。
實際上,許多編譯程式都會忽略register修飾符,因為儘管它完全合法,但它僅僅是暗示而不是命令。
4、auto關鍵字
用於宣告變數的生存期為自動,所有的變數預設就是auto的。
5、inline行內函數
呼叫函式時需要一定的時間和空間的開銷。C++提供一種提高效率的方法,即在編譯時將函式呼叫處用函式體替換,類似於C語言中的巨集展開。這種在函式呼叫處直接嵌入函式體的函式稱為行內函數(inline function),又稱內嵌函式或內建函式
注意:是在函式定義時增加 inline 關鍵字,而不是在函式宣告時。
優點:
行內函數可以有效避免函式呼叫的開銷,程式執行效率更高
缺點:
如果被宣告為行內函數的函式體非常大,則編譯器編譯後程序的可執行碼將會變得很大。當行內函數的函式體過大時,一般的編譯器會放棄內聯方式,而採用普通的方式呼叫函式。這樣,行內函數就和普通函式執行效率一樣了。
總結:
通常在程式設計過程中,我們會將一些頻繁被呼叫的短小函式宣告為行內函數。
呼叫行內函數和呼叫正規函式是等價的,差別僅僅是更快。