轉載 C語言中register型別的變數有什麼意義
一般情況下,變數的值是儲存在記憶體中的,CPU 每次使用資料都要從記憶體中讀取。如果有一些變數使用非常頻繁,從記憶體中讀取就會消耗很多時間,例如 for 迴圈中的增量控制:
int i; for(i=0; i<1000; i++){ // Some Code }
執行這段程式碼,CPU 為了獲得 i,會讀取 1000 次記憶體。
為了解決這個問題,可以將使用頻繁的變數放在CPU的通用暫存器中,這樣使用該變數時就不必訪問記憶體,直接從暫存器中讀取,大大提高程式的執行效率。
暫存器、快取、記憶體
為了加深對 register 變數的理解,這裡有必要講一下CPU暫存器。
按照與CPU的遠近來分,離CPU最近的是暫存器,然後是快取,最後是記憶體。
暫存器是最貼近CPU的,而且CPU只在暫存器中進行存取。寄存的意思是暫時存放資料,不用每次都從記憶體中取,它是一個臨時的存放資料的空間。
而暫存器的資料又來源於記憶體,於是 CPU <-- 暫存器 <-- 記憶體,這就是它們之間的資訊交換。
那麼為什麼還需要快取呢?因為如果頻繁地操作記憶體中同一地址上的資料會影響速度,於是就在暫存器和記憶體之間設定一個快取,把使用頻繁的資料暫時儲存到快取,如果暫存器需要讀取記憶體中同一地址上的資料,就不用大老遠地再去訪問記憶體,直接從快取中讀取即可。
快取的速度遠高於記憶體,價格也是如此。
注意:快取的容量是有限的,暫存器只能從快取中讀取到部分資料,對於使用不是很頻繁的資料,會繞過快取,直接到記憶體中讀取。所以不是每次都能從快取中得到資料,這就是快取的命中率,能夠從快取中讀取就命中,否則就沒命中。
關於快取的命中率又是一門學問,哪些資料保留在快取,哪些資料不保留,都有複雜的演算法。
注意:上面所說的CPU是指CPU核心,從市場上購買的CPU已是封裝好的套件,附帶了暫存器和快取,插到主機板上就可以用。
從經濟和速度的綜合考慮,快取又被分為一級快取、二級快取和三級快取,它們的存取速度和價格依次降低,容量依次增加。購買到的CPU一般會標出三級快取的容量。
register 變數
暫存器的數量是有限的,通常是把使用最頻繁的變數定義為 register 的。
來看一個計算 π 的近似值的例子,求解的一個近似公式如下:
為了提高精度,迴圈的次數越多越好,可以將迴圈的增量控制定義為暫存器變數,如下所示:
#include <stdio.h> #include <conio.h> int main() { register int i = 0; // 暫存器變數 double sign = 1.0, res = 0, ad = 1.0; for(i=1; i<=100000000; i++) { res += ad; sign=-sign; ad=sign/(2*i+1); } res *= 4; printf("pi is %f", res); getch(); return 0; }
執行結果:
pi is 3.141593
關於暫存器變數有以下事項需要注意:
1) 為暫存器變數分配暫存器是動態完成的,因此,只有區域性變數和形式引數才能定義為暫存器變數。
2) 區域性靜態變數不能定義為暫存器變數,因為一個變數只能宣告為一種儲存類別。
3) 暫存器的長度一般和機器的字長一致,所以,只有較短的型別如int、char、short等才適合定義為暫存器變數,諸如double等較大的型別,不推薦將其定義為暫存器型別。
4) CPU的暫存器數目有限,因此,即使定義了暫存器變數,編譯器可能並不真正為其分配暫存器,而是將其當做普通的auto變數來對待,為其分配棧記憶體。當然,有些優秀的編譯器,能自動識別使用頻繁的變數,如迴圈控制變數等,在有可用的暫存器時,即使沒有使用 register 關鍵字,也自動為其分配暫存器,無須由程式設計師來指定。
相關推薦
轉載 C語言中register型別的變數有什麼意義
一般情況下,變數的值是儲存在記憶體中的,CPU 每次使用資料都要從記憶體中讀取。如果有一些變數使用非常頻繁,從記憶體中讀取就會消耗很多時間,例如 for 迴圈中的增量控制: int i; for(i=0; i<1000; i++){ // Some C
C語言中register型別的變數有什麼意義
一般情況下,變數的值是儲存在記憶體中的,CPU 每次使用資料都要從記憶體中讀取。如果有一些變數使用非常頻繁,從記憶體中讀取就會消耗很多時間,例如 for 迴圈中的增量控制: int i; for(i=0; i<1000; i++){ // Some Cod
c語言中const 型別變數地址賦值給指標。
const在C語言中是表示道義上保證變數的值不會被修改,並不能實際阻止修改,通過指標可以修改常變數的值,但是會出現一些不可知的結果。幾種情況不同,我們一個一個來看。 1、直接賦值 const int a = 3; a = 5; // const.c:6:2: error: assignment of read
C語言中static全域性變數與普通的全域性變數區別
下面是中興通訊2012校招筆試題的一道問答題: 1. static全域性變數與普通的全域性變數有什麼區別 ? 全域性變數(外部變數)的說明之前再冠以static 就構成了靜態的全域性變數。 全域性變數本身就是靜態儲存方式, 靜態全域性變數當然也是靜態儲存方式。 這兩者在儲存方式上
C語言中 char 型別的取值範圍為什麼是-128~127
我們之前已經說過關於原碼、反碼和補碼的一些東西,如果你沒有看過,可以點這裡《 你知道原碼、反碼和補碼嗎,進來了解一下吧 》看一下 。 好了,可能你不會太想看,所以我們一起再來簡單的複習一下,如果我們現在有一個十進位制的整數 1 ,我們知道 1 個位元組等於 8 位,
C語言中的static變數
歡迎交流 E-mail:ce123#126.com(#->@) QQ:350725201 嵌入式開發交流群: (1)280352802(已滿) (2)289195589 宣告:版權所有,歡迎轉載! 轉載請註明出處:http://blog.csdn.net/ce123
C語言中‘,’運算子存在的意義
逗號運算子(‘,’)是C語言中優先順序最低的運算子,它用於連線兩個表示式(n-1個‘,’可以連線n個表示式)並從左至右執行表示式,最後一個表示式的值作為整個表示式的值。基本格式如下: 表示式1,表示式2,表示式3…,表示式n 舉個例子: #incl
C語言中,變數的儲存型別有幾種?
在C語言中,對變數的儲存型別說明有以下四種: auto 自動變數 register 暫存器變數 extern 外部變數 static 靜態變數
【轉載】在C語言中,double、long、unsigned、int、char類型數據所占字節數
src 有關 指針變量 none nbsp ide iso isp cli 和機器字長及編譯器有關系: 所以,int,long int,short int的寬度都可能隨編譯器而異。但有幾條鐵定的原則(ANSI/ISO制訂的): 1 sizeof(short int)&
C語言中%p,%u,%lu都有什麽用處
整型 end sig 語言 進制 clas 長整型 sign ext %p表示輸出這個指針, %d表示後面的輸出類型為有符號的10進制整形, %u表示無符號10進制整型, %lu表示輸出無符號長整型整數 (long unsigned)C語言中%p,%u,%lu都有什麽用處
C語言中%d,%p,%u,%lu等都有什麽用處
abc 16進制 body def 進制數 什麽 整形 無符號 進制 %d 有符號10進制整數(%ld 長整型,%hd短整型 )%hu 無符號短整形(%u無符號整形,%lu無符號長整形)%i 有符號10進制整數 (%i 和%d 沒有區別,%i 是老式寫法,都是
C語言中的struct和typedef struct<轉載>
對象 內部數據 編程 都是 內部 pre title HR 聲明 原文:http://www.nowamagic.net/librarys/veda/detail/1785 typedef為C語言的關鍵字,作用是為一種數據類型定義一個新名字。這裏的數據類型包括內部數據類
【轉載】C語言中的static 詳細分析
google了近三頁的關於C語言中static的內容,發現可用的資訊很少,要麼長篇大論不知所云要麼在關鍵之處幾個字略過,對於想挖掘底層原理的初學者來說參考性不是很大。所以,我這篇博文博採眾家之長,把網際網路上的資料整合歸類,並親手編寫程式驗證之。
C語言中int到float的強制型別轉換
最近在看一本名為的書。由於我所看過的計算機理論方面的書較少,加上自己大學期間一直也不用功,所以對於計算機的工作原理以及程式的工作方式我始終只知甚少,印象也十分模糊。 不過,應該說我碰到了一本好書。至少,通過昨晚對浮點數一章的閱讀(呃...我的確之前對浮點數從沒弄明白過),
C語言中exit(0)與exit(1)有什麼區別
今天天氣有點冷,當我在寫訊息佇列的程式的時候,遇到了結束程序的這個問題,突然腦海裡有點混亂,我是用_exit(),還是用exit(1),還是用exit(0)呢,然後自己度娘了一下,整理了一下稍微做
C語言中,為什麼字串可以賦值給字元指標變數
1.以字串形式出現的,編譯器都會為該字串自動新增一個0作為結束符,如在程式碼中寫 "abc",那麼編譯器幫你儲存的是"abc\0" 2."abc"是常量嗎?答案是有時是,有時不是。 不是常量的情況:"abc"作為字元陣列初始值的時候就不是,如 char str[] = "
C語言中printf和scanf函式基本的引數型別和輸出形式
printf函式的引數型別和輸出形式 字元 引數型別 輸出形式 d,i int 十進位制數 o int 無符號八進位制數(不含前導0) x,X int 無符號十六進位制數(沒有前
在C語言中,int ,char 等幾種資料型別所佔用的空間
在32位處理器中,int a; sizeof(a)=4;char a; sizeof(a)=1;float a; sizeof(a)=4;double a; sizeof(a)=8;long a; sizeof(a)=4;long int a; sizeof(a)=4;s
c語言中32為地址型別轉換為64位整數型別
uint64_t idt_operand = ((sizeof(idt) - 1) | ((uint64_t)(uint32_t)idt << 16)); idt是陣列名,也就是結構陣列型別的指標。static struct gate_desc idt[IDT
C語言中被static修飾的函式或變數
被static修飾的函式可認為是“區域性函式”,只能被本原始碼檔案訪問。而沒有static關鍵字的函式可認為是全域性函式(可在函式前寫上extern,此關鍵字是預設的,所以可不寫),可跨檔案被訪問。st