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

2.5 指針與絕對地址訪問

2.5.1 指針

存儲區中每一個字節有一個編號,這就是“地址”,它相當于賓館的房間號。在地址所標志的單元存放數據,這相當于賓館中各房間中住客人一樣。C語言根據定義的變量類型,編譯時給變量分配了相應的存儲空間,不僅分配了變量所占字節的多少,還把變量名與字節地址建立了一一對應關系。

一個變量的地址稱為該變量的“指針”,如:

  

假設i存儲在外部RAM2000H與2001H單元中,則2000為變量i的指針。

如果有一個變量專門用來存放另一變量的地址(即指針),則稱它為“指針變量”。

①直接尋址方式:按變量地址存取變量的方式。

②間接尋址方式:假設我們定義了變量i_pointer是存放整型變量的地址的,它被分配為3010、3011字節,可以通過下面語句將i的地址存放到i_pointer中。

  

假若整型變量i的起始地址為2000H,則i_pointer的值為2000。這時,要存取變量i的值,可以先找到存放“i的地址”單元地址(3000、3011),從中取出i的地址(2000),然后到2000、2001字節取出i的值。

Keil C51中指針變量的定義有如下兩種格式:

(1)數據類型 *[存儲區域]變量名;

例如:

  

說明:

①符號“*”表示該變量為指針變量。如上面所定義的,指針變量名是ptr、Xptr、Dptr、Cptr,而不是*ptr、*Xptr、*Dptr、*Cptr。

②可以用一個賦值語使一個指針變量指向一個變量,如:

  

③用符號“*”表示“指向”,②中所定義的pointer_1代表指針變量,而*pointer_1是pointer_1所指向的變量。*pointer_1也是代表一個變量,它和變量i是同一回事。下面兩個語句作用相同:

  

④一個指針變量只能指向同一類型的變量。例如,Dptr不能忽而指向一個整型變量,忽而指向一個實型變量。因此必須規定指針變量所指向的變量類型。上面定義中,表示Dptr所指向的變量只能是整型變量。

⑤指針變量中只能存放地址(指針),不要將一個整型量(或任何其他非地址類型的數據)賦給一個指針變量。下面的賦值是不合法的:

  

對例2-11的說明:

①在開頭處雖然定義了兩個指針變量pointer_1和pointer_2,但它們并未指向任何一個整型變量。只是提供兩個指針變量,規定它們可以指向整型變量。至于指向哪一個整型變量,要在程序語句中指定。程序第6、7行的作用就是使pointer_1指向a,pointer_2指向b,此時pointer_1的值為&a(即a的地址),pointer_2的值為&b。

②最后一行的*pointer_1和*pointer_2就是變量a和b。

③程序中有兩處出現*pointer_1和*pointer_2,請區分它們的不同含義。程序第3行的*pointer_1和*pointer_2表示定義兩個指針變量pointer_1、pointer_2。它們前面的“*”只是表示該變量是指針變量。程序最后一行printf函數中的*pointer_1和*pointer_2則代表變量,即pointer_1和pointer_2所指向的變量。

④第6、7行“pointer_1=&a;”和“pointer_2=&b;”是將a和b的地址分別賦給pointer_1和pointer_2。注意不應寫成“pointer_1=&a;”和“pointer_2=&b;”。因為a的地址是賦給指針變量pointer_1,而不是賦給*pointer_1。

  

下面對“&”和“*”運算符再做些說明:

①如果已執行了“pointer_1=&a;”語句,若有&* pointer_1,它的含義是什么?“&”和“*”兩個運算符的優先級別相同,但按自右而左方向結合,因此先進行* pointer_1的運算,它就是變量a,再執行&運算。因此,&* pointer_1與&a相同。如果有“pointer_2=&*pointer_1;”。它的作用是將&a(a的地址)賦給pointer_2,如果pointer_2原來指向b,現在已不再指向b而也指向a了。

②*&a的含義是什么?先進行&a運算,得a的地址,再進行*運算。即&a所指向的變量,*&a和* pointer_1的作用是一樣的(假設已執行了“pointer_1=&a;”),它們等價于變量a。即*&a與a等價。

③(* pointer_1)++相當于a++。注意括號是必要的,如果沒有括號,就成為了*(pointer_1++),這時先按pointer_1的原值進行*運算,得到a的值。然后使pointer_1的值改變,這樣pointer_1不再指向a了。

【例2-13】輸入a和b兩個整數,按先大后小的順序輸出a和b。

  

(2)數據類型[存儲區域1]*[存儲區域2]變量名;

其中,“存儲區域1”為指針所指向變量的存儲區域;“存儲區域2”為指針本身的存儲區域。例如:

  

2.5.2 絕對地址的訪問

Keil C51語言允許在程序中指定變量存儲的絕對地址,常用的絕對地址的定義方法有兩種:采用關鍵字“_at_”定義變量的絕對地址;采用存儲器指針指定變量的絕對地址。

(1)采用關鍵字_at_

用關鍵字“_at_”定義變量的絕對地址的一般格式:

數據類型[存儲區域]標識符_at_地址常數

例如:int xdata FLAG_at_0x8000;//int型變量FLAG存儲在片外RAM中,首地址為0x8000。

利用“_at_”定義的變量稱為“絕對變量”。由于對絕對變量的操作就是對存儲區域絕對地址的直接操作,因此在使用絕對變量時應注意以下問題。

①絕對變量必須是全局變量,即只能在函數外部定義。

②絕對變量不能被初始化。

③函數及bit型變量不能用“_at_”進行絕對地址定位。

(2)采用存儲器指針

利用存儲器指針也可以指定變量的絕對存儲地址,其方法是先定義一個存儲器指針變量,然后對該變量賦以指定存儲區域的絕對地址值。

【例2-14】利用存儲器指針進行變量的絕對地址定位。

  

主站蜘蛛池模板: 孝感市| 新宾| 逊克县| 三台县| 兰州市| 汾阳市| 常宁市| 宁陕县| 丽水市| 伽师县| 大庆市| 永登县| 滁州市| 岑溪市| 论坛| 宁都县| 麻城市| 迭部县| 娄烦县| 霍林郭勒市| 黄龙县| 宁安市| 吉林市| 贵溪市| 吴江市| 炎陵县| 蕲春县| 无极县| 磴口县| 罗城| 班戈县| 三台县| 牟定县| 抚州市| 台江县| 若尔盖县| 镇平县| 鄂尔多斯市| 镇雄县| 安福县| 常州市|