C語言關鍵字auto與register的深入理解

來源:互聯網
上載者:User

關鍵字概述
很多朋友看到這兒可能會有疑問,往往其它講C語言的書籍都是從HelloWorld,資料類型開始C語言學習的,為什麼我們要從C語言的關鍵字開始呢?關於這點,我有兩點需要說明:
本章節面向的讀者對象是有一定的C語言基礎知識的朋友(至少應該學習過大學裡的C語言程式設計等類似的課程)
本章節結合了作者多年嵌入式工作、研究、教學經驗而作,由電腦底層硬體到上層軟體設計融會貫通,中間有大量的深入淺出的樣本

在我對C語言進行培訓的時候,往往就是從C語言的關鍵字入手,因為C語言的關鍵字蘊含了C語言的全部的詞彙,囊括了C語言裡大量知識要點,從C語言關鍵字開刀,首先可以對你之前所學知識進行複習,其次,切磋一下和作者有什麼不同的見解,廢話少說,讓我們從關鍵字開始。
關鍵字,又叫保留字,是編譯器能識別的特殊單詞,每種電腦語言都會有其特定的關鍵字,C語言中有32位關鍵字。
問:為什麼要有關鍵字?
答:關鍵字是程式設計中代碼必須包含的部分,編譯器在編譯C代碼的時候,必然要將C代碼進行斷句,將代碼分割成不同部分,將這些部分分別進行解析和編譯。
int a = 10; int是關鍵字,編譯器看到它出現,會將它後面的字元作為整型變數名來處理。
也就是說,關鍵字是編譯器能認識的特殊字元串符號。
關鍵字的數量是由編譯器來決定的,關鍵字大小寫敏感性也和編譯器有關。如果關鍵字寫錯,那麼在代碼的解析過程中,編譯器就會報錯:符號不能識別或符號不能被解析。
每個關鍵字有著不同的意義,用來告知編譯器編程者的目的。

關鍵字分類
32個關鍵字每個都有不同的意義,大體上根據其意義可以分為以下幾類(底線表示不同分類中有交集):
1)非常見:auto、register、volatile、goto
2)儲存相關:const、extern、register、volatile、static、auto、signed、unsigned
3)資料類型:char、short、int、float、long、double、struct、union、enum、void
4)邏輯控制:if、else、for、while、do、break、continue、return、default、switch、case、goto
5)特殊用途:sizeof、typedef
我相信,大部分關鍵字我們都能認識,並且能夠使用,有一部分可能很少見,甚至一點印象也沒有:它也是C語言的關鍵字???
1.隱形刺客:auto
描述:
auto關鍵字在我們寫的代碼裡幾乎看不到,但是它又無處不在,它是如此的重要,又是如此的與世無爭,默默的履行著自己的義務,卻又隱姓埋名。
作用:C程式是面向過程的,在C代碼中會出現大量的函數模組,每個函數都有其生命週期(也稱範圍),在函數生命週期中聲明的變數通常叫做局部變數,也叫自動變數。例如:

複製代碼 代碼如下: int fun(){
int a = 10; // auto int a = 10;
// do something
return 0;
}

複製代碼 代碼如下: int fun(){
int a = 10; // auto int a = 10;
// do something
return 0;
}

整型變數a在fun函數內聲明,其範圍為fun函數內,出來fun函數,不能被引用,a變數為自動變數。也就是說編譯器會有int a = 10之前會加上auto的關鍵字。
auto的出現意味著,當前變數的範圍為當前函數或程式碼片段的局部變數,意味著當前變數會在記憶體棧上進行分配。
記憶體棧:
如果大家學過資料結構,應該知道,棧就是先進後出的資料結構。它類似於我們用箱子打包書本,第一本扔進去大英,第二本扔進行高數,第三本扔進行小說,那麼取書的時候,先取出來第一本是小說,第二是高數,第三本是大英。
棧的操作為入棧和出棧,入棧就是向箱子裡扔書,出棧就是從箱子裡取書。那麼這和我們的auto變數分配空間有什麼關係呢?
由於一個程式中可能會有大量的變數聲明,每個變數都會佔有一定的記憶體空間,而記憶體空間對於電腦來說是寶貴的硬體資源,因此合理的利用記憶體是編譯器要做的一個主要任務。有的變數是一次性使用的,如局部變數。有的變數要伴隨著整個程式來使用的,如全域變數。為了節省記憶體空間,最佳化效能,編譯器通常會將一次性使用的變數分配在棧上。也就是說,代碼中聲明一個一次性變數,就在棧上進行入棧操作。當該變數使用完了(生命週期結束),進行出棧操作。這樣,在執行不同的函數的時候,就會在一個棧上進行出入棧操作,也就是說它們在頻繁的使用一個相同的記憶體空間,從而可以更高效的利用記憶體。

PS:有的編譯器為了提高效率,在出棧時不會進行資料清空,這也就意味著,下個函數裡的變數在入棧使用該空間時,裡面的資料是上一次變數操作的結果。
2.閃電飛刀:register
描述:register就和它的名字一樣,很少出現在代碼世界中,因為敢稱為閃電飛刀的變數,通常只會在一些特定場合才能出現。它是如此的快,以致於CPU都對其刮目相看,但是它有一個致命的缺點,它的速度“看心情”而定,不是每一次都能讓人滿意。
作用:如果一個變數被register來修辭,就意味著,該變數會作為一個寄存器變數,讓該變數的訪問速度達到最快。比如:一個程式邏輯中有一個很大的迴圈,迴圈中有幾個變數要頻繁進行操作,這些變數可以聲明為register類型。
寄存器變數:寄存器變數是指一個變數直接引用寄存器,也就是對變數名的操作的結果是直接對寄存器進行訪問。寄存器是CPU的親信,CPU操作的每個運算元和操作結果,都由寄存器來暫時儲存,最後才寫入到記憶體或從記憶體中讀出。也就是說,變數的值通常儲存在記憶體中,CPU對變數進行讀取先是將變數的值從記憶體中讀取到寄存器中,然後進行運算,運算完將結果寫回到記憶體中。為什麼要這麼設計,而不直接對變數的值從記憶體中進行運算,而要再藉助於寄存器?這是由於考慮到效能的問題才這麼設計的。在電腦系統中,包含有很多種不同類型的儲存空間,如表xxx所示。
表xxx 電腦儲存空間分類

名稱

速度

特點

用途

靜態儲存空間

最快

造價高,體積大,適合小容量的緩衝

寄存器,緩衝

動態儲存裝置器

較快

造價較低,體積較小,適合大容易儲存資料

記憶體

在電腦中CPU的運算速度最快,現在都達到3GHZ左右,而相對應的儲存空間速度卻相對慢很多,訪問速度最快的寄存器和緩衝,由於其體積又大,不適合大容量的使用,所以只能二者相接合的方式來提高效率。程式碼儲存在記憶體中,當使用資料時,將其送到寄存器,讓CPU來訪問,使用完畢,送回記憶體儲存。而C語言又允許使用寄存器來儲存變數的值,很明顯這樣能大大提高程式的執行速度,但是,寄存器的個數是有限的,X86也就是十幾個,ARM最多才37個。我們不可能將全部的變數都聲明為寄存器變數,因為其它代碼也要使用寄存器,同樣,我們聲明的寄存器變數也不一定直接儲存在寄存器中,因為寄存器可能全部都在被其它代碼佔用。編譯器只能是盡量的為我們的變數安排在寄存器中。
在使用寄存器變數時,請注意:
待聲明為寄存器變數類型應該是CPU寄存器所能接受的類型,意味著寄存器變數是單個變數,變數長度應該小於等於寄存器長度
不能對寄存器變數使用取地址符“&”,因為該變數沒有記憶體位址
盡量在大量頻繁的操作時使用寄存器變數,且聲明的變數個數應該盡量的少

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.