官术网_书友最值得收藏!

建議8-4:盡量少使用register變量

前面內(nèi)容就已經(jīng)闡述過,計算機(jī)中保存變量當(dāng)前值的存儲單元有兩類:一類是內(nèi)存,另一類是CPU的寄存器,而register變量則將其值存儲到CPU的寄存器中。通常,寄存器變量比存儲于內(nèi)存的變量訪問效率更高。但是,編譯器并不一定會理睬register關(guān)鍵字,如果有太多的變量被聲明為register,它只會選取前幾個實際存儲于寄存器中,其余的就按普通變量進(jìn)行處理。如果一個編譯器自己具有一套寄存器優(yōu)化方法,它也可能會忽略register關(guān)鍵字,其依據(jù)是由編譯器決定哪些變量存儲于寄存器中要比人腦決定更為合理一些。

在典型情況下,通常會希望把使用頻率更高的那些變量聲明為寄存器變量。在有些計算機(jī)中,如果把指針變量聲明為寄存器變量,程序的效率將能得到提高,尤其是那些頻繁執(zhí)行間接訪問操作的指針。你也可以把函數(shù)的形式參數(shù)聲明為寄存器變量,這樣編譯器會在函數(shù)的起始位置生成指令,然后把這些值從內(nèi)存復(fù)制到寄存器中。但是,完全有可能這個優(yōu)化措施所節(jié)省的時間和空間的開銷還抵不上復(fù)制這幾個值所花的開銷。

register變量的使用示例如代碼清單1-29所示。

代碼清單1-29 register變量的使用示例


#include <stdio.h>
size_t fac(size_t n);
int main(void)
{
    size_t i;
    for(i=1;i<=5;i++)
    {
            printf("%d! = %d\n",i,fac(i));
    }
    return 0;
}
size_t fac(size_t n)
{
    register size_t result=1;
    register size_t i=1;
    for(i=1;i<=n;i++)
    {
            result=result*i;
    }
    return result;
}

在代碼清單1-29中,我們在fac函數(shù)中實現(xiàn)了階乘功能。因為fac函數(shù)中的變量result與i需要在for循環(huán)中反復(fù)調(diào)用,所以這里把它們定義成寄存器變量。其運(yùn)行結(jié)果如圖1-43所示。

寄存器變量的創(chuàng)建和銷毀時間與自動變量相同,但它需要做一些額外的工作。在一個使用寄存器變量的函數(shù)返回之前,這些寄存器必須恢復(fù)先前所存儲的值,確保調(diào)用者的寄存器變量未被破壞。許多機(jī)器使用運(yùn)行時堆棧來完成這個任務(wù)。當(dāng)函數(shù)開始執(zhí)行時,它把需要使用的所有寄存器的內(nèi)容都保存到內(nèi)存中,當(dāng)函數(shù)返回時,這些值會再復(fù)制到寄存器中。

圖1-43 代碼清單1-29的運(yùn)行結(jié)果

值得注意的是,在許多機(jī)器的硬件實現(xiàn)中,并不會為寄存器指定地址。同樣,某個特定的寄存器在不同的時刻所保存的值也不一定相同。基于這些原因,機(jī)器并不會向你提供寄存器變量的地址。因此,在C語言中,你不能夠通過“&”操作符來訪問register變量的地址。

最后,在使用register變量時,還需要注意如下幾個方面:

□ 只有局部自動變量和形式參數(shù)可以作為寄存器變量,否則將會導(dǎo)致無法編譯。

□ 一個計算機(jī)系統(tǒng)中的寄存器數(shù)目有限,不能定義任意多個寄存器變量。

□ 局部靜態(tài)變量不能定義為寄存器變量。

□ register變量一般只對整型和字符型數(shù)據(jù)有用。

□ 不能使用取地址運(yùn)算符“&”求寄存器變量的地址。

主站蜘蛛池模板: 海林市| 突泉县| 明光市| 吉首市| 葵青区| 宝坻区| 界首市| 平度市| 财经| 丹东市| 奉贤区| 桐城市| 宁阳县| 孝感市| 桃源县| 赫章县| 霍城县| 克拉玛依市| 麻阳| 普定县| 紫金县| 措美县| 辉南县| 洪湖市| 滨海县| 满洲里市| 如皋市| 襄汾县| 蒙自县| 贵南县| 万全县| 广灵县| 榆中县| 商都县| 科技| 项城市| 潢川县| 靖边县| 寿阳县| 台东市| 宁阳县|