單片機(jī)八語言編程_第1頁
單片機(jī)八語言編程_第2頁
單片機(jī)八語言編程_第3頁
單片機(jī)八語言編程_第4頁
單片機(jī)八語言編程_第5頁
已閱讀5頁,還剩131頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

單片機(jī)八語言編程第一頁,共一百三十七頁,2022年,8月28日第3章51單片機(jī)編程語言3.1單片機(jī)編程語言概述3.2 C51語言第二頁,共一百三十七頁,2022年,8月28日3.1單片機(jī)編程語言概述

51單片機(jī)的編程語言可以是匯編語言,也可以是高級(jí)語言,如由C語言演變而成的C51語言等。匯編語言產(chǎn)生的目標(biāo)代碼短,占用的存儲(chǔ)空間小,執(zhí)行速度快,能充分發(fā)揮單片機(jī)的硬件功能。但對(duì)于復(fù)雜的應(yīng)用來講使用匯編語言編程復(fù)雜,程序的可讀性和可移植性不強(qiáng)。高級(jí)語言產(chǎn)生的目標(biāo)代碼長,占用的存儲(chǔ)空間大,執(zhí)行速度慢。但這是相對(duì)于匯編語言來講的,其實(shí)C語言在大多數(shù)情況下的機(jī)器代碼生成效率和匯編語言相當(dāng),但可讀性和可移植性卻遠(yuǎn)遠(yuǎn)超過匯編語言,編程效率也大大高于匯編語言。

第三頁,共一百三十七頁,2022年,8月28日3.1單片機(jī)編程語言概述如果應(yīng)用系統(tǒng)的存儲(chǔ)空間比較小,且對(duì)實(shí)時(shí)性的要求很高,則應(yīng)選用匯編語言編程。如果系統(tǒng)的存儲(chǔ)空間比較大,且對(duì)實(shí)時(shí)性的要求不是很高,則C51語言是理想的編程語言。如果系統(tǒng)中有部分模塊對(duì)實(shí)時(shí)性的要求很高,而其它模塊對(duì)實(shí)時(shí)性的要求不是很高,則可以將兩種語言結(jié)合,程序的主體部分使用C51編程,對(duì)實(shí)時(shí)性的要求高的模塊用匯編語言編程,然后將匯編語言程序模塊嵌入到C51語言程序當(dāng)中。無論是高級(jí)語言還是匯編語言寫的源程序都必須轉(zhuǎn)換成目標(biāo)程序(機(jī)器語言),單片機(jī)才能執(zhí)行。目前很多公司都將編輯器、匯編器、編譯器、連接/定位器、符號(hào)轉(zhuǎn)換程序做成了軟件包,稱為集成開發(fā)環(huán)境,如KeiluVision、SiliconLaboratoriesIDE等。第四頁,共一百三十七頁,2022年,8月28日3.2 C51語言早期的嵌入式系統(tǒng)的硬件的功能相對(duì)較弱,軟件的規(guī)模相對(duì)較小,一般不超過8K。硬件工程師通常要同時(shí)進(jìn)行軟、硬件設(shè)計(jì),所以一般采用匯編語言來進(jìn)行程序設(shè)計(jì)。匯編程序的主要缺點(diǎn)是可讀性和可維護(hù)性較差(特別當(dāng)程序沒有很好的進(jìn)行注釋時(shí)),代碼的可重用性也比較低。目前的嵌入式系統(tǒng)硬件性能和軟件的規(guī)模都有了很大的提高,一般采用C語言進(jìn)行嵌入式系統(tǒng)程序設(shè)計(jì)。第五頁,共一百三十七頁,2022年,8月28日使用C語言有以下的優(yōu)點(diǎn):C語言具有結(jié)構(gòu)化和模塊化特點(diǎn),便于閱讀和維護(hù)。C語言可移植性好,很多微控制器都支持C編譯器。功能化的代碼能夠很方便的從一個(gè)工程移植到另一個(gè)工程,從而減少了開發(fā)時(shí)間。C語言編寫的程序比匯編語言編寫的程序更符合人們的思考習(xí)慣,開發(fā)者可以更專心的考慮算法,而不是考慮一些細(xì)節(jié)問題。這樣可以減少編程錯(cuò)誤出現(xiàn)的機(jī)率,從而提高開發(fā)效率,減少調(diào)試的時(shí)間。C語言和微控制器是相對(duì)獨(dú)立的,開發(fā)者不必知道處理器的具體內(nèi)部結(jié)構(gòu)和處理過程。當(dāng)基于新型的微控制器開發(fā)程序時(shí),可以很快上手,減少學(xué)習(xí)時(shí)間和程序開發(fā)時(shí)間。第六頁,共一百三十七頁,2022年,8月28日盡管C語言有以上的優(yōu)點(diǎn),但這并不是說匯編語言過時(shí)了。很多系統(tǒng)特別是實(shí)時(shí)嵌入式系統(tǒng)都是采用C和匯編語言進(jìn)行混合編程。對(duì)實(shí)時(shí)響應(yīng)時(shí)間有很嚴(yán)格要求的應(yīng)用系統(tǒng),使用匯編語言成了開發(fā)者的唯一選擇。C51語言是一種專門為8051單片機(jī)設(shè)計(jì)的高級(jí)語言C編譯器,支持符合ANSI標(biāo)準(zhǔn)的C語言程序設(shè)計(jì),同時(shí)針對(duì)8051單片機(jī)的自身特點(diǎn)做了一些特殊擴(kuò)展。如果有C/C++語言的基礎(chǔ),C51語言能夠很快掌握!第七頁,共一百三十七頁,2022年,8月28日

標(biāo)識(shí)符、關(guān)鍵字標(biāo)識(shí)符與關(guān)鍵字是C語言的基本組成部分。

標(biāo)識(shí)符C語言中的標(biāo)識(shí)符(identifier)是由一個(gè)或多個(gè)字符組成的序列,標(biāo)識(shí)符可以作為變量名、函數(shù)名、數(shù)組名、類型名或文件名。標(biāo)識(shí)符的第一個(gè)字符必須是字母或下劃線,隨后的字符必須是字母、數(shù)字或下劃線。不同的編譯器定義的標(biāo)識(shí)符的有效長度不完全相同,但不會(huì)少于8個(gè)字符。為了程序移植方便,標(biāo)識(shí)符的長度最好不超過8個(gè)字符。注意1:C語言區(qū)分字母的大小寫,這和匯編語言是不同的。例如:var

和Var是兩個(gè)不同的標(biāo)識(shí)符。注意2:C51編譯器6.0以上版本支持標(biāo)識(shí)符的有效長度為256,超過部分忽略。第八頁,共一百三十七頁,2022年,8月28日

關(guān)鍵字關(guān)鍵字(keyword)是一種具有固定名稱和特定含義的標(biāo)識(shí)符,又稱為保留字(reservedword)。這些標(biāo)識(shí)符系統(tǒng)已經(jīng)做了定義,有特定的功能。用戶自定義的標(biāo)識(shí)符不能和關(guān)鍵字同名。ANSIC語言定義了32個(gè)關(guān)鍵字。第九頁,共一百三十七頁,2022年,8月28日ANSIC關(guān)鍵字autodogotosignedunsignedbreakdoubleifsizeofvoidcaseelseintstaticvolatilecharenumlongstructwhileconstexternregisterswitchcontinuefloatreturntypedefdefaultforshortunion第十頁,共一百三十七頁,2022年,8月28日ANSIC關(guān)鍵字■程序控制語句:

breakcasecontinuedefaultdoelseforgotoifreturnswitchvolatilewhile■存儲(chǔ)種類說明:

autoconstexternregisterstatic■數(shù)據(jù)類型說明:

chardoubleenumfloatintlongshortsignedstructtypedefunionunsignedvoid■運(yùn)算符:

sizeof第十一頁,共一百三十七頁,2022年,8月28日擴(kuò)展關(guān)鍵字命令作用include讀外部文件,用<>指向包含文件目錄中的文件,用“”指向當(dāng)前目錄中的文件define定義預(yù)處理宏或常數(shù)undef撤銷預(yù)處理宏或常數(shù)定義if條件編譯判斷,若表達(dá)式為真,則開始條件編譯分支ifdef條件編譯判斷,若命名已經(jīng)定義,則開始條件編譯分支ifndef條件編譯判斷,若命名未定義,則開始條件編譯分支elif如果此前的if、ifdef、ifndef或elif未發(fā)生,并且表達(dá)式為真,則開始條件編譯else如果此前的if、ifdef、ifndef或elif未發(fā)生,則開始條件編譯endif結(jié)束此前的if、ifdef、ifndef、elif或else開始的條件編譯分支。error輸出用戶定義的出錯(cuò)消息分支line說明行號(hào)和可選的文件名,常用于出錯(cuò)消息中說明出錯(cuò)位置pragma說明編譯命令,可以是命令行形式中的編譯參數(shù)第十二頁,共一百三十七頁,2022年,8月28日C51關(guān)鍵字關(guān)鍵字用途說明_at_地址定位為變量進(jìn)行存儲(chǔ)器絕對(duì)空間地址定位alien函數(shù)特性聲明用以聲明與PL/M51兼容的函數(shù)bdata存儲(chǔ)器類型聲明可位尋址的8051內(nèi)部數(shù)據(jù)存儲(chǔ)器bit位變量聲明聲明位變量或位類型函數(shù)code存儲(chǔ)器類型聲明8051程序存儲(chǔ)器空間compact存儲(chǔ)器模式指定使用8051外部分頁尋址數(shù)據(jù)存儲(chǔ)空間data存儲(chǔ)器類型聲明直接尋址的8051內(nèi)部數(shù)據(jù)存儲(chǔ)器far存儲(chǔ)器類型聲明8051外部數(shù)據(jù)存儲(chǔ)器idata存儲(chǔ)器類型聲明間接尋址的8051內(nèi)部數(shù)據(jù)存儲(chǔ)器interrupt中斷函數(shù)聲明定義中斷服務(wù)函數(shù)(未完,見下頁)第十三頁,共一百三十七頁,2022年,8月28日C51關(guān)鍵字large存儲(chǔ)器模式指定使用8051外部數(shù)據(jù)存儲(chǔ)空間pdata存儲(chǔ)器類型聲明分頁尋址的8051外部數(shù)據(jù)存儲(chǔ)器_priority_多任務(wù)優(yōu)先聲明規(guī)定RTX51或RTX51Tiny的任務(wù)優(yōu)先級(jí)reentrant可重入函數(shù)聲明定義可重入函數(shù)sbit位變量聲明聲明可位尋址的特殊功能位sfr特殊功能寄存器聲明聲明8位的特殊功能寄存器sfr16特殊功能寄存器聲明聲明16位的特殊功能寄存器small存儲(chǔ)器模式指定使用8051內(nèi)部數(shù)據(jù)存儲(chǔ)空間_task_任務(wù)聲明定義實(shí)時(shí)多任務(wù)函數(shù)using寄存器組定義定義8051的工作寄存器組xdata存儲(chǔ)器類型聲明8051外部數(shù)據(jù)存儲(chǔ)器第十四頁,共一百三十七頁,2022年,8月28日可重入函數(shù)可重入(reentrant)函數(shù)可以由多于一個(gè)任務(wù)并發(fā)使用,而不必?fù)?dān)心數(shù)據(jù)錯(cuò)誤。相反,不可重入(non-reentrant)函數(shù)不能由超過一個(gè)任務(wù)所共享,除非能確保函數(shù)的互斥(或者使用信號(hào)量,或者在代碼的關(guān)鍵部分禁用中斷)??芍厝牒瘮?shù)可以在任意時(shí)刻被中斷,稍后再繼續(xù)運(yùn)行,不會(huì)丟失數(shù)據(jù)??芍厝牒瘮?shù)要么使用本地變量,要么在使用全局變量時(shí)保護(hù)自己的數(shù)據(jù)可重入函數(shù):不為連續(xù)的調(diào)用持有靜態(tài)數(shù)據(jù)。不返回指向靜態(tài)數(shù)據(jù)的指針;所有數(shù)據(jù)都由函數(shù)的調(diào)用者提供。使用本地?cái)?shù)據(jù),或者通過制作全局?jǐn)?shù)據(jù)的本地拷貝來保護(hù)全局?jǐn)?shù)據(jù)。絕不調(diào)用任何不可重入函數(shù)。第十五頁,共一百三十七頁,2022年,8月28日在C51中,還使用了/**/和//符號(hào)進(jìn)行注釋。在/**/符號(hào)中的所有字符均表示注釋說明。在//符號(hào)后的該行所有剩余文字均表示注釋說明。注釋的語句主要用來說明程序的功能,增加程序的可閱讀性和可維護(hù)性,注釋不影響程序的功能,也不會(huì)在編譯后的程序中出現(xiàn),即不影響運(yùn)行文件的大小。第十六頁,共一百三十七頁,2022年,8月28日

C語言的運(yùn)算符符號(hào)意義說明+加法運(yùn)算或表示正數(shù)-減法運(yùn)算或表示負(fù)數(shù)*乘法運(yùn)算/除法運(yùn)算當(dāng)2個(gè)整數(shù)相除時(shí),結(jié)果為整數(shù),小數(shù)部分舍去。%模運(yùn)算(求余)參加運(yùn)算的均應(yīng)為整數(shù)。++自增操作數(shù)據(jù)值加1--自減操作數(shù)據(jù)值減1第十七頁,共一百三十七頁,2022年,8月28日例:設(shè)x的初值為4y=x++;結(jié)果:x=5,y=4解釋:x++先使用x的值,然后x的值再自增。y=++x;結(jié)果:y=5,x=5解釋:++xx的值先自增,然后再使用x的值。y=x--;結(jié)果:y=4,x=3解釋:x--先使用x的值,然后x的值再自減。y=--x;結(jié)果:y=3,x=3解釋:--xx的值先自減,然后再使用x的值。 第十八頁,共一百三十七頁,2022年,8月28日邏輯運(yùn)算符符號(hào)含義>大于>=大于等于==等于<小于<=小于等于!=不等于&&邏輯與,二個(gè)操作數(shù)均為真時(shí),其值為真,否則為假|(zhì)|邏輯或,二個(gè)操作數(shù)均為假時(shí),其值為假,否則為真!邏輯非,一元運(yùn)算符,操作數(shù)為真,其值為假,操作數(shù)為假,其值為真注意:等于運(yùn)算符用兩個(gè)等號(hào)表示。一個(gè)等號(hào)表示賦值操作。第十九頁,共一百三十七頁,2022年,8月28日位運(yùn)算符符號(hào)含義&按位與|按位或^按位異或~按位取反。一元運(yùn)算符<<左移操作。左邊移出的位舍去,右邊移入的位補(bǔ)0>>右移操作。右邊移出的位舍去,左邊移入的位對(duì)無符號(hào)數(shù)補(bǔ)0;對(duì)有符號(hào)數(shù)補(bǔ)符號(hào)位第二十頁,共一百三十七頁,2022年,8月28日例:unsignedcharx=0x55;

unsignedchary=0x37;unsignedcharz;z=x&y; 則 z=0x15z=x|y; 則 z=0x77z=x^y; 則 z=0x62z=~x; 則 z=0xAAz=x<<2; 則 z=0x54z=x>>1; 則 z=0x2A第二十一頁,共一百三十七頁,2022年,8月28日例:unsignedcharx=0x95;

signedchary=0x95;unsignedcharz;z=x>>1; 則 z=0x4Az=y>>1; 則 z=0xCA第二十二頁,共一百三十七頁,2022年,8月28日賦值運(yùn)算符通常把’=’稱為賦值運(yùn)算符。它是二元運(yùn)算符,左邊必須是個(gè)變量或數(shù)組元素(稱為左值)右邊是表達(dá)式(稱為右值)。當(dāng)左值和右值的數(shù)據(jù)類型不一致時(shí),數(shù)據(jù)會(huì)自動(dòng)進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換。除了’=’之外,C語言還提供了10種復(fù)合賦值運(yùn)算符,它們的功能是對(duì)左值和右值進(jìn)行相關(guān)運(yùn)算后,將運(yùn)算結(jié)果賦給左值。復(fù)合賦值運(yùn)算符如下所示:

+=-=*=/=%=<<=>>= &=^= !=其中前5種是算術(shù)運(yùn)算,后5種是位操作位算。第二十三頁,共一百三十七頁,2022年,8月28日逗號(hào)運(yùn)算符逗號(hào)運(yùn)算符的作用是把幾個(gè)表達(dá)式串在一起,成為逗號(hào)表達(dá)式。 格式如下: 表達(dá)式1,表達(dá)式2,…,表達(dá)式n注意:逗號(hào)運(yùn)算符的運(yùn)算順序是從左至右,最右邊表達(dá)式的值是整個(gè)逗號(hào)表達(dá)式的值。例如:x=(y=5,z=y+3);則該語句執(zhí)行完成后y=5,z=8,x=8。第二十四頁,共一百三十七頁,2022年,8月28日條件運(yùn)算符條件運(yùn)算符用’?’與‘:’來替代簡單的if-else條件語句。該運(yùn)算符是三元運(yùn)算符。 格式如下: 表達(dá)式1?表達(dá)式2:表達(dá)式3該運(yùn)算符的功能是若表達(dá)式1為真,則執(zhí)行表達(dá)式2,否則執(zhí)行表達(dá)式3。例如:z=’a’>’b’?3:5;由于’a’>’b’的值為假,所以z=5。第二十五頁,共一百三十七頁,2022年,8月28日強(qiáng)制類型轉(zhuǎn)換運(yùn)算符在C語言程序的表達(dá)式或變量賦值運(yùn)算中,有時(shí)會(huì)出現(xiàn)運(yùn)算對(duì)象的數(shù)據(jù)類型不一致的情況,C語言允許對(duì)參與操作的標(biāo)準(zhǔn)數(shù)據(jù)類型進(jìn)行隱式轉(zhuǎn)換和顯示轉(zhuǎn)換。隱式轉(zhuǎn)換由系統(tǒng)自動(dòng)按以下優(yōu)先級(jí)進(jìn)行:bit→char→int→long→floatsigned→unsigned其中,箭頭方向僅表示數(shù)據(jù)類型級(jí)別的高低,轉(zhuǎn)換時(shí)由低向高進(jìn)行,而不是數(shù)據(jù)轉(zhuǎn)換時(shí)的順序。例如:char變量和long變量進(jìn)行運(yùn)算,char變量無需先轉(zhuǎn)換為int然后再轉(zhuǎn)換成long,而是直接由char轉(zhuǎn)換成long。第二十六頁,共一百三十七頁,2022年,8月28日某些時(shí)候需要按用戶的需要進(jìn)行某些數(shù)據(jù)類型轉(zhuǎn)換,可使用強(qiáng)制類型轉(zhuǎn)換符進(jìn)行顯式轉(zhuǎn)換。強(qiáng)制轉(zhuǎn)換符的功能是將表達(dá)式結(jié)果轉(zhuǎn)換成指定的數(shù)據(jù)類型,強(qiáng)制類型轉(zhuǎn)換符的運(yùn)算符號(hào)為()。 格式為: (類型名)(表達(dá)式)例如:(int)(7.2/2)將7.2/2的結(jié)果轉(zhuǎn)換為整型,即3。第二十七頁,共一百三十七頁,2022年,8月28日sizeof運(yùn)算符C語言中可以用sizeof運(yùn)算符計(jì)算數(shù)據(jù)類型變量以及表達(dá)式的字節(jié)數(shù)。 它的一般使用形式為:

sizeof(表達(dá)式)或sizeof(數(shù)據(jù)類型)注意:sizeof是一種特殊的運(yùn)算符,不是函數(shù)。實(shí)際上字節(jié)數(shù)的計(jì)算是在程序編譯時(shí)完成的,而不是在程序執(zhí)行的過程中才計(jì)算出來的。第二十八頁,共一百三十七頁,2022年,8月28日其它運(yùn)算符*

: 指針運(yùn)算符。作用是通過指針變量間接訪問指針變量所指向的變量,對(duì)其進(jìn)行數(shù)據(jù)存取操作。&

: 取地址運(yùn)算符。作用是獲取變量所占用的存儲(chǔ)單元的地址。[]

: 下標(biāo)運(yùn)算符。作用是用來獲取數(shù)組的指定單元。->

: 指向結(jié)構(gòu)成員運(yùn)算符。作用是用結(jié)構(gòu)變量的指針來訪問結(jié)構(gòu)中的成員變量。.

: 結(jié)構(gòu)成員運(yùn)算符,作用是用結(jié)構(gòu)變量來訪問結(jié)構(gòu)中的成員變量。第二十九頁,共一百三十七頁,2022年,8月28日運(yùn)算優(yōu)先級(jí)優(yōu)先級(jí)符號(hào)含義運(yùn)算對(duì)象個(gè)數(shù)結(jié)合方向1()圓括號(hào)自左向右[]下標(biāo)運(yùn)算符-> 指向結(jié)構(gòu)成員運(yùn)算符.結(jié)構(gòu)成員運(yùn)算符2!邏輯非運(yùn)算符單操作數(shù)自右向左~按位取反操作符++自增運(yùn)算符--自減運(yùn)算符-負(fù)號(hào)運(yùn)算符(類型)類型轉(zhuǎn)換運(yùn)算符*指針運(yùn)算符&取地址運(yùn)算符sizeof長度運(yùn)算符第三十頁,共一百三十七頁,2022年,8月28日優(yōu)先級(jí)符號(hào)含義運(yùn)算對(duì)象個(gè)數(shù)結(jié)合方向3*乘法運(yùn)算符雙操作符自左向右/除法運(yùn)算符%求余運(yùn)算符4+加法運(yùn)算符雙操作符自左向右-減法運(yùn)算符5<<左移運(yùn)算符雙操作符自左向右>>右移運(yùn)算符6<、<=、>、>=關(guān)系運(yùn)算符雙操作符自左向右7==等于運(yùn)算符雙操作符自左向右!=不等于運(yùn)算符第三十一頁,共一百三十七頁,2022年,8月28日優(yōu)先級(jí)符號(hào)含義運(yùn)算對(duì)象個(gè)數(shù)結(jié)合方向8&按位與運(yùn)算符雙操作符自左向右9^按位異或運(yùn)算符雙操作符自左向右10|按位或運(yùn)算符雙操作符自左向右11&&邏輯與運(yùn)算符雙操作符自左向右12||邏輯或運(yùn)算符雙操作符自左向右13?:條件運(yùn)算符三操作符自右向左14=、+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=賦值運(yùn)算符雙操作符自左向右15,逗號(hào)運(yùn)算符自左向右第三十二頁,共一百三十七頁,2022年,8月28日

數(shù)據(jù)類型C語言中的數(shù)據(jù)根據(jù)是否允許數(shù)據(jù)值在程序執(zhí)行過程中發(fā)生變化,分為常量和變量。常量又稱為標(biāo)量,它的值在程序執(zhí)行過程中不能改變。變量是一種在程序執(zhí)行過程中,其值能不斷變化的量。使用一個(gè)變量前必須進(jìn)行定義。 在C51中變量定義的格式如下:

[存儲(chǔ)種類]數(shù)據(jù)類型[存儲(chǔ)器類型]變量名表;第三十三頁,共一百三十七頁,2022年,8月28日基本數(shù)據(jù)類型C語言的基本數(shù)據(jù)類型有char、int、short、long、float和double。對(duì)C51編譯器來說:short類型與int類型相同double類型與float類型相同。第三十四頁,共一百三十七頁,2022年,8月28日存儲(chǔ)區(qū)域8051系列微處理器采用了哈佛體系結(jié)構(gòu),即程序存儲(chǔ)區(qū)和數(shù)據(jù)存儲(chǔ)區(qū)是分離的。8051系列微處理器提供了三種不同類型的存儲(chǔ)區(qū)域(memoryareas), 程序存儲(chǔ)區(qū)(programmemory) 內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)(internaldatamemory) 外部數(shù)據(jù)存儲(chǔ)區(qū)(externaldatamemory)這三種存儲(chǔ)區(qū)域均從地址0開始編址,通過采用不同的尋址指令來解決地址重疊的問題。第三十五頁,共一百三十七頁,2022年,8月28日第三十六頁,共一百三十七頁,2022年,8月28日程序存儲(chǔ)區(qū)(programmemory)程序存儲(chǔ)區(qū),也稱為CODE區(qū),常用來存放可執(zhí)行代碼。代碼區(qū)的地址位數(shù)為16位,即尋址空間可達(dá)64K。一般情況,程序存儲(chǔ)區(qū)是只讀的,除了保存可執(zhí)行代碼,還可用于保存各種常量值,查找表等固定的數(shù)據(jù)結(jié)構(gòu)。第三十七頁,共一百三十七頁,2022年,8月28日內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)(internaldatamemory)內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)(internaldatamemory),共256個(gè)字節(jié)。這部分主要是作為程序的數(shù)據(jù)段。該區(qū)域的前128字節(jié),稱為DATA區(qū)。該區(qū)可采用直接尋址方式來訪問。DATA區(qū)也可通過用R0和R1存放要操作的數(shù)據(jù)地址,采用間接尋址來訪問。該區(qū)域的后128個(gè)字節(jié),即從地址80H開始的內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū),用做特殊功能寄存器區(qū)(specialfunctionregistermemory),簡稱SFR。這些特殊功能寄存器用來控制計(jì)時(shí)器,計(jì)數(shù)器,串行I/O,I/O端口和外設(shè)的工作。只能直接尋址注意:特殊功能寄存器并未占用特殊功能寄存器區(qū)的所有地址單元,即特殊功能寄存器是離散分布。第三十八頁,共一百三十七頁,2022年,8月28日內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)的DATA區(qū)又可以細(xì)分為三個(gè)子段:第一個(gè)子段包含四個(gè)寄存器組,每個(gè)寄存器組包含8個(gè)寄存器,四個(gè)寄存器組共32個(gè)字節(jié)??稍谌魏螘r(shí)候通過修改PSW寄存器的RS1和RS0兩個(gè)位標(biāo)志來選擇四組寄存器的任意一組作為當(dāng)前工作寄存器組。第二個(gè)子段叫做位尋址段BDATA,包括16個(gè)字節(jié),共128位,每一位都可單獨(dú)尋址。這16個(gè)字節(jié)也可像數(shù)據(jù)段中其它字節(jié)一樣按字節(jié)進(jìn)行尋址。第三個(gè)子段為一般的數(shù)據(jù)存儲(chǔ)器,僅能按字節(jié)尋址,共80個(gè)字節(jié)。第三十九頁,共一百三十七頁,2022年,8月28日說明:某些系列的單片機(jī)(如8052)有額外的128字節(jié)的內(nèi)部RAM,同樣位于從80H開始的內(nèi)部數(shù)據(jù)存儲(chǔ)地址空間中,稱為IDATA區(qū)。IDATA區(qū)的地址和SFR的地址是重疊的,必須使用不同的尋址方式的指令來解決地址重疊問題。SFR區(qū)只能通過直接尋址來訪問,IDATA區(qū)只能通過間接尋址來訪問。第四十頁,共一百三十七頁,2022年,8月28日外部數(shù)據(jù)存儲(chǔ)區(qū)(externaldatamemory)外部數(shù)據(jù)存儲(chǔ)區(qū),也稱為XDATA

區(qū)。XDATA區(qū)和CODE區(qū)一樣也采用16位地址尋址,即尋址空間可達(dá)64KB。該區(qū)通常包括一些通用數(shù)據(jù)存儲(chǔ)器或者一些需要通過總線接口訪問的外圍器件。訪問外部數(shù)據(jù)區(qū)比訪問內(nèi)部數(shù)據(jù)區(qū)要慢,因?yàn)樵L問外部數(shù)據(jù)區(qū)時(shí),必須先將要訪問單元的16位地址裝載到數(shù)據(jù)指針寄存器DPTR中,然后才能通過DPTR采用間接訪問方式來訪問該單元。第四十一頁,共一百三十七頁,2022年,8月28日C51使用兩種修飾符來表示外部數(shù)據(jù)區(qū):xdata,pdataxdata

用來說明外部數(shù)據(jù)空間的所有64KB的地址空間。pdata

用來指向外部數(shù)據(jù)空間中的大小為一頁(256字節(jié))的數(shù)據(jù)存儲(chǔ)空間。注意:某些新型的8051芯片有更大的XRAM(如16M的XRAM),一般用far類型來描述這些區(qū)域??梢苑謩e用far

和constfar

來訪問位于擴(kuò)充RAM空間中的變量和擴(kuò)充ROM空間中的常量。第四十二頁,共一百三十七頁,2022年,8月28日注意:某些單片機(jī)芯片提供了片內(nèi)的XRAM空間,這種空間也使用和傳統(tǒng)的外部數(shù)據(jù)空間相同的指令來訪問。這種XRAM空間,通常使用芯片專用的SFR配置寄存器來使能,它和傳統(tǒng)外部存儲(chǔ)空間占用相同的地址空間。第四十三頁,共一百三十七頁,2022年,8月28日存儲(chǔ)器類型C51編譯器允許8051微處理器使用各種類型的存儲(chǔ)區(qū)域??梢栽谧兞柯暶鲿r(shí)使用存儲(chǔ)器類型(memorytypes)來指定變量所希望占用的存儲(chǔ)區(qū)域。內(nèi)部數(shù)據(jù)區(qū)的訪問速度比外部數(shù)據(jù)區(qū)的訪問速度高很多。因而一般將經(jīng)常使用的變量放在內(nèi)部數(shù)據(jù)區(qū),將大的或不常使用的變量放在外部數(shù)據(jù)區(qū)。第四十四頁,共一百三十七頁,2022年,8月28日存儲(chǔ)器類型存儲(chǔ)區(qū)域大小對(duì)應(yīng)的匯編語句描述code程序存儲(chǔ)區(qū)64KBMOVCA,@A+DPTR用來說明常量data直接尋址的內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)128BMOVXX,#ADDR訪問速度快idata間接尋址的內(nèi)部數(shù)據(jù)區(qū)256BMOVXX,@Rn可訪問整個(gè)內(nèi)部數(shù)據(jù)區(qū)域bdata位尋址的內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)16B(128b)可使用位尋址或字節(jié)尋址來訪問這一區(qū)域xdata外部數(shù)據(jù)存儲(chǔ)或64KBMOVXA,@DPTR使用DPTR來訪問外部數(shù)據(jù)存儲(chǔ)器far擴(kuò)充的RAM和ROM使用用戶定義的專用例程或特殊芯片指令擴(kuò)展命令pdata分頁的外部數(shù)據(jù)存儲(chǔ)區(qū)256BMOVXA,@Rn利用R0,R1來訪問分頁的外部數(shù)據(jù)存儲(chǔ)器第四十五頁,共一百三十七頁,2022年,8月28日聲明變量時(shí)可以說明變量的存儲(chǔ)器類型,如下例所示: //內(nèi)部數(shù)據(jù)區(qū)的字符型變量。

chardatavar1; //在程序區(qū)中定義字串charcodetext[]="ENTERPARAMETER:";//外部數(shù)據(jù)區(qū)的長度為100的無符號(hào)長整形數(shù)組unsignedlongxdataarray[100];//內(nèi)部數(shù)據(jù)區(qū),間接尋址方式訪問的浮點(diǎn)變量

floatidatax,y,z; //外部數(shù)據(jù)區(qū),分頁存儲(chǔ)區(qū)中的無符號(hào)整型變量

unsignedintpdatadimension; //外部數(shù)據(jù)區(qū),無符號(hào)字符類型的三維數(shù)組變量unsignedcharxdatavector[10][4][4]; //內(nèi)部數(shù)據(jù)區(qū),可位操作的字符變量charbdataflags;說明:聲明變量時(shí)存儲(chǔ)區(qū)修飾符和數(shù)據(jù)類型修飾符的位置可以互換,即chardatax;和datacharx;是完全等效的。不過從兼容性考慮,建議使用前一種格式。第四十六頁,共一百三十七頁,2022年,8月28日存儲(chǔ)模式(memorymodels)如果在變量聲明時(shí)未聲明變量的存儲(chǔ)器類型,則該變量的存儲(chǔ)器類型,由程序的存儲(chǔ)模式來決定。小模式(smallmodel)緊湊模式(compactmodel)大模式(largemodel)注意:除非應(yīng)用在特殊的場(chǎng)合,否則SMALL存儲(chǔ)模式可以提供最快和最有效的代碼。第四十七頁,共一百三十七頁,2022年,8月28日小模式(smallmodel)在小模式下,所有未聲明存儲(chǔ)器類型的變量,缺省駐留在內(nèi)部數(shù)據(jù)區(qū),即這種方式和用data進(jìn)行顯式說明一樣。在這種存儲(chǔ)模式下,變量的訪問是最有效。但是所有的數(shù)據(jù)對(duì)象(包括堆棧)都必須放在內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)中。第四十八頁,共一百三十七頁,2022年,8月28日緊湊模式(compactmodel)在緊湊模式下,所有未聲明存儲(chǔ)器類型的變量,缺省駐留在外部數(shù)據(jù)區(qū)的一個(gè)頁上,即這種方式和用pdata顯示說明一樣。該模式利用R0和R1寄存器來進(jìn)行間接尋址(@R0,@R1),此時(shí)最大可尋址256字節(jié)的存儲(chǔ)區(qū)域。這種方式的存取速度比小模式慢,但比大模式快。在緊湊模式下使用了超過256字節(jié)的外部數(shù)據(jù)存儲(chǔ)區(qū),那么訪問單元的高8位地址(即頁地址)必須由端口P2來輸出。開發(fā)人員必須在鏈接時(shí)為PDATA設(shè)置合適的開始地址。第四十九頁,共一百三十七頁,2022年,8月28日大模式(largemodel)在大模式下,所有未聲明存儲(chǔ)器類型的變量,缺省時(shí)駐留在外部數(shù)據(jù)存儲(chǔ)區(qū),即和用xdata顯示說明一樣。此時(shí)最大可尋址64K字節(jié)的存儲(chǔ)區(qū)域。此時(shí)使用數(shù)據(jù)指針寄存器(DPTR)來進(jìn)行間接尋址。使用這種尋址方式效率低,生成的代碼比小模式或緊湊模式下生成的代碼要長。第五十頁,共一百三十七頁,2022年,8月28日動(dòng)態(tài)存儲(chǔ)分配對(duì)大多數(shù)應(yīng)用來說,應(yīng)盡可能在編譯的時(shí)候確定所需要的內(nèi)存空間,但是對(duì)于有些需要使用動(dòng)態(tài)結(jié)構(gòu),如樹和鏈表的應(yīng)用來說,這種方式就不再適用了,這時(shí)必須要使用動(dòng)態(tài)存儲(chǔ)分配。動(dòng)態(tài)存儲(chǔ)分配的實(shí)現(xiàn):用戶需要聲明一個(gè)字節(jié)數(shù)組作為堆,數(shù)組的大小根據(jù)所需要?jiǎng)討B(tài)內(nèi)存的大小來決定。該數(shù)組的存儲(chǔ)器類型必須被聲明為XDATA,因?yàn)閹旌瘮?shù)使用具體指針來進(jìn)行內(nèi)存尋址。將指向堆首地址的指針和堆的大小傳遞給初始化函數(shù)init_mempool,該函數(shù)將設(shè)置一些內(nèi)部變量并對(duì)動(dòng)態(tài)存儲(chǔ)空間進(jìn)行初始化。初始化工作完成后就可在程序中調(diào)用malloc和free等C語言動(dòng)態(tài)分配函數(shù)。第五十一頁,共一百三十七頁,2022年,8月28日C51語言支持以下幾種動(dòng)態(tài)分配的函數(shù):malloc:申請(qǐng)內(nèi)存空間。調(diào)用時(shí)將所申請(qǐng)的內(nèi)存空間的大小傳遞給函數(shù),函數(shù)返回一個(gè)內(nèi)存空間指針。如果操作失敗,返回的指針值為NULL。calloc:計(jì)算并申請(qǐng)內(nèi)存空間。調(diào)用時(shí)將所申請(qǐng)的變量數(shù)目和變量所占用的大小傳遞給函數(shù),函數(shù)返回一個(gè)內(nèi)存空間指針。如果操作失敗,返回的指針值為NULL。realloc:重新分配內(nèi)存空間。調(diào)用時(shí)將一個(gè)已經(jīng)申請(qǐng)的內(nèi)存指針和新的內(nèi)存空間大小傳遞給函數(shù),函數(shù)返回一個(gè)內(nèi)存空間指針。如果操作失敗,返回的指針值為NULL。free:釋放內(nèi)存空間。調(diào)用時(shí)將一個(gè)已經(jīng)申請(qǐng)的內(nèi)存指針傳遞給函數(shù),函數(shù)將釋放該內(nèi)存空間。第五十二頁,共一百三十七頁,2022年,8月28日

C51中的特殊數(shù)據(jù)類型C51中有幾種ANSIC所沒有的特殊數(shù)據(jù)類型,這些數(shù)據(jù)類型是和存儲(chǔ)區(qū)域和存儲(chǔ)器類型的概念密切相關(guān)的。

位變量可位尋址的對(duì)象特殊功能寄存器第五十三頁,共一百三十七頁,2022年,8月28日位變量位變量(BitTypes)是指用一個(gè)二進(jìn)制位表示的變量。位數(shù)據(jù)類型可以用來說明變量,參數(shù)表,函數(shù)返回值等。位數(shù)據(jù)變量聲明和基本的數(shù)據(jù)類型聲明一樣。所有的位變量都存儲(chǔ)在內(nèi)部數(shù)據(jù)區(qū)的位尋址段中。因?yàn)樵摱沃挥?6個(gè)字節(jié)長,所以在一個(gè)作用域內(nèi)最多只能聲明128個(gè)位變量。注意:由于位變量只能存儲(chǔ)在內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)的位變量區(qū)內(nèi),因此只能使用data和idata兩種存儲(chǔ)器類型修飾符,其它存儲(chǔ)器類型是非法的。第五十四頁,共一百三十七頁,2022年,8月28日例3.15位變量的使用staticbitdone_flag=0; /*位變量*/bittestfunc( /*位函數(shù)返回類型*/ bitflag1, /*位類型參數(shù)*/ bitflag2) { … return(0); /*位類型返回值*/ }第五十五頁,共一百三十七頁,2022年,8月28日位變量定義或聲明時(shí)必須遵循以下規(guī)則:禁止中斷的函數(shù)(#pragmadisable)和顯式定義寄存器組(usingn)的函數(shù)不能返回位變量。函數(shù)在這種情況下返回位變量時(shí),編譯器將產(chǎn)生一個(gè)錯(cuò)誤信息。不能將指針聲明為指向一個(gè)位類型。

bit*ptr; /*非法語句*/不能聲明位類型的數(shù)組

bitware[5]; /*非法語句*/第五十六頁,共一百三十七頁,2022年,8月28日可位尋址的對(duì)象可位尋址的對(duì)象(Bit-addressableObjects)是指可以同時(shí)用字節(jié)(字)尋址和位尋址方式進(jìn)行訪問的對(duì)象。只有當(dāng)數(shù)據(jù)對(duì)象占據(jù)8051內(nèi)部數(shù)據(jù)區(qū)的可位尋址區(qū)時(shí),才是一個(gè)可位尋址對(duì)象。C51使用bdata存儲(chǔ)器類型來聲明可位尋址對(duì)象。例如:intbdataibase; /*可位尋址的整形變量*/charbdatabary[4]; /*可位尋址的字符形數(shù)組*/注意:聲明為bdata存儲(chǔ)器類型的變量必須為全局變量,不能是局部變量。由于bdata區(qū)為16個(gè)字節(jié),因此可尋址對(duì)象所占存儲(chǔ)空間不能大于16個(gè)字節(jié)。第五十七頁,共一百三十七頁,2022年,8月28日上例中的ibase和bary是可位尋址對(duì)象。因此,這些變量的位可以單獨(dú)的訪問和更改??墒褂胹bit關(guān)鍵字聲明位變量來訪問用bdata聲明變量的指定位。sbitmybit0=ibase^0; /**/sbitmybit15=ibase^15; /**/sbitary07=bary[0]^7; /*bit7ofbary[0]*/sbitary37=bary[3]^7; /*bit7ofbary[3]*/表達(dá)式中在’^’符號(hào)后的表達(dá)式定義了位的位置。該表達(dá)式必須是一個(gè)常量。表達(dá)式的取值范圍由變量聲明中的基變量的數(shù)據(jù)類型來決定。對(duì)char和unsignedchar類型,范圍為0-7;對(duì)int,unsignedint,short,unsignedshort,為0-15;對(duì)long和unsignedlong為0-31。第五十八頁,共一百三十七頁,2022年,8月28日下面的例子,采用了位尋址,字節(jié)尋址,字尋址來改變可位尋址對(duì)象的值。ary37=1; /*setbit7inbary[3]*/bary[3]='a'; /*Byteaddressing*/ibase=-1; /*Wordaddressing*/mybit15=0; /**/可位尋址對(duì)象不僅可以是基本變量類型,還可以是結(jié)構(gòu)或聯(lián)合這樣的復(fù)雜數(shù)據(jù)類型。第五十九頁,共一百三十七頁,2022年,8月28日例3.16以復(fù)雜數(shù)據(jù)類型為基變量的可位尋址對(duì)象unionlft{floatmf;longml;};bdatastructbad{charm1;unionlftu;}tcp;sbittcpf31=tcp.u.ml^31; /**/sbittcpm10=tcp.m1^0;sbittcpm17=tcp.m1^7;第六十頁,共一百三十七頁,2022年,8月28日說明:位變量用基地址加位偏移來獲取實(shí)際的物理地址。物理地址位地址0指向第一個(gè)字節(jié)的0位,8指向第2個(gè)字節(jié)的0位。8051中整型變量存儲(chǔ)時(shí)是高字節(jié)在低地址(第1個(gè)字節(jié)),低字節(jié)在高地址(第2個(gè)字節(jié))。即整型的0位在第2個(gè)字節(jié)的0位上,這個(gè)地址用sbit來標(biāo)識(shí)時(shí)是位置8。第六十一頁,共一百三十七頁,2022年,8月28日例3.17位變量與整型變量的對(duì)應(yīng)關(guān)系bdataintiData; //位尋址變量必須為全局變量sbitbTest1=iData^8;sbitbTest2=iData^0;main(){ iData=0; bTest1=1; //iData=1; iData=0; bTest2=1; //iData=256;}第六十二頁,共一百三十七頁,2022年,8月28日特殊功能寄存器8051系列的微控制器提供了一個(gè)獨(dú)立的內(nèi)存區(qū),用來存放特殊功能寄存器(specialfunctionregister,SFR)。SFR用來在程序中控制定時(shí)器,計(jì)數(shù)器,串行I/O,端口I/O操作,以及外設(shè)的操作。SFR駐留在地址0X80到0XFF空間,可按字節(jié)尋址或按字尋址,某些寄存器還可以按位尋址。8051系列微控制器中SFR的個(gè)數(shù)和類型是變化的。C51沒有預(yù)先定義SFR的名字,而是提供了許多8051兼容芯片的包含文件,這些文件對(duì)芯片的SFR進(jìn)行了定義。CX51編譯器用sfr,sfr16,sbit來進(jìn)行SFR定義。第六十三頁,共一百三十七頁,2022年,8月28日sfr:定義8位特殊功能寄存器sfr可以用來定義8051單片機(jī)的8位特殊功能寄存器。sfr占用一個(gè)字節(jié)內(nèi)存單元,取值范圍是0~255。SFR的聲明和C變量的聲明格式是一樣的,只不過使用的修飾符不是char或int而是sfr。例如:sfrP0=0x80; /*Port-0,address80h*/sfrP1=0x90; /*Port-1,address90h*/sfrP2=0xA0; /*Port-2,address0A0h*/sfrP3=0xB0; /*Port-3,address0B0h*/P0,P1,P2,P3是sfr聲明的特殊功能寄存器的名稱。特殊功能寄存器名稱是一個(gè)合法的C標(biāo)識(shí)符。等號(hào)后的地址必須是數(shù)值常量,不允許使用帶運(yùn)算符的表達(dá)式。第六十四頁,共一百三十七頁,2022年,8月28日sfr16:定義16位特殊功能寄存器8051芯片可以將兩個(gè)8位SFR作為一個(gè)16位寄存器來訪問。條件是這兩個(gè)SFR必須處在相鄰地址上,并且是低字節(jié)在高字節(jié)地址的前面。C51提供了sfr16數(shù)據(jù)類型來進(jìn)行16位特殊功能寄存器的聲明,聲明時(shí)低字節(jié)地址被用來作為sfr16的地址。例如:sfr16T2=0xCC; /*Timer2:T2L0CCh,T2H0CDh*/sfr16RCAP2=0xCA;/*RCAP2L0CAh,RCAP2H0CBh*/在這個(gè)例子中,T2和RCAP2被聲明為16位的特殊功能寄存器。sfr16聲明和sfr聲明的規(guī)則相同。第六十五頁,共一百三十七頁,2022年,8月28日sbit:定義特殊功能位sbit用來訪問SFR中的可尋址位和其它可位尋址對(duì)象的可尋址位。在8051應(yīng)用中,經(jīng)常需要對(duì)SFR中的可尋址位(特殊功能位)進(jìn)行獨(dú)立訪問。可以用sbit數(shù)據(jù)類型來將SFR中的可尋址位聲明為特殊功能位。sbitEA=0xAF;上例中將EA定義為地址0XAF,對(duì)8051而言這是中斷使能寄存器(IE)的中斷許可位。第六十六頁,共一百三十七頁,2022年,8月28日有三種方法來聲明位地址:方法一:sfr_name^int_constant,即SFR寄存器名^整形常量。這種方法使用已經(jīng)定義的sfr作為sbit的基地址。該SFR的地址必須能被8整除,^符號(hào)后的表達(dá)式定義了可尋址位的位地址。位地址必須是0-7之間的數(shù)。sfrPSW=0xD0; //聲明寄存器名sfrIE=0xA8;sbitOV=PSW^2; //聲明特殊功能位sbitCY=PSW^7;sbitEA=IE^7;第六十七頁,共一百三十七頁,2022年,8月28日方法二:int_constant^int_constant,即整形常量^整形常量。這種方法使用整形常數(shù)作為基地址。該地址必須可以被8整除,^符號(hào)后的表達(dá)式定義了可尋址位的位地址。位地址必須是0-7之間的數(shù)。sbitOV=0xD0^2;sbitCY=0xD0^7;sbitEA=0xA8^7;方法三:int_constant用絕對(duì)位地址來聲明sbit。sbitOV=0xD2;sbitCY=0xD7;sbitEA=0xAF;第六十八頁,共一百三十七頁,2022年,8月28日注意:sbit、bit和位域是三種不同的數(shù)據(jù)類型。使用sbit聲明時(shí),基對(duì)象必須可位尋址變量或者是可以位尋址的特殊功能寄存器。類型訪問對(duì)象sbit可位尋址變量或可位尋址的特殊功能寄存器bit可位尋址區(qū)中的位,共128位位域?qū)⒆止?jié),整型,長整型的某幾個(gè)位作為一個(gè)數(shù)據(jù)存儲(chǔ)單元,進(jìn)行獨(dú)立訪問。第六十九頁,共一百三十七頁,2022年,8月28日絕對(duì)變量地址開發(fā)者有時(shí)候希望把變量存儲(chǔ)在指定的地址單元中??捎胈at_

關(guān)鍵詞來將變量定位在一個(gè)絕對(duì)的內(nèi)存地址單元。 使用方法如下:數(shù)據(jù)類型存儲(chǔ)器類型變量名_at_變量所在絕對(duì)地址;在_at_后面的絕對(duì)地址必須符合存儲(chǔ)器類型的物理邊界限制,即不超過存儲(chǔ)區(qū)域的最大可尋址范圍,該地址必須為常數(shù)。第七十頁,共一百三十七頁,2022年,8月28日絕對(duì)變量定位遵循以下約束:絕對(duì)變量不能初始化。類型為bit的函數(shù)和變量不能用絕對(duì)地址定位。絕對(duì)變量必須是全局變量,不能是局部變量。第七十一頁,共一百三十七頁,2022年,8月28日例3.18structlink{ structlinkidata*next; charcode*test;};structlinklistidata_at_0x40; /*listatidata0x40*/charxdatatext[256]_at_0xE000;/*arrayatxdata0xE000*/intxdatai1_at_0x8000; /*i1atxdata0x8000*/voidmain(void){ list.next=(void*)0; i1=0x1234; text[0]='a';}第七十二頁,共一百三十七頁,2022年,8月28日有時(shí)需要在不同的模塊之間調(diào)用變量,可使用下列的語句來在另一個(gè)源文件中訪問上例中用_at_修飾的變量。例3.19struct link{ structlinkidata*next; charcode*test;};externstructlinkidatalist; /*listatidata0x40*/externcharxdatatext[256];/*arrayatxdata0xE000*/externintxdatai1; /*intatxdata0x8000*/第七十三頁,共一百三十七頁,2022年,8月28日

數(shù)組和指針數(shù)組是一個(gè)由同種類型的變量組成的集合,它保存在連續(xù)的存儲(chǔ)區(qū)域中,第一個(gè)元素保存在最低地址中,最末一個(gè)元素保存在最高地址中。數(shù)組可以是一維的也可以是多維的。 數(shù)組的定義方式如下: 數(shù)據(jù)類型數(shù)組名[常量1][常量2]…[常量n]; 這里的n是數(shù)組的維數(shù)。在定義時(shí)可以進(jìn)行數(shù)組元素的初始化,初始化的值放在{}中,每個(gè)元素值用逗號(hào)分開。如果是對(duì)多維數(shù)組進(jìn)行初始化,還可以使用{}將元素維的大小分成組。第七十四頁,共一百三十七頁,2022年,8月28日例如:chara[2][3]={0,1,2,3,4,5};chara[2][3]={{0,1,2},{3,4,5}};以上兩條語句的功能是相同的,執(zhí)行完成后各元素的值如下:(設(shè)初始地址為ADDR)地址對(duì)應(yīng)元素對(duì)應(yīng)值A(chǔ)DDRa[0][0]0ADDR+1a[0][1]1ADDR+2a[0][2]2ADDR+3a[1][0]3ADDR+4a[1][1]4ADDR+5a[1][2]5第七十五頁,共一百三十七頁,2022年,8月28日對(duì)于特殊的字符串?dāng)?shù)組,初始化時(shí)不僅可以采用每個(gè)元素分別賦值,還可以以字符串的形式賦值。如

chararray[20]=”helloworld”;還可以使維數(shù)的大小為空,由初始化字串的長度決定數(shù)組的長度。如

chararray[]=”helloworld”;上例中,數(shù)組array的長度為12個(gè)字節(jié)(字符串賦值時(shí)會(huì)增加一個(gè)’\0’字符,作為字符串的結(jié)束標(biāo)志)。第七十六頁,共一百三十七頁,2022年,8月28日注意:C語言中的數(shù)組元素的下標(biāo)總是從0開始的。多維數(shù)組在內(nèi)存中保存時(shí),下標(biāo)1變化最慢,下標(biāo)n變化最快。第七十七頁,共一百三十七頁,2022年,8月28日指針與地址的概念程序中的變量經(jīng)過編譯處理后都對(duì)應(yīng)著內(nèi)存中的一個(gè)地址。編譯器根據(jù)變量的類型,為其分配不同大小的內(nèi)存單元來存放變量的數(shù)據(jù)。所謂指針,就是某個(gè)變量所占用存儲(chǔ)單元的首地址。用來存放指針值的變量稱為指針變量。指針變量的定義格式如下:

類型說明符*指針變量名其中:“*”表示定義的是指針變量,類型說明符表示該指針變量指向的變量的類型。第七十八頁,共一百三十七頁,2022年,8月28日C51的指針和標(biāo)準(zhǔn)C中的指針功能相同。但是由于8051體系結(jié)構(gòu)的特殊性,C51提供了兩種不同類型的指針:通用指針(GenericPointers)具體指針(Memory-specificPointers)。通用指針的聲明是和標(biāo)準(zhǔn)C中的指針聲明是相同的,例如:char*s; /*指向字符類型的指針*/int*numptr; /*指向整型類型的指針*/long*state; /*指向長整型類型的指針*/第七十九頁,共一百三十七頁,2022年,8月28日通用指針總是占用三個(gè)字節(jié)。第1個(gè)字節(jié)保存存儲(chǔ)器類型編碼值,第2個(gè)字節(jié)保存地址的高字節(jié),第3個(gè)字節(jié)保存地址的低字節(jié)。許多C51的庫例程使用這種指針類型,通用指針類型可以訪問任何存儲(chǔ)區(qū)域內(nèi)變量。存儲(chǔ)器類型idata/data/bdataxdatapdatacode編碼值0x000x010xFE0xFF第八十頁,共一百三十七頁,2022年,8月28日具體指針是在聲明時(shí)指定了存儲(chǔ)器類型的指針,是指向特定存儲(chǔ)區(qū)域中的指針變量。char data *str; /*ptrtostringindata*/int xdata*numtab; /*ptrtoint(s)inxdata*/longcode*powtab; /*ptrtolong(s)incode*/具體指針不需要保存存儲(chǔ)器類型字節(jié)。具體指針可以保存在一個(gè)字節(jié)(idata,data,bdata,pdata類型指針)或2個(gè)字節(jié)(code和xdata類型指針)中。具體指針可以用來訪問8051聲明的存儲(chǔ)區(qū)內(nèi)的變量。具體指針的效率高,但靈活性較差。第八十一頁,共一百三十七頁,2022年,8月28日指定具體指針本身的存儲(chǔ)類型的定義例:chardata*xdataptr; /*ptrinxdatatodatachar*/intxdata*datanumtab;/*numtabindatatoxdataint*/longcode*idatapowtab; /*powtabinidatatocodelong*/注意:本例中變量定義時(shí)使用了兩個(gè)存儲(chǔ)器類型,‘*’前的存儲(chǔ)器類型修飾指針指向的數(shù)據(jù),‘*’后的存儲(chǔ)器類型修飾指針本身,即指針?biāo)紦?jù)的存儲(chǔ)區(qū)域類型。

第八十二頁,共一百三十七頁,2022年,8月28日注意:完成相同的功能,使用通用指針類型的代碼與使用具體指針類型的代碼相比,前者的運(yùn)行速度要慢很多。原因:這是因?yàn)橥ㄓ弥羔橆愋椭挥性诔绦蜻\(yùn)行時(shí)才能知道實(shí)際的變量存儲(chǔ)區(qū)類型,因此編譯器就不能對(duì)內(nèi)存訪問進(jìn)行優(yōu)化,從而只能生成可以訪問任意存儲(chǔ)區(qū)的通用代碼。如果必須優(yōu)先考慮程序的運(yùn)行速度,那么只要有可能就應(yīng)該使用具體指針來替代通用指針第八十三頁,共一百三十七頁,2022年,8月28日指針變量的引用在利用指針變量進(jìn)行間接訪問時(shí),必須使它指向一個(gè)確定的變量。指針變量只能存放地址,不能將一個(gè)非地址量賦給指針變量。C語言中有兩個(gè)與指針相關(guān)的運(yùn)算符:*:指針運(yùn)算符,作用是通過指針變量間接訪問它所指向的變量,來存取數(shù)據(jù)。&:取地址運(yùn)算符,作用是取得變量所占用存儲(chǔ)單元的首地址,即指針。第八十四頁,共一百三十七頁,2022年,8月28日數(shù)組的指針 一個(gè)數(shù)組包含多個(gè)元素,每個(gè)數(shù)組元素都在內(nèi)存中占用存儲(chǔ)單元,都有相應(yīng)的地址,并且這些存儲(chǔ)單元都是連續(xù)的。指針變量可以指向數(shù)組和數(shù)組的任意元素。引用數(shù)組元素可以使用:下標(biāo)法(即[]運(yùn)算符和對(duì)應(yīng)元素的下標(biāo))指針法(即通過指向數(shù)組元素的指針找到所需元素)。第八十五頁,共一百三十七頁,2022年,8月28日例如:floata[10];float*p1,*p2;p1=a;p2=&a[0];上例運(yùn)行完成后,指針p1和p2的值是相同的,均指向數(shù)組的首地址,即第一個(gè)元素。 注意:指向數(shù)組的指針的值和指向數(shù)組首元素的指針的值是相同的第八十六頁,共一百三十七頁,2022年,8月28日C語言規(guī)定,如果指針變量pointer已經(jīng)指向數(shù)組中的一個(gè)元素,則pointer+1指向同一個(gè)數(shù)組元素的下一個(gè)元素,而不是pointer的值簡單加1。實(shí)際增加的大小,由指針指向變量的類型決定。第八十七頁,共一百三十七頁,2022年,8月28日函數(shù)的指針在C語言中,指針變量除了能指向數(shù)據(jù)對(duì)象外,也可以指向函數(shù)。函數(shù)在編譯時(shí),編譯器為每個(gè)函數(shù)分配一個(gè)入口地址,這個(gè)入口地址就稱為函數(shù)的指針。函數(shù)的指針可以賦給函數(shù)指針變量,并能通過函數(shù)指針變量來調(diào)用它所指向的函數(shù)。指向函數(shù)指針變量的定義格式如下: 類型標(biāo)識(shí)符(*指針變量名)(參量列表)第八十八頁,共一百三十七頁,2022年,8月28日intadd(inta,intb){returna+b};intsub(inta,intb){returna-b};main(){ int(*pFunc)(int,int); //定義函數(shù)指針變量!

intx,y; pFunc=add; //對(duì)函數(shù)指針變量賦值

x=(*pFunc)(3,4); pFunc=sub; y=(*pFunc)(5,3);}上例運(yùn)行完成后,x=7,y=2。第八十九頁,共一百三十七頁,2022年,8月28日說明:函數(shù)指針變量定義時(shí),兩側(cè)的()是必須的,表示變量名先于*結(jié)合,是一個(gè)指針變量。然后再與后隨的()結(jié)合,表示指針變量指向的對(duì)象是函數(shù)。指向的函數(shù)的指針變量可以指向任何一個(gè)格式相同的函數(shù)的入口地址。C語言約定,函數(shù)名本身就是函數(shù)的入口地址。當(dāng)函數(shù)指針變量指向函數(shù)時(shí),即可用它來調(diào)用所指的函數(shù)。調(diào)用格式為(*指針變量名)(實(shí)參表)第九十頁,共一百三十七頁,2022年,8月28日

程序設(shè)計(jì)的三種基本結(jié)構(gòu)計(jì)算機(jī)程序是由若干條有序的語句組成的。在程序執(zhí)行過程中一般有以下幾種情況:在程序執(zhí)行過程中,程序按語句的順序逐條執(zhí)行,這稱為的順序結(jié)構(gòu)。在程序執(zhí)行過程中,根據(jù)特定的條件選擇執(zhí)行某些語句,即程序執(zhí)行的順序根據(jù)條件來選擇,這稱為選擇結(jié)構(gòu)。在程序執(zhí)行過程中,根據(jù)某個(gè)條件是否成立重復(fù)執(zhí)行一段程序,直到該條件不成立為止,即程序的執(zhí)行順序在某處循環(huán),這稱為循環(huán)結(jié)構(gòu)。程序是由順序、選擇、循環(huán)這三種結(jié)構(gòu)構(gòu)成的復(fù)雜組合。第九十一頁,共一百三十七頁,2022年,8月28日C語言的語句用來向計(jì)算機(jī)系統(tǒng)發(fā)出操作指令,C語言中語句是以分號(hào)為結(jié)束標(biāo)志的。C語言中語句可分為以下幾類:控制語句:控制程序運(yùn)行的語句??照Z句:只有一個(gè)分號(hào)的語句,稱為空語句,它不進(jìn)行任何操作。表達(dá)式語句:表達(dá)式后面加上分號(hào)就構(gòu)成一個(gè)表達(dá)式語句。函數(shù)調(diào)用語句也是表達(dá)式語句,由函數(shù)調(diào)用加分號(hào)構(gòu)成。復(fù)合語句:可以把多個(gè)語句用{}括起來,就成為復(fù)合語句,多用于選擇或循環(huán)結(jié)構(gòu)中。注釋語句:在C51中,由/*、*/符號(hào)對(duì)包含的內(nèi)容以及雙斜杠//后面的內(nèi)容均表示注釋語句。編程人員使用注釋語句來解釋程序的功能,標(biāo)注修改時(shí)間等。第九十二頁,共一百三十七頁,2022年,8月28日語句功能if…else…條件語句for()循環(huán)語句while()循環(huán)語句do…while()循環(huán)語句continue結(jié)束本次循環(huán)語句break中止執(zhí)行switch語句或循環(huán)語句switch…case多分支選擇語句goto轉(zhuǎn)向語句return從函數(shù)返回語句第九十三頁,共一百三十七頁,2022年,8月28日順序結(jié)構(gòu)順序結(jié)構(gòu)是從前往后依次執(zhí)行語句。從整體上看所有程序都是順序結(jié)構(gòu),只不過中間某些部分是由選擇結(jié)構(gòu)或循環(huán)結(jié)構(gòu)構(gòu)成,選擇結(jié)構(gòu)或循環(huán)結(jié)構(gòu)部分執(zhí)行完成后,程序重新按順序結(jié)構(gòu)向下執(zhí)行。選擇結(jié)構(gòu)選擇結(jié)構(gòu)的基本特點(diǎn)是程序由多路分支構(gòu)成,在程序的一次執(zhí)行中根據(jù)指定的條件,選擇執(zhí)行其中的一條分支,而其他分支上的語句被直接跳過。循環(huán)結(jié)構(gòu)循環(huán)結(jié)構(gòu)是根據(jù)某個(gè)或某些條件是否成立,來重復(fù)運(yùn)行一段相同的程序。

第九十四頁,共一百三十七頁,2022年,8月28日C語言中可由if語句和switch語句構(gòu)成選擇結(jié)構(gòu)。if語句有3種基本形式:if(表達(dá)式)語句if(表達(dá)式)語句1else語句2if(表達(dá)式1)語句1elseif(表達(dá)式2)語句2

elseif(表達(dá)式3)語句3

else語句n在選擇結(jié)構(gòu)中,else默認(rèn)與最靠近它的if配對(duì),可用{}改變配對(duì)。if語句中,如果需要執(zhí)行的語句不止一條,可用{}組成復(fù)合語句。第九十五頁,共一百三十七頁,2022年,8月28日switch語句專門用來處理多路分支的情形,形式如下:switch(表達(dá)式){case常量表達(dá)式1:

語句1:

break;case常量表達(dá)式2:

語句2:

break;…case常量表達(dá)式n:

語句n:

break;default:

語句n+1;

break; }第九十六頁,共一百三十七頁,2022年,8月28日對(duì)switch語句需要注意:case分支中的常量表達(dá)式的值必須是整形、字符型或枚舉類型,不能使用條件運(yùn)算符。break語句用于跳出switch結(jié)構(gòu)。若case分支中未使用break語句,則程序?qū)⒗^續(xù)執(zhí)行下一個(gè)case分支中的語句直至遇到break語句或整個(gè)switch語句結(jié)束。這可以用于多個(gè)分支需要執(zhí)行相同的語句進(jìn)行處理的情況。第九十七頁,共一百三十七頁,2022年,8月28日for循環(huán)語句的一般格式為:for(表達(dá)式1;表達(dá)式2;表達(dá)式3)循環(huán)體語句for循環(huán)語句的執(zhí)行過程為:求解表達(dá)式1。求解表達(dá)式2。若其值為真,則執(zhí)行循環(huán)體;若其值為假,則循環(huán)語句結(jié)束,執(zhí)行后續(xù)語句。求解表達(dá)式3。并轉(zhuǎn)到第2步繼續(xù)執(zhí)行,直至條件為假時(shí)結(jié)束循環(huán)。注意:若第一次求解表達(dá)式2,其值就不成立,則循環(huán)體將一次都不執(zhí)行。第九十八頁,共一百三十七頁,2022年,8月28日while循環(huán)while語句格式為:while(表達(dá)式)循環(huán)體語句while語句先求解循環(huán)條件表達(dá)式的值。如果為真,則執(zhí)行循環(huán)體;否則跳出循環(huán),執(zhí)行后續(xù)操作。注意:一般來說在循環(huán)體中應(yīng)該有使循環(huán)最終能結(jié)束的語句。如果表達(dá)式初始值為假,則循環(huán)體將一次都不執(zhí)行。第九十九頁,共一百三十七頁,2022年,8月28日do…while循環(huán)do…while語句格式為:do循環(huán)體語句while(表達(dá)式);do…while循環(huán)是先執(zhí)行循環(huán)體一次,再判斷表達(dá)式的值,若為真,則繼續(xù)執(zhí)行循環(huán),否則退出循環(huán)。注意:do…while語句至少執(zhí)行循環(huán)體一次第一百頁,共一百三十七頁,2022年,8月28日goto語句goto語句的格式:goto語句標(biāo)號(hào);goto語句是無條件轉(zhuǎn)移語句,它將程序的運(yùn)行轉(zhuǎn)移到指定的標(biāo)號(hào)處。注意:goto語句使程序的轉(zhuǎn)移控制變得非常靈活,但是也可能破壞程序良好結(jié)構(gòu),因此應(yīng)小心使用。第一百零一頁,共一百三十七頁,2022年,8月28日break語句在循環(huán)語句中,break語句的作用是在循環(huán)體中測(cè)試到指定條件為真時(shí),其控制程序立即跳出當(dāng)前循環(huán)結(jié)構(gòu),轉(zhuǎn)而執(zhí)行循環(huán)語句的后續(xù)語句。continue語句continue語句只能用于循環(huán)結(jié)構(gòu)中,作用是結(jié)束本次循環(huán)。一旦執(zhí)行了continue語句,程序就跳過循環(huán)體中位于該語句后的所有語句,提前結(jié)束本輪循環(huán)并開始下一輪循環(huán)。第一百零二頁,共一百三十七頁,2022年,8月28日

函數(shù)在C語言中,函數(shù)是程序的基本組成單位。函數(shù)不僅可以實(shí)現(xiàn)程序的模塊化,提高程序的可讀性和可維護(hù)性,使程序設(shè)計(jì)變得簡單和直觀,還可以把程序中經(jīng)常用到的一些計(jì)算或操作設(shè)計(jì)成通用的函數(shù),以供隨時(shí)調(diào)用。C程序由一個(gè)主函數(shù)main()和若干個(gè)其它函數(shù)組成。由主函數(shù)調(diào)用其它函數(shù),其它函數(shù)也可以互相調(diào)用,同一個(gè)函數(shù)可以被調(diào)用多次。第一百零三頁,共一百三十七頁,2022年,8月28日函數(shù)定義函數(shù)定義的一般形式是:函數(shù)類型函數(shù)名(形式參數(shù)列表){

局部變量聲明部分 語句(有返回值的要有return語句)}函數(shù)類型定義了函數(shù)中返回語句(return)返回值的數(shù)據(jù)類型,返回值可以是任何一種有效的數(shù)據(jù)類型。如果沒有使用函數(shù)類型說明符,函數(shù)返回值默認(rèn)為整形值。第一百零四頁,共一百三十七頁,2022年,8月28日參數(shù)表是一個(gè)用逗號(hào)分隔的變量表,當(dāng)函數(shù)被調(diào)用時(shí)這些變量接收調(diào)用參數(shù)的值。一個(gè)函數(shù)可以沒有參數(shù),這時(shí)函數(shù)參數(shù)表是空的。注意即使沒有參數(shù),括號(hào)仍是必須的。C51對(duì)函數(shù)的功能進(jìn)行了擴(kuò)展,函數(shù)定義的完整形式如下:函數(shù)類型函數(shù)名(形式參數(shù)列表){small|compact|large}[reentrant][interruptn][usingn]第一百零五頁,共一百三十七頁,2022年,8月28日函數(shù)返回值返回語句return用來回送一個(gè)數(shù)值給定義的函數(shù),完成后從函數(shù)中退出。如果函數(shù)沒有返回值可以不使用return語句,或使用不帶返回值的return語句。關(guān)于返回值有以下幾條注意點(diǎn):返回值是通過return語句返回的。返回值的類型如果與函數(shù)定義的類型不一致,那么返回值將被自動(dòng)轉(zhuǎn)化為函數(shù)定義的類型。如果沒有return語句,函數(shù)會(huì)返回一個(gè)不確定的值。因此如果函數(shù)無需返回值,可以用”void”類型說明符指明函數(shù)無返回值。第一百零六頁,共一百三十七頁,2022年,8月28日形式參數(shù)與實(shí)際參數(shù)與使用變量一樣,在調(diào)用一個(gè)函數(shù)之前,必須對(duì)該函數(shù)進(jìn)行聲明,即先聲明后調(diào)用。函數(shù)聲明的一般形式是:函數(shù)類型函數(shù)名(形式參數(shù)列表);函數(shù)定義時(shí)參數(shù)列表中的參數(shù)稱為形式參數(shù),簡稱形參,它們同函數(shù)內(nèi)部的局部變量作用相同,形參的定義是在函數(shù)名后的括號(hào)中。函數(shù)調(diào)用時(shí)所使用的替換參數(shù),是實(shí)際參數(shù),簡稱實(shí)參。定義的形參與調(diào)用函數(shù)的實(shí)參類型應(yīng)該一致,書寫順序應(yīng)該相同。第一百零七頁,共一百三十七頁,2022年,8月28日在C語言中對(duì)不同類型的實(shí)際參數(shù),有三種不同的參數(shù)傳遞方式:基本數(shù)據(jù)類型的參數(shù)傳遞當(dāng)函數(shù)的參數(shù)是一般類型變量時(shí),主調(diào)函數(shù)將實(shí)際參數(shù)的值傳遞給被調(diào)用函數(shù)中的形式參數(shù),這種方式稱為傳值調(diào)用。這種參數(shù)傳遞方式下形式參數(shù)的值發(fā)生改變時(shí),實(shí)際參數(shù)的值不會(huì)受到影響。因此值傳遞是一種單向傳遞。數(shù)組類型的參數(shù)傳遞當(dāng)函數(shù)的參數(shù)是數(shù)組類型的變量時(shí),主調(diào)函數(shù)將實(shí)際參數(shù)數(shù)組的起始地址傳遞到被調(diào)用函數(shù)中的形式參數(shù)中,這種方式稱為地址傳遞。這種參數(shù)傳遞方式下形式參數(shù)的值發(fā)生改變時(shí),實(shí)際參數(shù)的值也會(huì)改變,因此地址傳遞是一種雙向傳遞。指針類型的參數(shù)傳遞當(dāng)函數(shù)的參數(shù)是指針類型的變量時(shí),主調(diào)函數(shù)將實(shí)際參數(shù)的地址傳遞給被調(diào)用函數(shù)的形式參數(shù),因此也是地址傳遞。這種參數(shù)傳遞方式下形式參數(shù)的值發(fā)生改變時(shí),實(shí)際參數(shù)的值也會(huì)改變。第一百零八頁,共一百三十七頁,2022年,8月28日函數(shù)調(diào)用方式在一個(gè)函數(shù)中調(diào)用另一函數(shù)需要具備下面的條件。被調(diào)用的函數(shù)必須是已經(jīng)存在的函數(shù),即已經(jīng)聲明或定義的函數(shù)。(庫函數(shù)或自定義函數(shù))如果是庫函數(shù),應(yīng)該在程序開頭用#include命令將有關(guān)庫函數(shù)所需用到的信息包含到本程序中來。如果是用戶定義的函數(shù),一般還應(yīng)該對(duì)被調(diào)用的函數(shù)做函數(shù)聲明。第一百零九頁,共一百三十七頁,2022年,8月28日調(diào)用函數(shù)的方式可以是以下幾種:函數(shù)作為語句:把函數(shù)調(diào)用作為一個(gè)語句,不使用函數(shù)返回值,只是完成函數(shù)所定義的操作。函數(shù)作為表達(dá)式:函數(shù)調(diào)用出現(xiàn)在一個(gè)表達(dá)式中,使用函數(shù)的返回值進(jìn)行相關(guān)運(yùn)算。函數(shù)作為一個(gè)參數(shù):函數(shù)調(diào)用作為另一個(gè)函數(shù)的實(shí)參,即使用函數(shù)的返回值做為另一個(gè)函數(shù)的實(shí)參。函數(shù)遞歸調(diào)用:函數(shù)可以自我調(diào)用。如果函數(shù)內(nèi)部一個(gè)語句調(diào)用了函數(shù)自己,則稱為遞歸。第一百一十頁,共一百三十七頁,2022年,8月28日內(nèi)部函數(shù)和外部函數(shù)C語言程序可以由多個(gè)函數(shù)組成,這些函數(shù)可以在同一個(gè)程序文件中,也可以在多個(gè)不同的程序文件中。根據(jù)這些函數(shù)的使用范圍,可以把它們分為靜態(tài)函數(shù)和外部函數(shù)。靜態(tài)函數(shù)(內(nèi)部函數(shù))靜態(tài)函數(shù)只能在定義它的文件中被調(diào)用,而不能在其他文件中的函數(shù)所調(diào)用。定義格式為:static

類型說明符函數(shù)名(形式參數(shù)列表)外部函數(shù)(默認(rèn))外部函數(shù)可以在定義它的文件和其它文件中被調(diào)用??梢栽诤瘮?shù)定義和調(diào)用時(shí)使用extern說明是外部函數(shù)。關(guān)鍵字extern可省略。extern

類型說明符函數(shù)名(形式參數(shù)列表)第一百一十一頁,共一百三十七頁,2022年,8月28日可重入函數(shù)可重入函數(shù)可以在同一個(gè)時(shí)刻由多個(gè)進(jìn)程共享。當(dāng)一個(gè)進(jìn)程正在執(zhí)行一個(gè)可重入函數(shù),另一個(gè)進(jìn)程可以中斷該進(jìn)程,并可以開始執(zhí)行同一個(gè)可重入函數(shù),而不影響函數(shù)的運(yùn)行結(jié)果。ANSIC語言中,調(diào)用函數(shù)時(shí)會(huì)把函數(shù)的參數(shù)和函數(shù)中使用的局部變量入棧。因?yàn)?051內(nèi)部堆??臻g的限制,為了提高效率,C51沒有提供這種堆棧,而是提供一種壓縮棧。每個(gè)函數(shù)有一個(gè)給定存儲(chǔ)空間,用于存放局部變量。函數(shù)中的每個(gè)變量都存放在這個(gè)空間的固定位置。當(dāng)遞歸調(diào)用該過程時(shí)會(huì)導(dǎo)致變量被覆蓋,所以通常情況下CX51中的函數(shù)是不能重入的。第一百一十二頁,共一百三十七頁,2022年,8月28日為此必須使用reentrant函數(shù)屬性來聲明函數(shù)是可重入的。格式如下:函數(shù)類型函數(shù)名(形式參數(shù)列表)reentrant與不可重入函數(shù)的參數(shù)傳遞和局部變量的存儲(chǔ)分配方法不同,C51編譯器為再入函數(shù)生成一個(gè)模擬棧,通過這

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論