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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

單片機八語言編程第1頁,共137頁,2023年,2月20日,星期一第3章51單片機編程語言3.1單片機編程語言概述3.2 C51語言第2頁,共137頁,2023年,2月20日,星期一3.1單片機編程語言概述

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

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

標識符、關鍵字標識符與關鍵字是C語言的基本組成部分。

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

和Var是兩個不同的標識符。注意2:C51編譯器6.0以上版本支持標識符的有效長度為256,超過部分忽略。第8頁,共137頁,2023年,2月20日,星期一

關鍵字關鍵字(keyword)是一種具有固定名稱和特定含義的標識符,又稱為保留字(reservedword)。這些標識符系統(tǒng)已經(jīng)做了定義,有特定的功能。用戶自定義的標識符不能和關鍵字同名。ANSIC語言定義了32個關鍵字。第9頁,共137頁,2023年,2月20日,星期一ANSIC關鍵字autodogotosignedunsignedbreakdoubleifsizeofvoidcaseelseintstaticvolatilecharenumlongstructwhileconstexternregisterswitchcontinuefloatreturntypedefdefaultforshortunion第10頁,共137頁,2023年,2月20日,星期一ANSIC關鍵字■程序控制語句:

breakcasecontinuedefaultdoelseforgotoifreturnswitchvolatilewhile■存儲種類說明:

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

chardoubleenumfloatintlongshortsignedstructtypedefunionunsignedvoid■運算符:

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

C語言的運算符符號意義說明+加法運算或表示正數(shù)-減法運算或表示負數(shù)*乘法運算/除法運算當2個整數(shù)相除時,結果為整數(shù),小數(shù)部分舍去。%模運算(求余)參加運算的均應為整數(shù)。++自增操作數(shù)據(jù)值加1--自減操作數(shù)據(jù)值減1第17頁,共137頁,2023年,2月20日,星期一例:設x的初值為4y=x++;結果:x=5,y=4解釋:x++先使用x的值,然后x的值再自增。y=++x;結果:y=5,x=5解釋:++xx的值先自增,然后再使用x的值。y=x--;結果:y=4,x=3解釋:x--先使用x的值,然后x的值再自減。y=--x;結果:y=3,x=3解釋:--xx的值先自減,然后再使用x的值。 第18頁,共137頁,2023年,2月20日,星期一邏輯運算符符號含義>大于>=大于等于==等于<小于<=小于等于!=不等于&&邏輯與,二個操作數(shù)均為真時,其值為真,否則為假||邏輯或,二個操作數(shù)均為假時,其值為假,否則為真!邏輯非,一元運算符,操作數(shù)為真,其值為假,操作數(shù)為假,其值為真注意:等于運算符用兩個等號表示。一個等號表示賦值操作。第19頁,共137頁,2023年,2月20日,星期一位運算符符號含義&按位與|按位或^按位異或~按位取反。一元運算符<<左移操作。左邊移出的位舍去,右邊移入的位補0>>右移操作。右邊移出的位舍去,左邊移入的位對無符號數(shù)補0;對有符號數(shù)補符號位第20頁,共137頁,2023年,2月20日,星期一例: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第21頁,共137頁,2023年,2月20日,星期一例:unsignedcharx=0x95;

signedchary=0x95;unsignedcharz;z=x>>1; 則 z=0x4Az=y>>1; 則 z=0xCA第22頁,共137頁,2023年,2月20日,星期一賦值運算符通常把’=’稱為賦值運算符。它是二元運算符,左邊必須是個變量或數(shù)組元素(稱為左值)右邊是表達式(稱為右值)。當左值和右值的數(shù)據(jù)類型不一致時,數(shù)據(jù)會自動進行數(shù)據(jù)類型轉換。除了’=’之外,C語言還提供了10種復合賦值運算符,它們的功能是對左值和右值進行相關運算后,將運算結果賦給左值。復合賦值運算符如下所示:

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

sizeof(表達式)或sizeof(數(shù)據(jù)類型)注意:sizeof是一種特殊的運算符,不是函數(shù)。實際上字節(jié)數(shù)的計算是在程序編譯時完成的,而不是在程序執(zhí)行的過程中才計算出來的。第28頁,共137頁,2023年,2月20日,星期一其它運算符*

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

: 取地址運算符。作用是獲取變量所占用的存儲單元的地址。[]

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

: 指向結構成員運算符。作用是用結構變量的指針來訪問結構中的成員變量。.

: 結構成員運算符,作用是用結構變量來訪問結構中的成員變量。第29頁,共137頁,2023年,2月20日,星期一運算優(yōu)先級優(yōu)先級符號含義運算對象個數(shù)結合方向1()圓括號自左向右[]下標運算符-> 指向結構成員運算符.結構成員運算符2!邏輯非運算符單操作數(shù)自右向左~按位取反操作符++自增運算符--自減運算符-負號運算符(類型)類型轉換運算符*指針運算符&取地址運算符sizeof長度運算符第30頁,共137頁,2023年,2月20日,星期一優(yōu)先級符號含義運算對象個數(shù)結合方向3*乘法運算符雙操作符自左向右/除法運算符%求余運算符4+加法運算符雙操作符自左向右-減法運算符5<<左移運算符雙操作符自左向右>>右移運算符6<、<=、>、>=關系運算符雙操作符自左向右7==等于運算符雙操作符自左向右!=不等于運算符第31頁,共137頁,2023年,2月20日,星期一優(yōu)先級符號含義運算對象個數(shù)結合方向8&按位與運算符雙操作符自左向右9^按位異或運算符雙操作符自左向右10|按位或運算符雙操作符自左向右11&&邏輯與運算符雙操作符自左向右12||邏輯或運算符雙操作符自左向右13?:條件運算符三操作符自右向左14=、+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=賦值運算符雙操作符自左向右15,逗號運算符自左向右第32頁,共137頁,2023年,2月20日,星期一3.3.3

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

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

區(qū)。XDATA區(qū)和CODE區(qū)一樣也采用16位地址尋址,即尋址空間可達64KB。該區(qū)通常包括一些通用數(shù)據(jù)存儲器或者一些需要通過總線接口訪問的外圍器件。訪問外部數(shù)據(jù)區(qū)比訪問內部數(shù)據(jù)區(qū)要慢,因為訪問外部數(shù)據(jù)區(qū)時,必須先將要訪問單元的16位地址裝載到數(shù)據(jù)指針寄存器DPTR中,然后才能通過DPTR采用間接訪問方式來訪問該單元。第41頁,共137頁,2023年,2月20日,星期一C51使用兩種修飾符來表示外部數(shù)據(jù)區(qū):xdata,pdataxdata

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

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

和constfar

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

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

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

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

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

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

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

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

關鍵詞來將變量定位在一個絕對的內存地址單元。 使用方法如下:數(shù)據(jù)類型存儲器類型變量名_at_變量所在絕對地址;在_at_后面的絕對地址必須符合存儲器類型的物理邊界限制,即不超過存儲區(qū)域的最大可尋址范圍,該地址必須為常數(shù)。第70頁,共137頁,2023年,2月20日,星期一絕對變量定位遵循以下約束:絕對變量不能初始化。類型為bit的函數(shù)和變量不能用絕對地址定位。絕對變量必須是全局變量,不能是局部變量。第71頁,共137頁,2023年,2月20日,星期一例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';}第72頁,共137頁,2023年,2月20日,星期一有時需要在不同的模塊之間調用變量,可使用下列的語句來在另一個源文件中訪問上例中用_at_修飾的變量。例3.19struct link{ structlinkidata*next; charcode*test;};externstructlinkidatalist; /*listatidata0x40*/externcharxdatatext[256];/*arrayatxdata0xE000*/externintxdatai1; /*intatxdata0x8000*/第73頁,共137頁,2023年,2月20日,星期一3.3.6

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

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

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

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

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

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

x=(*pFunc)(3,4); pFunc=sub; y=(*pFunc)(5,3);}上例運行完成后,x=7,y=2。第89頁,共137頁,2023年,2月20日,星期一說明:函數(shù)指針變量定義時,兩側的()是必須的,表示變量名先于*結合,是一個指針變量。然后再與后隨的()結合,表示指針變量指向的對象是函數(shù)。指向的函數(shù)的指針變量可以指向任何一個格式相同的函數(shù)的入口地址。C語言約定,函數(shù)名本身就是函數(shù)的入口地址。當函數(shù)指針變量指向函數(shù)時,即可用它來調用所指的函數(shù)。調用格式為(*指針變量名)(實參表)第90頁,共137頁,2023年,2月20日,星期一3.3.7

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

第94頁,共137頁,2023年,2月20日,星期一C語言中可由if語句和switch語句構成選擇結構。if語句有3種基本形式:if(表達式)語句if(表達式)語句1else語句2if(表達式1)語句1elseif(表達式2)語句2

elseif(表達式3)語句3

else語句n在選擇結構中,else默認與最靠近它的if配對,可用{}改變配對。if語句中,如果需要執(zhí)行的語句不止一條,可用{}組成復合語句。第95頁,共137頁,2023年,2月20日,星期一switch語句專門用來處理多路分支的情形,形式如下:switch(表達式){case常量表達式1:

語句1:

break;case常量表達式2:

語句2:

break;…case常量表達式n:

語句n:

break;default:

語句n+1;

break; }第96頁,共137頁,2023年,2月20日,星期一對switch語句需要注意:case分支中的常量表達式的值必須是整形、字符型或枚舉類型,不能使用條件運算符。break語句用于跳出switch結構。若case分支中未使用break語句,則程序將繼續(xù)執(zhí)行下一個case分支中的語句直至遇到break語句或整個switch語句結束。這可以用于多個分支需要執(zhí)行相同的語句進行處理的情況。第97頁,共137頁,2023年,2月20日,星期一for循環(huán)語句的一般格式為:for(表達式1;表達式2;表達式3)循環(huán)體語句for循環(huán)語句的執(zhí)行過程為:求解表達式1。求解表達式2。若其值為真,則執(zhí)行循環(huán)體;若其值為假,則循環(huán)語句結束,執(zhí)行后續(xù)語句。求解表達式3。并轉到第2步繼續(xù)執(zhí)行,直至條件為假時結束循環(huán)。注意:若第一次求解表達式2,其值就不成立,則循環(huán)體將一次都不執(zhí)行。第98頁,共137頁,2023年,2月20日,星期一while循環(huán)while語句格式為:while(表達式)循環(huán)體語句while語句先求解循環(huán)條件表達式的值。如果為真,則執(zhí)行循環(huán)體;否則跳出循環(huán),執(zhí)行后續(xù)操作。注意:一般來說在循環(huán)體中應該有使循環(huán)最終能結束的語句。如果表達式初始值為假,則循環(huán)體將一次都不執(zhí)行。第99頁,共137頁,2023年,2月20日,星期一do…while循環(huán)do…while語句格式為:do循環(huán)體語句while(表達式);do…while循環(huán)是先執(zhí)行循環(huán)體一次,再判斷表達式的值,若為真,則繼續(xù)執(zhí)行循環(huán),否則退出循環(huán)。注意:do…while語句至少執(zhí)行循環(huán)體一次第100頁,共137頁,2023年,2月20日,星期一goto語句goto語句的格式:goto語句標號;goto語句是無條件轉移語句,它將程序的運行轉移到指定的標號處。注意:goto語句使程序的轉移控制變得非常靈活,但是也可能破壞程序良好結構,因此應小心使用。第101頁,共137頁,2023年,2月20日,星期一break語句在循環(huán)語句中,break語句的作用是在循環(huán)體中測試到指定條件為真時,其控制程序立即跳出當前循環(huán)結構,轉而執(zhí)行循環(huán)語句的后續(xù)語句。continue語句continue語句只能用于循環(huán)結構中,作用是結束本次循環(huán)。一旦執(zhí)行了continue語句,程序就跳過循環(huán)體中位于該語句后的所有語句,提前結束本輪循環(huán)并開始下一輪循環(huán)。第102頁,共137頁,2023年,2月20日,星期一3.3.8

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

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

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

類型說明符函數(shù)名(形式參數(shù)列表)第111頁,共137頁,2023年,2月20日,星期一可重入函數(shù)可重入函數(shù)可以在同一個時刻由多個進程共享。當一個進程正在執(zhí)行一個可重入函數(shù),另一個進程可以中斷該進程,并可以開始執(zhí)行同一個可重入函數(shù),而不影響函數(shù)的運行結果。ANSIC語言中,調用函數(shù)時會把函數(shù)的參數(shù)和函數(shù)中使用的局部變量入棧。因為8051內部堆??臻g的限制,為了提高效率,C51沒有提供這種堆棧,而是提供一種壓縮棧。每個函數(shù)有一個給定存儲空間,用于存放局部變量。函數(shù)中的每個變量都存放在這個空間的固定位置。當遞歸調用該過程時會導致變量被

溫馨提示

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

評論

0/150

提交評論