對應(yīng)值實(shí)際上就是指針?biāo)成涞?/font>3字寄存器數(shù)值。
結(jié)合程序③編譯分析,當(dāng)需要引用某物理地址內(nèi)數(shù)據(jù)時(shí),會(huì)調(diào)用“C?CLDPTR”函數(shù),函數(shù)功能就是根據(jù)這些賦值確定使用何種尋址方式引用數(shù)據(jù)。而這一過程包括“C?CLDPTR”函數(shù)都是編譯器自動(dòng)完成的。
在匯編語言中,R1寄存器可以用于間接尋址,如:MOV A,@R1。不能寫為MOV A,@12H。因此在程序③中,將變量p對應(yīng)的3字節(jié)數(shù)據(jù)賦值給R3、R2、R1。
綜上所述,Keil C-51編譯環(huán)境下,指針是一個(gè)占3字節(jié)的特殊變量,編譯器編譯程序時(shí),自動(dòng)生成判斷尋址方式的子函數(shù),并根據(jù)根據(jù)目標(biāo)數(shù)據(jù)所在的物理存儲(chǔ)區(qū)不同,為指針首字節(jié)賦值,根據(jù)賦值的不同,進(jìn)行不同方式的尋址;指針的后2字節(jié),用于存放引用的地址。
調(diào)試訓(xùn)練:
下面的程序編譯器會(huì)怎樣編譯?與程序③有何不同?請根據(jù)程序③和程序④的分析方式分析程序⑤的執(zhí)行結(jié)果。
程序⑤
#include "REG52.H"
unsigned char tab1[8];
unsigned char codetab2[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
unsigned char *p;
void main()
{
unsignedchar i;
p=tab1;
for(i=0;i<8;i++,p++)
*p=i;
p=tab2;
for(i=0;i<8;i++,p++)
*p=i;
}
思考:下列語句中:
p=tab2;
for(i=0;i<8;i++,p++)
*p=i;
執(zhí)行完for循環(huán)后,tab2數(shù)組內(nèi)的值會(huì)改變嗎?為什么?
4、指針意義
在匯編編程中,由于單片機(jī)數(shù)據(jù)存放的物理存儲(chǔ)區(qū)不同,導(dǎo)致有不同的尋址方式,用戶進(jìn)行必須根據(jù)這一規(guī)律設(shè)計(jì)程序。而在C語言中,不管目標(biāo)數(shù)據(jù)所在的物理存儲(chǔ)區(qū)如何,指針都可指向該地址,并自動(dòng)編譯尋址方式。
但指針并不是萬能的,如程序⑤中:
p=tab2;
for(i=0;i<8;i++,p++)
*p=i;
這些語句編譯時(shí)并不會(huì)報(bào)錯(cuò),但卻不能實(shí)現(xiàn)功能,因?yàn)?/font>tab2數(shù)組是定義在程序存儲(chǔ)器(ROM)的常量數(shù)組,ROM內(nèi)的數(shù)據(jù)更改是不能通過這種方式實(shí)現(xiàn)的。因此,當(dāng)用戶不明確單片機(jī)的物理存儲(chǔ)區(qū)特性時(shí),使用指針會(huì)容易出錯(cuò)。先將程序⑤中的主函數(shù)語句做如下修改,得到程序⑥:
#include"REG52.H"
unsignedchar tab1[8];
unsignedchar code tab2[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
unsignedchar *p;
voidmain()
{
unsigned char i;
for(i=0;i<8;i++,p++)
tab1[ i]=i;
for(i=0;i<8;i++,p++)
tab2[ i]=i;
}
單獨(dú)看第一個(gè)for循環(huán),可實(shí)現(xiàn)與程序⑤一樣的效果,即tab1數(shù)組內(nèi)被賦值為:0,1,2,3,4,5,6,7。
第二個(gè)for循環(huán)從語句上可認(rèn)為是與程序⑤功能相同,但實(shí)際上,不管是程序⑤還是程序⑥,都不能實(shí)現(xiàn)對tab2數(shù)組的賦值。但在程序⑥中,編譯器會(huì)提示錯(cuò)誤,如圖12所示。
因此,指針的使用不當(dāng),不僅會(huì)帶來程序運(yùn)行結(jié)果的不正確,同時(shí)也難以發(fā)現(xiàn)這些錯(cuò)誤。
對比程序⑤和程序⑥中的兩段程序:
p=tab1; for(i=0;i<8;i++,p++)
for(i=0;i<8;i++,p++) tab1[ i]=i;
*p=i;
它們執(zhí)行的結(jié)果是一樣的,那么哪種更好呢?對于初學(xué)者來說,顯然是后者,因?yàn)楹笳吒子诶斫獬绦蚝x,而前者必須要理解指針在此處的作用;那么對于有經(jīng)驗(yàn)的程序員呢?也是后者,因?yàn)槌绦驁?zhí)行效率上,后者也要大于前者,因?yàn)槌绦颌菰诰幾g過程中,編譯器始終會(huì)生成一個(gè)子函數(shù)用于確定尋址方式,再賦值;程序⑥則是直接確定了尋址方式執(zhí)并行進(jìn)行賦值。盡管執(zhí)行效率的降低在接受范圍內(nèi),但對于一個(gè)簡單、明了的功能來說,用簡單的方式實(shí)現(xiàn)要比復(fù)雜方式合理。
設(shè)計(jì)者在程序中使用指針的目的往往是讓程序具有可移植性,但8051單片機(jī)的功能是有限的,它實(shí)現(xiàn)的功能相對固化,如時(shí)間顯示、數(shù)據(jù)采集等等,這些功能確定后,幾乎不會(huì)做出更改,基于此特點(diǎn),8051單片機(jī)的代碼代碼量都不長。因此即便是不同構(gòu)架的單片機(jī)程序互相移植,代碼的修改并不復(fù)雜,移植過程中,也幾乎都是針對不同構(gòu)架單片機(jī)的I/O工作方式不同、指令周期不同做常規(guī)修改;或是關(guān)鍵字的修改。因此合理的設(shè)計(jì)單片機(jī)程序,盡可能的提高程序的效率、穩(wěn)定性、可閱讀性才是程序設(shè)計(jì)的核心主旨。指針在8051單片機(jī)中固然可以使用,但并不能說明指針的使用就一定是高效、準(zhǔn)確、易于他人理解。
作者: absflash 時(shí)間: 2015-10-30 20:37
圖文并茂,做的漂亮
作者: cvgjhuor 時(shí)間: 2017-9-23 19:45
這么詳細(xì),真的很漂亮
作者: toveyxin 時(shí)間: 2018-1-18 13:36
受益匪淺呀
作者: hyz5122 時(shí)間: 2019-9-7 10:31
很不錯(cuò)的文章。。!
作者: mdy0712 時(shí)間: 2019-9-8 02:32
指針是C語言的靈魂,F(xiàn)在還體會(huì)不到它的好處,慢慢來,應(yīng)該是有用的
作者: 鵬博士PBs 時(shí)間: 2019-9-9 07:30
指針變量
作者: zxy2266 時(shí)間: 2019-9-11 19:12
太詳細(xì)了,我學(xué)51只是點(diǎn)皮毛,以前對變化的顯示不理解,原來都是指針的作用
作者: QQ572008555 時(shí)間: 2020-2-18 23:41
看到一半 后面的有些看不懂了 慢慢學(xué) 收藏了
作者: 哈哈哈大西瓜 時(shí)間: 2020-4-2 22:52
感謝作者
作者: m199629 時(shí)間: 2021-1-27 08:44
大佬,圖文并茂很詳細(xì)
作者: 51mcu學(xué)習(xí) 時(shí)間: 2021-1-28 16:24
好教程,回頭學(xué)指針再慢慢看和研究
作者: 51mcu學(xué)習(xí) 時(shí)間: 2021-1-28 16:25
聽說指針比較難懂
| 歡迎光臨 (http://m.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |