C語言丨一文帶你了解關鍵字register(又名閃電飛刀 )


register:這個關鍵字請求編譯器盡可能的將變量存在CPU內部寄存器中,而不是通過內存尋址訪問,以提高效率。注意是盡可能,不是絕對。

因為,如果定義了很多register變量,可能會超過CPU的寄存器個數,超過容量。所以只是可能。

關於register關鍵字,在《C與指針》這一本書的都151頁,作者這樣說到:

“在許多機器上,register變量所產生的代碼將比靜態內存中的變量和堆棧中的變量所產生的代碼執行速度更快。

但是這取決於你的環境,許多當前的編譯器比程序員更加懂得怎樣合理分配寄存器。”


 

一、閃電飛刀----register

register就和它的名字一樣,很少出現在代碼世界中,因為敢稱為閃電飛刀的變量,通常只會在一些特定場合才能出現。它是如此的快,以致於CPU都對其刮目相看,但是它有一個致命的缺點,它的速度“看心情”而定,不是每一次都能讓人滿意。

作用:如果一個變量被register來修辭,就意味着,該變量會作為一個寄存器變量,讓該變量的訪問速度達到最快。比如:一個程序邏輯中有一個很大的循環,循環中有幾個變量要頻繁進行操作,這些變量可以聲明為register類型。


 

二、皇帝身邊的小太監----寄存器

寄存器變量:寄存器變量是指一個變量直接引用寄存器,也就是對變量名的操作的結果是直接對寄存器進行訪問。寄存器是CPU的親信,CPU操作的每個操作數和操作結果,都由寄存器來暫時保存,最后才寫入到內存或從內存中讀出。也就是說,變量的值通常保存在內存中,CPU對變量進行讀取先是將變量的值從內存中讀取到寄存器中,然后進行運算,運算完將結果寫回到內存中。

為什么要這么設計,而不直接對變量的值從內存中進行運算,而要再借助於寄存器?這是由於考慮到性能的問題才這么設計的。在計算機系統中,包含有很多種不同類型的存儲器,如表xxx所示。


 

在計算機中CPU的運算速度最快,現在都達到3GHZ左右,而相對應的存儲器速度卻相對慢很多,訪問速度最快的寄存器和緩存,由於其體積又大,不適合大容量的使用,所以只能二者相接合的方式來提高效率。程序代碼保存在內存中,當使用數據時,將其送到寄存器,讓CPU來訪問,使用完畢,送回內存保存。而C語言又允許使用寄存器來保存變量的值,很明顯這樣能大大提高程序的執行速度,但是,寄存器的個數是有限的,X86也就是十幾個,ARM最多才37個。我們不可能將全部的變量都聲明為寄存器變量,因為其它代碼也要使用寄存器,同樣,我們聲明的寄存器變量也不一定直接保存在寄存器中,因為寄存器可能全部都在被其它代碼占用。編譯器只能是盡量的為我們的變量安排在寄存器中。

在使用寄存器變量時,請注意:

待聲明為寄存器變量類型應該是CPU寄存器所能接受的類型,意味着寄存器變量是單個變量,變量長度應該小於等於寄存器長度。

不能對寄存器變量使用取地址符“&”,因為該變量沒有內存地址。

盡量在大量頻繁的操作時使用寄存器變量,且聲明的變量個數應該盡量的少。


 

三、舉例

  register修飾符暗示編譯程序相應的變量將被頻繁地使用,如果可能的話,應將其保存在CPU的寄存器中,以加快其存儲速度。例如下面的內存塊拷貝代碼,

#ifdef NOSTRUCTASSIGN

memcpy (d, s, l)

{

        register char *d;

    register char *s;

    register int i;

    while (i--)

        *d++ = *s++;

}

#endif

    但是使用register修飾符有幾點限制。

(1)register變量必須是能被CPU所接受的類型。

這通常意味着register變量必須是一個單個的值,並且長度應該小於或者等於整型的長度。不過,有些機器的寄存器也能存放浮點數。

(2)因為register變量可能不存放在內存中,所以不能用“&”來獲取register變量的地址。

(3)只有局部自動變量和形式參數可以作為寄存器變量,其它(如全局變量)不行。

在調用一個函數時占用一些寄存器以存放寄存器變量的值,函數調用結束后釋放寄存器。此后,在調用另外一個函數時又可以利用這些寄存器來存放該函數的寄存器變量。

(4)局部靜態變量不能定義為寄存器變量。不能寫成:register static int a, b, c;

(5)由於寄存器的數量有限(不同的cpu寄存器數目不一),不能定義任意多個寄存器變量,而且某些寄存器只能接受特定類型的數據(如指針和浮點數),因此真正起作用的register修飾符的數目和類型都依賴於運行程序的機器,而任何多余的register修飾符都將被編譯程序所忽略。

注意:

早期的C編譯程序不會把變量保存在寄存器中,除非你命令它這樣做,這時register修飾符是C語言的一種很有價值的補充。然而,隨着編譯程序設計技術的進步,在決定哪些變量應該被存到寄存器中時,現在的C編譯環境能比程序員做出更好的決定。實際上,許多編譯程序都會忽略register修飾符,因為盡管它完全合法,但它僅僅是暗示而不是命令。


 

如果你想更好的提升你的編程能力,學好C語言C++編程!彎道超車,快人一步!

C語言C++學習企鵝圈子】,分享(源碼、項目實戰視頻、項目筆記,基礎入門教程)

歡迎轉行和學習編程的伙伴,利用更多的資料學習成長比自己琢磨更快哦!

編程學習書籍:


 

編程學習視頻:


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM