_單片機(jī)C語(yǔ)言程序設(shè)計(jì)_第1頁(yè)
_單片機(jī)C語(yǔ)言程序設(shè)計(jì)_第2頁(yè)
_單片機(jī)C語(yǔ)言程序設(shè)計(jì)_第3頁(yè)
_單片機(jī)C語(yǔ)言程序設(shè)計(jì)_第4頁(yè)
_單片機(jī)C語(yǔ)言程序設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩102頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第四章 單片機(jī)C語(yǔ)言程序設(shè)計(jì)4.1 C語(yǔ)言與MCS-51單片機(jī)4.1.1 C語(yǔ)言的特點(diǎn)及程序結(jié)構(gòu)一C語(yǔ)言的特點(diǎn)1語(yǔ)言簡(jiǎn)潔、緊湊,使用方便、靈活。2運(yùn)算符豐富。3數(shù)據(jù)結(jié)構(gòu)豐富。具有現(xiàn)代化語(yǔ)言的各種數(shù)據(jù)結(jié)構(gòu)。4可進(jìn)行結(jié)構(gòu)化程序設(shè)計(jì)。5可以直接對(duì)計(jì)算機(jī)硬件進(jìn)行操作。6生成的目標(biāo)代碼質(zhì)量高,程序執(zhí)行效率高。7可移植性好。C語(yǔ)言程序結(jié)構(gòu)一般如下:預(yù)處理命令 include函數(shù)說(shuō)明 long fun1(); float fun2(); int x,y; float z;二C語(yǔ)言的程序結(jié)構(gòu)功能函數(shù)主函數(shù)功能函數(shù)功能函數(shù)1 fun1() 函數(shù)體 主函數(shù) main() 主函數(shù)體 功能函數(shù)2 fun2() 函數(shù)體

2、C語(yǔ)言程序在書(shū)寫(xiě)時(shí),一條語(yǔ)句可以寫(xiě)成一行,也可以寫(xiě)成幾行;還可以一行內(nèi)寫(xiě)多條語(yǔ)句;但每條語(yǔ)句后面必須以分號(hào)“;作為結(jié)束符。C語(yǔ)言程序?qū)Υ笮?xiě)字母比較敏感,在程序中,同一個(gè)字母的大小寫(xiě)系統(tǒng)是作不同的處理。在程序中可以用“/*/或“/對(duì)C程序中的任何局部作注釋,以增加程序的可讀性。 C語(yǔ)言本身沒(méi)有輸入輸出語(yǔ)句。輸入和輸出是通過(guò)輸入輸出函數(shù)scanf()和printf()來(lái)實(shí)現(xiàn)的。輸入輸出函數(shù)是通過(guò)標(biāo)準(zhǔn)庫(kù)函數(shù)形式提供給用戶。 4.1.2 C語(yǔ)言與MCS-51單片機(jī)用匯編語(yǔ)言編寫(xiě)MCS51單片機(jī)程序必須要考慮其存儲(chǔ)器結(jié)構(gòu),尤其必須考慮其片內(nèi)數(shù)據(jù)存儲(chǔ)器與特殊功能存放器的使用以及按實(shí)際地址處理端口數(shù)據(jù)。用

3、C語(yǔ)言編寫(xiě)的MCS51單片機(jī)應(yīng)用程序,對(duì)數(shù)據(jù)類型與變量的定義,必須要與單片機(jī)的存儲(chǔ)結(jié)構(gòu)相關(guān)聯(lián),否那么編譯器不能正確地映射定位。 C51包含的數(shù)據(jù)類型、變量存儲(chǔ)模式、輸入輸出處理、函數(shù)等方面與標(biāo)準(zhǔn)的C語(yǔ)言有一定的區(qū)別。 其它的語(yǔ)法規(guī)那么、程序結(jié)構(gòu)及程序設(shè)計(jì)方法等與標(biāo)準(zhǔn)的C語(yǔ)言程序設(shè)計(jì)相同。4.1.3 C51程序結(jié)構(gòu)C51的語(yǔ)法規(guī)定、程序結(jié)構(gòu)及程序設(shè)計(jì)方法都與標(biāo)準(zhǔn)的C語(yǔ)言程序設(shè)計(jì)相同,但C51程序與標(biāo)準(zhǔn)的C程序在以下幾個(gè)方面不一樣:1C51中定義的庫(kù)函數(shù)和標(biāo)準(zhǔn)C語(yǔ)言定義的庫(kù)函數(shù)不同。標(biāo)準(zhǔn)的C語(yǔ)言定義的庫(kù)函數(shù)是按通用微型計(jì)算機(jī)來(lái)定義的,而C51中的庫(kù)函數(shù)是按MCS-51單片機(jī)相應(yīng)情況來(lái)定義的;2C5

4、1中的數(shù)據(jù)類型與標(biāo)準(zhǔn)C的數(shù)據(jù)類型也有一定的區(qū)別,在C51中還增加了幾種針對(duì)MCS-51單片機(jī)特有的數(shù)據(jù)類型;3C51變量的存儲(chǔ)模式與標(biāo)準(zhǔn)C中變量的存儲(chǔ)模式不一樣,C51中變量的存儲(chǔ)模式是與MCS-51單片機(jī)的存儲(chǔ)器緊密相關(guān);4C51與標(biāo)準(zhǔn)C的輸入輸出處理不一樣,C51中的輸入輸出是通過(guò)MCS-51串行口來(lái)完成的,輸入輸出指令執(zhí)行前必須要對(duì)串行口進(jìn)行初始化;5C51與標(biāo)準(zhǔn)C在函數(shù)使用方面也有一定的區(qū)別,C51中有專門的中斷函數(shù)。4.2 C51的數(shù)據(jù)類型 C51的數(shù)據(jù)類型分為根本數(shù)據(jù)類型和組合數(shù)據(jù)類型,情況與標(biāo)準(zhǔn)C中的數(shù)據(jù)類型根本相同,但其中char型與short型相同,float型與double

5、型相同,C51中還有專門針對(duì)于MCS-51單片機(jī)的特殊功能存放器型和位類型。 一 char字符型有signed char和unsigned char之分,默認(rèn)為signed char。對(duì)于signed char,最高位為符號(hào)位,“0表示正數(shù),“1表示負(fù)數(shù),補(bǔ)碼表示,所能表示的數(shù)值范圍是-128+127;對(duì)于unsigned char,它用于定義無(wú)符號(hào)字節(jié)數(shù)據(jù)或字符,取值范圍為0255。unsigned char可以用來(lái)存放無(wú)符號(hào)數(shù),也可以存放西文字符,一個(gè)西文字符占一個(gè)字節(jié),在計(jì)算機(jī)內(nèi)部用ASCII碼存放。 二int整型分singed int和unsigned int。默認(rèn)為signed in

6、t。它們的長(zhǎng)度均為兩個(gè)字節(jié),用于存放一個(gè)雙字節(jié)數(shù)據(jù)。對(duì)于signed int,用于存放兩字節(jié)帶符號(hào)數(shù),補(bǔ)碼表示,數(shù)的范疇為-32768+32767。對(duì)于unsigned int,用于存放兩字節(jié)無(wú)符號(hào)數(shù),數(shù)的范圍為065535。三long長(zhǎng)整型 分singed long和unsigned long。默認(rèn)為signed long。對(duì)于signed long,用于存放四字節(jié)帶符號(hào)數(shù),補(bǔ)碼表示,數(shù)的范疇為-2147483648+2147483647。對(duì)于unsigned long,用于存放四字節(jié)無(wú)符號(hào)數(shù),數(shù)的范圍為04294967295。四float浮點(diǎn)型 float型數(shù)據(jù)的長(zhǎng)度為四個(gè)字節(jié),包含指數(shù)和

7、尾數(shù)兩局部,最高位為符號(hào)位,“1表示負(fù)數(shù),“0表示正數(shù),其次的8位為階碼,最后的23位為尾數(shù)的有效數(shù)位,由于尾數(shù)的整數(shù)局部隱含為“1,所以尾數(shù)的精度為24位。 +124.75=+1111100.11B=+1.111100112+110E=+00000110+01111111=10000101B +127 字節(jié)地址3210浮點(diǎn)數(shù)的內(nèi)容SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM單精度浮點(diǎn)數(shù)的格式一個(gè)浮點(diǎn)數(shù)的取值范圍: -1S2E-1271.M字節(jié)地址3210浮點(diǎn)數(shù)的內(nèi)容01000010111110011000000000000000五* 指針型 指針型本身就是一個(gè)變量,在這個(gè)

8、變量中存放的指向另一個(gè)數(shù)據(jù)的地址。六特殊功能存放器型 sfr為字節(jié)型特殊功能存放器類型,占一個(gè)內(nèi)存單元,sfr16為雙字節(jié)型特殊功能存放器類型,占用兩個(gè)字節(jié)單元,在C51中對(duì)特殊功能存放器的訪問(wèn)必須先用sfr或sfr16進(jìn)行聲明。七位類型在C51中,支持兩種位類型:bit型和sbit型。它們?cè)趦?nèi)存中都只占一個(gè)二進(jìn)制位,其值可以是“1或“0。用bit定義的位變量在C51編譯器編譯時(shí),在不同的時(shí)候位地址是可以變化的,用sbit定義的位變量必須與MCS-51單片機(jī)的一個(gè)可以尋址位單元或可位尋址的字節(jié)單元中的某一位聯(lián)系在一起,在C51編譯器編譯時(shí),其對(duì)應(yīng)的位地址是不可變化的?;緮?shù)據(jù)類型長(zhǎng)度取值范圍u

9、nsigned char1字節(jié)0255signed char1字節(jié)-128+127unsigned int2字節(jié)065535signed int2字節(jié)-32768+32767unsigned long4字節(jié)04294967295signed long4字節(jié)-2147483648+2147483647float4字節(jié)1.175494E-383.402823E+38bit1位0或1Sbit1位0或1sfr1字節(jié)0255sfr162字節(jié)065535KEIL C51編譯器能夠識(shí)別的根本數(shù)據(jù)類型在C51語(yǔ)言程序中,有可能會(huì)出現(xiàn)在運(yùn)算中數(shù)據(jù)類型不一致的情況。C51允許任何標(biāo)準(zhǔn)數(shù)據(jù)類型的隱式轉(zhuǎn)換,隱式轉(zhuǎn)換的

10、優(yōu)先級(jí)順序如下:bitcharintlongfloatsignedunsignedC51除了支持隱式類型轉(zhuǎn)換外,還可以通過(guò)強(qiáng)制類型轉(zhuǎn)換符“對(duì)數(shù)據(jù)類型進(jìn)行人為的強(qiáng)制轉(zhuǎn)換。px=(char xdata * )0 xB0004.3 51的運(yùn)算量4.3.1 常量常量是指在程序執(zhí)行過(guò)程中其值不能改變的量。在C51中支持整型常量、浮點(diǎn)型常量、字符型常量和字符串型常量。一整型常量 整型常量也就是整型常數(shù),根據(jù)其值范圍在計(jì)算機(jī)中分配不同的字節(jié)數(shù)來(lái)存放。在C51中它可以表示成以下幾種形式: 十進(jìn)制整數(shù)。如234、-56、0等。 十六進(jìn)制整數(shù)。以0 x開(kāi)頭表示,如0 x12表示十六進(jìn)制數(shù)12H。 長(zhǎng)整數(shù)。在C51

11、中當(dāng)一個(gè)整數(shù)的值到達(dá)長(zhǎng)整型的范圍,那么該數(shù)按長(zhǎng)整型存放,在存儲(chǔ)器中占四個(gè)字節(jié),如一個(gè)整數(shù)后面加一個(gè)字母L,這個(gè)數(shù)在存儲(chǔ)器中也按長(zhǎng)整型存放。如123L在存儲(chǔ)器中占四個(gè)字節(jié)。二浮點(diǎn)型常量 十進(jìn)制表示形式又稱定點(diǎn)表示形式,由數(shù)字和小數(shù)點(diǎn)組成。如 0.123、34.645等 指數(shù)表示形式為: 數(shù)字 .數(shù)字 e 數(shù)字 例如:123.456e-3、-3.123e2等三字符型常量 字符型常量是用單引號(hào)引起的字符,如a、1、F等。可以是可顯示的ASCII字符,也可以是不可顯示的控制字符。對(duì)不可顯示的控制字符須在前面加上反斜杠“組成轉(zhuǎn)義字符。利用它可以完成一些特殊功能和輸出時(shí)的格式控制。常用的轉(zhuǎn)義字符如表4-2

12、所示。 轉(zhuǎn)義字符含 義ASCII碼(十六進(jìn)制數(shù)) 0空字符(null)00H n換行符(LF)0AH r回車符(CR)0DH t水平制表符(HT)09H b退格符(BS)08H f換頁(yè)符(FF)0CH 單引號(hào)27H ”雙引號(hào)22H 反斜杠5CH表4-2四字符串型常量 字符串型常量由雙引號(hào)“括起的字符組成。如“D、“1234、“ABCD等。一個(gè)字符常量在計(jì)算機(jī)內(nèi)只用一個(gè)字節(jié)存放,一個(gè)字符串常量在內(nèi)存中存放時(shí)不僅雙引號(hào)內(nèi)的字符一個(gè)占一個(gè)字節(jié),而且系統(tǒng)會(huì)自動(dòng)的在后面加一個(gè)轉(zhuǎn)義字符“0作為字符串結(jié)束符。4.3.2 變量定義的格式如下: 存儲(chǔ)種類 數(shù)據(jù)類型說(shuō)明符 存儲(chǔ)器類型 變量名1=初值,變量名2初值

13、;一數(shù)據(jù)類型說(shuō)明符指明變量在存儲(chǔ)器中占用的字節(jié)數(shù)??梢允歉緮?shù)據(jù)類型說(shuō)明符,可以是組合數(shù)據(jù)類型說(shuō)明符,可以是用typedef定義的類型別名?!纠?-1】 typedef的使用。typedef unsigned int WORD;typedef unsigned char BYTE;BYTE a1=0 x12;WORD a2=0 x1234;存儲(chǔ)種類 數(shù)據(jù)類型說(shuō)明符 存儲(chǔ)器類型 變量名1=初值,變量名2初值;二變量名在C51中規(guī)定變量名可以由字母、數(shù)字和下劃線三種字符組成,且第一個(gè)字母必須為字母或下劃線。變量名有兩種:普通變量名和指針變量名。它們的區(qū)別是指針變量名前面要帶“*號(hào)。存儲(chǔ)種類 數(shù)據(jù)類

14、型說(shuō)明符 存儲(chǔ)器類型 變量名1=初值,變量名2初值;三存儲(chǔ)種類存儲(chǔ)種類是指變量在程序執(zhí)行過(guò)程中的作用范圍。C51變量的存儲(chǔ)種類有四種,分別是:自動(dòng)(auto)、外部(extern)、靜態(tài)(static)、存放器(register)。存儲(chǔ)種類 數(shù)據(jù)類型說(shuō)明符 存儲(chǔ)器類型 變量名1=初值,變量名2初值;四存儲(chǔ)器類型存儲(chǔ)器類型與存儲(chǔ)種類完全不同。C51編譯器能識(shí)別的存儲(chǔ)器類型有以下幾種。存儲(chǔ)器類型描 述 data直接尋址的片內(nèi)RAM低128B,訪問(wèn)速度快 bdata片內(nèi)RAM的可位尋址區(qū)(20H2FH),允許字節(jié)和位混合訪問(wèn) idata間接尋址訪問(wèn)的片內(nèi)RAM,允許訪問(wèn)全部片內(nèi)RAM pdata用R

15、i間接訪問(wèn)的片外RAM的低256B xdata用DPTR間接訪問(wèn)的片外RAM,允許訪問(wèn)全部64k片外RAM code程序存儲(chǔ)器ROM64k空間存儲(chǔ)種類 數(shù)據(jù)類型說(shuō)明符 存儲(chǔ)器類型 變量名1=初值,變量名2初值;【例4-2】變量定義存儲(chǔ)種類和存儲(chǔ)器類型相關(guān)情況。 char data varl; /*在片內(nèi)RAM低128B定義用直接尋址方式訪問(wèn)的字符型變量var1*/ int idata var2; /*在片內(nèi)RAM256B定義用間接尋址方式訪問(wèn)的整型變量var2*/ auto unsigned long data var3; /*在片內(nèi)RAM128B定義用直接尋址方式訪問(wèn)的自動(dòng)無(wú)符號(hào)長(zhǎng)整型變量v

16、ar3*/ extern float xdata var4; /*在片外RAM64KB空間定義用間接尋址方式訪問(wèn)的外部實(shí)型變量var4*/ int code var5; /*在ROM空間定義整型變量var5*/ unsign char bdata var6; /*在片內(nèi)RAM位尋址區(qū)20H2FH單元定義可字節(jié)處理和位處理的無(wú)符號(hào)字符型變量var6*/存儲(chǔ)種類 數(shù)據(jù)類型說(shuō)明符 存儲(chǔ)器類型 變量名1=初值,變量名2初值;五特殊功能存放器變量在C51中,允許用戶對(duì)特殊功能存放器進(jìn)行訪問(wèn),訪問(wèn)時(shí)須通過(guò)sfr或sfr16類型說(shuō)明符進(jìn)行定義,定義時(shí)須指明它們所對(duì)應(yīng)的片內(nèi)RAM單元的地址。格式如下: sfr

17、或sfr16 特殊功能存放器名=地址;特殊功能存放器名一般用大寫(xiě)字母表示。地址一般用直接地址形式,【例4-3】特殊功能存放器的定義。 sfr PSW=0 xd0; sfr SCON=0 x98; sfr TMOD=0 x89; sfr P1=0 x90; sfr16 DPTR=0 x82;DPL:82H DPH:83H sfr16 T0=0X8A; TL0:8AH TH0:8BH六位變量 在C51中,允許用戶通過(guò)位類型符定義位變量。位類型符有兩個(gè):bit和sbit??梢远x兩種位變量。 bit位類型符用于定義一般的可位處理位變量。格式如下: bit 位變量名; 注意存儲(chǔ)器類型只能是bdata、

18、data、idata。只能是片內(nèi)RAM的可位尋址區(qū),嚴(yán)格來(lái)說(shuō)只能是bdata?!纠?-4】 bit型變量的定義。bit data a1; /*正確*/bit bdata a2; /*正確*/bit pdata a3; /*錯(cuò)誤*/bit xdata a4; /*錯(cuò)誤*/sbit 位變量名=位地址;【例4-5】sbit型變量的定義。sbit OV=0 xd2;sbit CY=oxd7;unsigned char bdata flag;sbit flag0=flag0;sfr P1=0 x90;sbit P1_0=P10;sbit P1_1=P11;sbit P1_2=P12; sbit P1_7

19、=P17;C51編譯器把MCS-51單片機(jī)的常用的特殊功能存放器和特殊位進(jìn)行了定義,放在一個(gè)“reg51.h或“reg52.h的頭文件中,使用之前用一條預(yù)處理命令#include 把這個(gè)頭文件包含到程序中4.3.3 存儲(chǔ)模式 C51編譯器支持三種存儲(chǔ)模式:SMALL模式、COMPACT模式和LARGE模式。不同的存儲(chǔ)模式對(duì)變量默認(rèn)的存儲(chǔ)器類型不一樣。1SMALL模式。SMALL模式稱為小編譯模式,在SMALL模式下,編譯時(shí),函數(shù)參數(shù)和變量被默認(rèn)在片內(nèi)RAM中,存儲(chǔ)器類型為data。2COMPACT模式。編譯時(shí),函數(shù)參數(shù)和變量被默認(rèn)在片外RAM的低256字節(jié)空間,存儲(chǔ)器類型為pdata。3LAR

20、GE模式。編譯時(shí)函數(shù)參數(shù)和變量被默認(rèn)在片外RAM的64K字節(jié)空間,存儲(chǔ)器類型為xdata。在程序中變量的存儲(chǔ)模式的指定通過(guò)#pragma預(yù)處理命令來(lái)實(shí)現(xiàn)。函數(shù)的存儲(chǔ)模式可通過(guò)在函數(shù)定義時(shí)后面帶存儲(chǔ)模式說(shuō)明。如果沒(méi)有指定,那么系統(tǒng)都隱含為SMALL模式?!纠?-6】變量的存儲(chǔ)模式。#pragma small /*變量的存儲(chǔ)模式為SMALL*/char k1;int xdata m1;#pragma compact /*變量的存儲(chǔ)模式為compact */char k2;int xdata m2;int func1(int x1,int y1) large /*函數(shù)的存儲(chǔ)模式LARGE*/retu

21、rn(x1+y1);int func2(int x2,int y2) /*函數(shù)的存儲(chǔ)模式隱含為SMALL*/ return(x2-y2);4.3.4 絕對(duì)地址的訪問(wèn)一使用C51運(yùn)行庫(kù)中預(yù)定義宏 C51編譯器提供了一組宏定義來(lái)對(duì)51系列單片機(jī)的code、data、pdata和xdata空間進(jìn)行絕對(duì)尋址。規(guī)定只能以無(wú)符號(hào)數(shù)方式訪問(wèn),定義了8個(gè)宏定義,其函數(shù)原型如下:#define CBYTE(unsigned char volatile*)0 x50000L)#define DBYTE(unsigned char volatile*)0 x40000L)#define PBYTE(unsigned

22、 char volatile*)0 x30000L)#define XBYTE(unsigned char volatile*)0 x20000L)#define CWORD(unsigned int volatile*)0 x50000L)#define DWORD(unsigned int volatile*)0 x40000L)#define PWORD(unsigned int volatile*)0 x30000L)#define XWORD(unsigned int volatile*)0 x20000L)這些函數(shù)原型放在absacc.h文件中。使用時(shí)用預(yù)處理命令把該頭文件包含到文

23、件中,形式為:#include 。【例4-7】絕對(duì)地址對(duì)存儲(chǔ)單元的訪問(wèn)#include /*絕對(duì)地址頭文件包含在文件中*/#include /*將存放器頭文件包含在文件中*/#define uchar unsigned char /*uchar為unsigned char*/#define uint unsigned int /*uint為unsigned int*/void main(void)uchar var1;uint var2;var1=XBYTE0 x0005; /*訪問(wèn)片外RAM的0005H字節(jié)單元*/var2=XWORD0 x0002; /*訪問(wèn)片外RAM的0002H字單元*/

24、.while(1); 二通過(guò)指針訪問(wèn)【例4-8】 通過(guò)指針實(shí)現(xiàn)絕對(duì)地址的訪問(wèn)。#define uchar unsigned char /*uchar為unsigned char*/#define uint unsigned int /*符號(hào)uint為unsigned int*/void func(void)uchar data var1;uchar pdata *dp1; /*定義一個(gè)指向pdata區(qū)的指針dp1*/uint xdata *dp2; /*定義一個(gè)指向xdata區(qū)的指針dp2*/uchar data *dp3; /*定義一個(gè)指向data區(qū)的指針dp3*/dp1=0 x30; /*

25、dp1指針賦值,指向pdata區(qū)的30H單元*/dp2=0 x1000; /*dp2指向xdata區(qū)的1000H單元*/*dp1=0 xff; /*將數(shù)據(jù)0 xff送到片外RAM30H單元*/*dp2=0 x1234; /*將數(shù)據(jù)0 x1234送到片外1000H單元*/dp3=&var1; /*dp3指針指向data區(qū)的var1變量*/*dp3=0 x20; /*給變量var1賦值0 x20*/三使用C51擴(kuò)展關(guān)鍵字_at_使用_at_對(duì)指定存儲(chǔ)器空間的絕對(duì)地址訪問(wèn),格式如下: 存儲(chǔ)器類型 數(shù)據(jù)類型說(shuō)明符 變量名 _at_ 地址常數(shù);存儲(chǔ)器類型為data、bdata、idata、pdata等,

26、如省略那么按存儲(chǔ)模式規(guī)定的默認(rèn)存儲(chǔ)器類型確定變量的存儲(chǔ)器區(qū)域;使用_at_定義的變量必須為全局變量?!纠?-9】通過(guò)_at_實(shí)現(xiàn)絕對(duì)地址的訪問(wèn)。#define uchar unsigned char #define uint unsigned intvoid main(void)data uchar x1_at_ 0 x40; /*在data區(qū)字節(jié)變量x1, 地址40H*/xdata uint x2 _at_ 0 x2000; /*在xdata區(qū)定義字變量x2 */x1=0 xff;x2=0 x1234;.while(1);4.4 C51的運(yùn)算符及表達(dá)式4.4.1 賦值運(yùn)算符“= 它的功能是將

27、一個(gè)數(shù)據(jù)的值賦給一個(gè)變量,如x=10。 利用賦值運(yùn)算符將一個(gè)變量與一個(gè)表達(dá)式連接起來(lái)的式子稱為賦值表達(dá)式, 在賦值表達(dá)式的后面加一個(gè)分號(hào)“;就構(gòu)成了賦值語(yǔ)句, 變量=表達(dá)式; 例如: x=8+9; /*將8+9的值賦紿變量x*/ x=y=5; /*將常數(shù)5同時(shí)賦給變量x和y*/ 在C51中,允許在一個(gè)語(yǔ)句中同時(shí)給多個(gè)變量賦值,賦值順序自右向左。 4.4.2 算術(shù)運(yùn)算符C51中支持的算術(shù)運(yùn)算符有:+ 加或取正值運(yùn)算符- 減或取負(fù)值運(yùn)算符* 乘運(yùn)算符/ 除運(yùn)算符% 取余運(yùn)算符對(duì)于除運(yùn)算,如相除的兩個(gè)數(shù)為浮點(diǎn)數(shù),那么運(yùn)算的結(jié)果也為浮點(diǎn)數(shù),如相除的兩個(gè)數(shù)為整數(shù),那么運(yùn)算的結(jié)果也為整數(shù),即為整除。如25

28、.0/20.0結(jié)果為1.25,而25/20結(jié)果為1。 對(duì)于取余運(yùn)算,那么要求參加運(yùn)算的兩個(gè)數(shù)必須為整數(shù),運(yùn)算結(jié)果為它們的余數(shù)。例如:x=5%3,結(jié)果x的值為2。4.4.3 關(guān)系運(yùn)算符C51中有6種關(guān)系運(yùn)算符: 大于= 大于等于3,結(jié)果為真1,而10= =100,結(jié)果為假0。4.4.4 邏輯運(yùn)算符C51有3種邏輯運(yùn)算符:| 邏輯或& 邏輯與! 邏輯非邏輯運(yùn)算符用于求條件式的邏輯值,用邏輯運(yùn)算符將關(guān)系表達(dá)式或邏輯量連接起來(lái)的式子就是邏輯表達(dá)式。 邏輯與,格式: 條件式1 & 條件式2 當(dāng)條件式1與條件式2都為真時(shí)結(jié)果為真非0值, 否那么為假0值。邏輯或,格式: 條件式1 | 條件式2 當(dāng)條件式1與

29、條件式2都為假時(shí)結(jié)果為假0值, 否那么為真非0值。邏輯非,格式: !條件式當(dāng)條件式原來(lái)為真非0值,邏輯非后結(jié)果為假0值。當(dāng)條件式原來(lái)為假0值,邏輯非后結(jié)果為真非0值。例如:假設(shè)a=8,b=3,c=0,那么!a為假,a & b為真,b & c為假, b | c為真。4.4.5 位運(yùn)算符C51中的位運(yùn)算符有: & 按位與 | 按位或 按位異或 按位取反 右移例4-10】設(shè)a=0 x45=01010100B, b=0 x3b=00111011B,那么 a&b=00010000b=0 x10。 a|b=01111111B=0 x7f。 ab=01101111B=0 x6f。 a=10101011B=0

30、 xab。 a2=00001110B=0 x0e。4.4.6 復(fù)合賦值運(yùn)算符 C51語(yǔ)言中支持在賦值運(yùn)算符“=的前面加上其它運(yùn)算符,組成復(fù)合賦值運(yùn)算符。下面是C51中支持的復(fù)合賦值運(yùn)算符: += 加法賦值 + 減法賦值 *= 乘法賦值 /= 除法賦值 %= 取模賦值 &= 邏輯與賦值 |= 邏輯或賦值 = 邏輯異或賦值 = 邏輯非賦值 = 右移位賦值 =2相當(dāng)于x=x2。4.4.7 逗號(hào)運(yùn)算符 在C51語(yǔ)言中,逗號(hào)“,是一個(gè)特殊的運(yùn)算符,可以用它將兩個(gè)或兩個(gè)以上的表達(dá)式連接起來(lái),稱為逗號(hào)表達(dá)式。逗號(hào)表達(dá)式的一般格式為: 表達(dá)式1,表達(dá)式2,表達(dá)式n例如: x=(a=3,6*3) 結(jié)果x的值為1

31、8。4.4.8 條件運(yùn)算符 條件運(yùn)算符“?:是C51語(yǔ)言中唯一的一個(gè)三目運(yùn)算符: 邏輯表達(dá)式?表達(dá)式1:表達(dá)式2當(dāng)邏輯表達(dá)式的值為真非0值時(shí),將計(jì)算的表達(dá)式1的值作為整個(gè)條件表達(dá)式的值;當(dāng)邏輯表達(dá)式的值為假0值時(shí),將計(jì)算的表達(dá)式2的值作為整個(gè)條件表達(dá)式的值。例如:條件表達(dá)式max=(ab)?a:b 執(zhí)行結(jié)果是將a和b中較大的數(shù)賦值給變量max。4.4.9 指針與地址運(yùn)算符變量的指針就是該變量的地址,還可以定義一個(gè)專門指向某個(gè)變量的地址的指針變量。運(yùn)算符: * 指針運(yùn)算符 & 取地址運(yùn)算符 例如:指針變量p中的地址為2000H,那么*p所訪問(wèn)的是地址為2000H的存儲(chǔ)單元,x=*p,實(shí)現(xiàn)把地址為

32、2000H的存儲(chǔ)單元的內(nèi)容送給變量x。 例如:設(shè)變量x的內(nèi)容為12H,地址為2000H,那么&x的值為2000H, 如有一指針變量p,那么通常用p=&x,實(shí)現(xiàn)將x變量的地址送給指針變量p,指針變量p指向變量x, 以后可以通過(guò)*p訪問(wèn)變量x。4.5 表達(dá)式語(yǔ)句及復(fù)合語(yǔ)句4.5.1 表達(dá)式語(yǔ)句在表達(dá)式的后邊加一個(gè)分號(hào)“;就構(gòu)成了表達(dá)式語(yǔ)句 ,如:a=+b*9;x=8;y=7;+k; 僅由個(gè)分號(hào)“;占一行形成一個(gè)表達(dá)式語(yǔ)句,這種語(yǔ)句稱為空語(yǔ)句。 空語(yǔ)句在程序設(shè)計(jì)中通常用于兩種情況:1在程序中為有關(guān)語(yǔ)句提供標(biāo)號(hào),用以標(biāo)記程序執(zhí)行的位置。例如采用下面的語(yǔ)句可以構(gòu)成一個(gè)循環(huán)。repeat:; ; goto

33、 repeat;2在用while語(yǔ)句構(gòu)成的循環(huán)語(yǔ)句后面加一個(gè)分號(hào),形成一個(gè)不執(zhí)行其它操作的空循環(huán)體。這種結(jié)構(gòu)通常用于對(duì)某位進(jìn)行判斷,當(dāng)不滿足條件那么等待,滿足條件那么執(zhí)行?!纠?-11】下面這段子程序用于讀取8051單片機(jī)的串行口的數(shù)據(jù),當(dāng)沒(méi)有接收到那么等待,當(dāng)接收到,接收數(shù)據(jù)后返回,返回值為接收的數(shù)據(jù)。#include char getchar()char c;while(!RI); /當(dāng)接收中斷標(biāo)志位RI為0那么等待, /當(dāng)接收中斷標(biāo)志位為1那么結(jié)束等待。c=SBUF;RI=0;return(c);4.5.2 復(fù)合語(yǔ)句 復(fù)合語(yǔ)句是由假設(shè)干條語(yǔ)句組合而成的一種語(yǔ)句,在C51中,用一個(gè)大括號(hào)“

34、將假設(shè)干條語(yǔ)句括在一起就形成了一個(gè)復(fù)合語(yǔ)句,復(fù)合語(yǔ)句最后不需要以分號(hào)“;結(jié)束,但它內(nèi)部的各條語(yǔ)句仍需以分號(hào)“;結(jié)束。復(fù)合語(yǔ)句的一般形式為:局部變量定義;語(yǔ)句l;語(yǔ)句2;在復(fù)合語(yǔ)句內(nèi)部語(yǔ)句所定義的變量,稱為該復(fù)合語(yǔ)句中的局部變量,它僅在當(dāng)前這個(gè)復(fù)合語(yǔ)句中有效。4.6 C51的輸入輸出在C51的標(biāo)準(zhǔn)函數(shù)庫(kù)中提供了一個(gè)名為“stdio.h的一般I/O函數(shù)庫(kù),它當(dāng)中定義了C51中的輸入和輸出函數(shù)。當(dāng)對(duì)輸入和輸出函數(shù)使用時(shí),須先用預(yù)處理命令“#include 將該函數(shù)庫(kù)包含到文件中。 在C51的一般I/O函數(shù)庫(kù)中定義的I/O函數(shù)都是通過(guò)串行接口實(shí)現(xiàn),在使用I/O函數(shù)之前,應(yīng)先對(duì)MCS-51單片機(jī)的串行接

35、口進(jìn)行初始化。選擇串口工作于方式2,波特率由定時(shí)器/計(jì)數(shù)器1 8位自動(dòng)重載方式溢出率決定。設(shè)系統(tǒng)時(shí)鐘為12MHZ,波特率為2400,那么初始化程序如下:SCON=0 x52;TMOD=0X20;TH1=0 xf3;TR1=1;4.6.1 格式輸出函數(shù)printf()printf(格式控制,輸出參數(shù)表)格式控制是用雙引號(hào)括起來(lái)的字符串,也稱轉(zhuǎn)換控制字符串,它包括三種信息:格式說(shuō)明符、普通字符和轉(zhuǎn)義字符。1格式說(shuō)明符,由“%和格式字符組成,它的作用是用于指明輸出的數(shù)據(jù)的格式輸出,如%d、%f等,它們的具體情況見(jiàn)表4-4。2普通字符,這些字符按原樣輸出,用來(lái)輸出某些提示信息。3轉(zhuǎn)義字符,就是前面介紹

36、的轉(zhuǎn)義字符表4-2,用來(lái)輸出特定的控制符,如輸出轉(zhuǎn)義字符n就是使輸出換一行。輸出參數(shù)表是需要輸出的一組數(shù)據(jù),可以是表達(dá)式。格式字符數(shù)據(jù)類型輸出格式dint帶符號(hào)十進(jìn)制數(shù)uint無(wú)符號(hào)十進(jìn)制數(shù)oint無(wú)符號(hào)八進(jìn)制數(shù)xint無(wú)符號(hào)十六進(jìn)制數(shù),用“af”表示Xint無(wú)符號(hào)十六進(jìn)制數(shù),用“AF”表示ffloat帶符號(hào)十進(jìn)制數(shù)浮點(diǎn)數(shù),形式為-dddd.dddde,Efloat帶符號(hào)十進(jìn)制數(shù)浮點(diǎn)數(shù),形式為-d.ddddEddg,Gfloat自動(dòng)選擇e或f格式中更緊湊的一種輸出格式cchar單個(gè)字符s指針指向一個(gè)帶結(jié)束符的字符串p指針帶存儲(chǔ)器批示符和偏移量的指針,形式為M:aaaa其中,M可分別為:C(co

37、de),D(data),I(idata),P(pdata)如M為a,則表示的是指針偏移量4.6.2 格式輸入函數(shù)scanfscanf的格式如下:scanf格式控制,地址列表格式控制可以包括以下三種信息:空白字符、普通字符和格式說(shuō)明。1空白字符,包含空格、制表符、換行符等,這些字符在輸出時(shí)被忽略。2普通字符,除了以百分號(hào)“%開(kāi)頭的格式說(shuō)明符而外的所有非空白字符,在輸入時(shí)要求原樣輸入。3格式說(shuō)明,由百分號(hào)“%和格式說(shuō)明符組成,用于指明輸入數(shù)據(jù)的格式,具體情況見(jiàn)表4-5。地址列表是由假設(shè)干個(gè)地址組成,它可以是指針變量、取地址運(yùn)算符“&加變量變量的地址或字符串名表示字符串的首地址。格式字符數(shù)據(jù)類型輸出

38、格式dint指針帶符號(hào)十進(jìn)制數(shù)uint指針無(wú)符號(hào)十進(jìn)制數(shù)oint指針無(wú)符號(hào)八進(jìn)制數(shù)xint指針無(wú)符號(hào)十六進(jìn)制數(shù)f,e,Efloat指針浮點(diǎn)數(shù)cchar指針字符sstring指針字符串【例4-12】 使用格式輸入輸出函數(shù)的例子#include /包含特殊功能存放器庫(kù)#include /包含I/O函數(shù)庫(kù)void main(void) /主函數(shù)int x,y; /定義整型變量x和ySCON=0 x52; /串口初始化TMOD=0 x20;TH1=0XF3;TR1=1;printf(“input x,y:n); /輸出提示信息scanf(“%d%d,&x,&y); /輸入x和y的值printf(“n)

39、; /輸出換行printf(“%d+%d=%d,x,y,x+y); /按十進(jìn)制形式輸出printf(“n); /輸出換行printf(“%xH+%xH=%XH,x,y,x+y); /按十六進(jìn)制形式輸出while(1); /結(jié)束4.7 C51程序根本結(jié)構(gòu)與相關(guān)語(yǔ)句4.7.1 C51的根本結(jié)構(gòu)一順序結(jié)構(gòu)順序結(jié)構(gòu):程序由低地址到高地址依次執(zhí)行,圖4.3給出順序結(jié)構(gòu)流程圖,程序先執(zhí)行A操作,然后再執(zhí)行B操作。AB圖4.3 順序結(jié)構(gòu)流程圖程序先對(duì)一個(gè)條件進(jìn)行判斷。當(dāng)條件成立,即條件語(yǔ)句為“真時(shí),執(zhí)行一個(gè)分支,當(dāng)條件不成立時(shí),即條件語(yǔ)句為“假時(shí),執(zhí)行另一個(gè)分支。二選擇結(jié)構(gòu)條件P語(yǔ)句A語(yǔ)句B成立不成立實(shí)現(xiàn)選

40、擇結(jié)構(gòu)的語(yǔ)句為if/else,if/else if語(yǔ)句。多分支結(jié)構(gòu)既可以通過(guò)if和else if語(yǔ)句嵌套實(shí)現(xiàn),也可用swith/case語(yǔ)句實(shí)現(xiàn)。循環(huán)結(jié)構(gòu)又分為兩種:當(dāng)while型循環(huán)結(jié)構(gòu);直到do.while型循環(huán)結(jié)構(gòu)。1當(dāng)型循環(huán)結(jié)構(gòu)當(dāng)條件P成立為“真時(shí),重復(fù)執(zhí)行語(yǔ)句A,當(dāng)條件不成立為“假時(shí)才停止重復(fù),執(zhí)行后面的程序。三循環(huán)結(jié)構(gòu)條件P語(yǔ)句A成立不成立圖4.3 當(dāng)型循環(huán)結(jié)構(gòu) 2直到型循環(huán)結(jié)構(gòu)先執(zhí)行語(yǔ)句A,再判斷條件P,當(dāng)條件成立為“真時(shí),再重復(fù)執(zhí)行語(yǔ)句A,直到條件不成立為“假時(shí)才停止重復(fù),執(zhí)行后面的程序。條件P語(yǔ)句A成立不成立圖4.4 直到型循環(huán)結(jié)構(gòu)構(gòu)成循環(huán)結(jié)構(gòu)的語(yǔ)句主要有:while、do

41、while、for、goto等。4.7.2 if語(yǔ)句if語(yǔ)句是C51中的一個(gè)根本條件選擇語(yǔ)句,它通常有三種格式:1if 表達(dá)式 語(yǔ)句;2if 表達(dá)式 語(yǔ)句1; else 語(yǔ)句2;3if 表達(dá)式1 語(yǔ)句1; else if 表達(dá)式2 語(yǔ)句2; else if 表達(dá)式3 語(yǔ)句3; else if 表達(dá)式n-1 語(yǔ)句n-1; else 語(yǔ)句n【例4-13】 if語(yǔ)句的用法。1if (x!=y) printf(“x=%d,y=%dn,x,y);執(zhí)行上面語(yǔ)句時(shí),如果x不等于y,那么輸出x的值和y的值。2if (xy) max=x; else max=y;執(zhí)行上面語(yǔ)句時(shí),如x大于y成立,那么把x送給最大值

42、變量max,如x大于y不成立,那么把y送給最大值變量max。使max變量得到x、y中的大數(shù)。3if (score=90) printf(“Your result is an An); else if (score=80) printf(“Your result is an Bn); else if (score=70) printf(“Your result is an Cn); else if (score=60) printf(“Your result is an Dn); else printf(“Your result is an En);執(zhí)行上面語(yǔ)句后,能夠根據(jù)分?jǐn)?shù)score分別打出

43、A、B、C、D、E五個(gè)等級(jí)。4.7.3 switch/case語(yǔ)句switch是C51中提供的專門處理多分支結(jié)構(gòu)的多分支選擇語(yǔ)句。它的格式如下:switch 表達(dá)式case 常量表達(dá)式1:語(yǔ)句1;break;case 常量表達(dá)式2:語(yǔ)句2;break;case 常量表達(dá)式n:語(yǔ)句n;break;default:語(yǔ)句n+1;說(shuō)明如下:1switch后面括號(hào)內(nèi)的表達(dá)式,可以是整型或字符型表達(dá)式2當(dāng)該表達(dá)式的值與某一“case后面的常量表達(dá)式的值相等時(shí),就執(zhí)行該“case后面的語(yǔ)句,然后遇到break語(yǔ)句退出switch語(yǔ)句。假設(shè)表達(dá)式的值與所有case后的常量表達(dá)式的值都不相同,那么執(zhí)行defau

44、lt后面的語(yǔ)句,然后退出switch結(jié)構(gòu)。3每一個(gè)case常量表達(dá)式的值必須不同,否那么會(huì)自相矛盾4case語(yǔ)句和default語(yǔ)句的出現(xiàn)次序?qū)?zhí)行過(guò)程沒(méi)有影響。5每個(gè)case語(yǔ)句后面可以有“break,也可以沒(méi)有。有break語(yǔ)句,執(zhí)行到break那么退出switch結(jié)構(gòu),假設(shè)沒(méi)有,那么會(huì)順次執(zhí)行后面的語(yǔ)句,直到遇到break或結(jié)束。6每一個(gè)case語(yǔ)句后面可以帶一個(gè)語(yǔ)句,也可以帶多個(gè)語(yǔ)句,還可以不帶。語(yǔ)句可以用花括號(hào)括起,也可以不括。7多個(gè)case可以共用一組執(zhí)行語(yǔ)句。【例4-14】 switch/case語(yǔ)句的用法。對(duì)學(xué)生成績(jī)劃分為AD,對(duì)應(yīng)不同的百分制分?jǐn)?shù),要求根據(jù)不同的等級(jí)打印出它的

45、對(duì)應(yīng)百分?jǐn)?shù)。可以通過(guò)下面的switch/case語(yǔ)句實(shí)現(xiàn)。switchgradecase A;printf90100n;break;case B;printf8090n;break;case C;printf7080n;break;case D;printf6070n;break;case E;printf60n;break;default;printferrorn4.7.4 while語(yǔ)句 while語(yǔ)句在C51中用于實(shí)現(xiàn)當(dāng)型循環(huán)結(jié)構(gòu),它的格式如下: while表達(dá)式 語(yǔ)句; /*循環(huán)體*/ while語(yǔ)句后面的表達(dá)式是能否循環(huán)的條件,后面的語(yǔ)句是循環(huán)體。當(dāng)表達(dá)式為非0真時(shí),就重復(fù)執(zhí)行循環(huán)體

46、內(nèi)的語(yǔ)句;當(dāng)表達(dá)式為0假,那么中止while循環(huán),程序?qū)?zhí)行循環(huán)結(jié)構(gòu)之外的下一條語(yǔ)句。#include /包含特殊功能存放器庫(kù)#include /包含I/O函數(shù)庫(kù)void main(void) /主函數(shù)int i,s=0; /定義整型變量x和yi=1;SCON=0 x52; /串口初始化TMOD=0 x20;TH1=0XF3;TR1=1;while (i=100) /累加1100之和在s中s=s+i;i+;printf(“1+2+3+100=%dn,s);while(1);【例4-15】通過(guò)while語(yǔ)句計(jì)算并輸出1100的累加和程序執(zhí)行的結(jié)果:1+2+3+100=50504.7.5 do w

47、hile語(yǔ)句do while語(yǔ)句在C51中用于實(shí)現(xiàn)直到型循環(huán)結(jié)構(gòu),格式如下: do 語(yǔ)句; /*循環(huán)體*/ while表達(dá)式; 它的特點(diǎn)是:先執(zhí)行循環(huán)體中的語(yǔ)句,后判斷表達(dá)式。 如表達(dá)式成立真,那么再執(zhí)行循環(huán)體,然后又判斷,直到有表達(dá)式不成立假時(shí),退出循環(huán),執(zhí)行do while結(jié)構(gòu)的下一條語(yǔ)句。 do while語(yǔ)句在執(zhí)行時(shí),循環(huán)體內(nèi)的語(yǔ)句至少會(huì)被執(zhí)行一次。【例4-16】 通過(guò)do while語(yǔ)句計(jì)算并輸出1100的累加和。#include /包含特殊功能存放器庫(kù)#include /包含I/O函數(shù)庫(kù)void main(void) /主函數(shù)int i,s=0; /定義整型變量x和yi=1;SCO

48、N=0 x52; /串口初始化TMOD=0 x20;TH1=0XF3;TR1=1;do /累加1100之和在s中s=s+i;i+;while (i=100);printf(“1+2+3+100=%dn,s);while(1);程序執(zhí)行的結(jié)果:1+2+3+100=5050for語(yǔ)句是使用最靈活、用得最多的循環(huán)控制語(yǔ)句。它可以用于循環(huán)次數(shù)已經(jīng)確定的情況,也可以用于循環(huán)次數(shù)不確定的情況。格式如下:for表達(dá)式1;表達(dá)式2;表達(dá)式3語(yǔ)句; /*循環(huán)體*/for語(yǔ)句后面帶三個(gè)表達(dá)式,它的執(zhí)行過(guò)程如下:1先求解表達(dá)式1的值。2求解表達(dá)式2的值,如表達(dá)式2的值為真,那么執(zhí)行循環(huán)休中的語(yǔ)句,求解表達(dá)式3,轉(zhuǎn)到

49、2繼續(xù)執(zhí)行。 如表達(dá)式2的值為假,那么結(jié)束for循環(huán),轉(zhuǎn)到最后一步。4.7.6 for語(yǔ)句【例4-17】 用for語(yǔ)句計(jì)算并輸出1100的累加和。#include /包含特殊功能存放器庫(kù)#include /包含I/O函數(shù)庫(kù)void main(void) /主函數(shù)int i,s=0; /定義整型變量x和ySCON=0 x52; /串口初始化TMOD=0 x20;TH1=0XF3;TR1=1;for (i=1;i=100;i+) s=s+i; /累加1100之和在s中printf(“1+2+3+100=%dn,s);while(1);程序執(zhí)行的結(jié)果:1+2+3+100=5050 在一個(gè)循環(huán)的循環(huán)體

50、中允許又包含一個(gè)完整的循環(huán)結(jié)構(gòu),這種結(jié)構(gòu)稱為循環(huán)的嵌套。外面的循環(huán)稱為外循環(huán),里面的循環(huán)稱為內(nèi)循環(huán),如果在內(nèi)循環(huán)的循環(huán)體內(nèi)又包含循環(huán)結(jié)構(gòu),就構(gòu)成了多重循環(huán)。在C51中,允許三種循環(huán)結(jié)構(gòu)相互嵌套?!纠?-18】用嵌套結(jié)構(gòu)構(gòu)造一個(gè)延時(shí)程序。void delay(unsigned int x)unsigned char j;while(x-)for (j=0;j125;j+);4.7.7 循環(huán)的嵌套 break和continue語(yǔ)句通常用于循環(huán)結(jié)構(gòu)中,用來(lái)跳出循環(huán)結(jié)構(gòu)。但是二者又有所不同。1break語(yǔ)句break語(yǔ)句可以跳出switch結(jié)構(gòu),使程序繼續(xù)執(zhí)行switch結(jié)構(gòu)后面的一個(gè)語(yǔ)句。還可以從循

51、環(huán)體中跳出循環(huán),執(zhí)行循環(huán)結(jié)構(gòu)下面的語(yǔ)句。4.7.8 break和continue語(yǔ)句 2continue語(yǔ)句continue語(yǔ)句用在循環(huán)結(jié)構(gòu)中,用于結(jié)束本次循環(huán),跳過(guò)循環(huán)體中continue下面尚未執(zhí)行的語(yǔ)句,直接進(jìn)行下一次是否執(zhí)行循環(huán)的判定。【例4-19】下面一段程序用于計(jì)算圓的面積,當(dāng)計(jì)算到面積大于100時(shí),由break語(yǔ)句跳出循環(huán)。for (r=1;r100) break;printf(“%fn,area);【例4-20】 輸出100200間不能被3整除的數(shù)。for (i=100;iy?x:y;returnz;int max(int x,int y)int z;z=xy?x:y;retu

52、rnz;4reentrant修飾符 這個(gè)修飾符用于把函數(shù)定義為可重入函數(shù)。就是允許被遞歸調(diào)用的函數(shù)。關(guān)于重入函數(shù),注意以下幾點(diǎn):1用reentrant修飾的重入函數(shù)被調(diào)用時(shí),實(shí)參表內(nèi)不允許使用bit類型的參數(shù)。函數(shù)體內(nèi)也不允許存在任何關(guān)于位變量的操作,更不能返回bit類型的值。2編譯時(shí),系統(tǒng)為重入函數(shù)在內(nèi)部或外部存儲(chǔ)器中建立一個(gè)模擬堆棧區(qū),稱為重入棧。重入函數(shù)的局部變量及參數(shù)被放在重入棧中,使重入函數(shù)可以實(shí)現(xiàn)遞歸調(diào)用。3在參數(shù)的傳遞上,實(shí)際參數(shù)可以傳遞給間接調(diào)用的重入函數(shù)。無(wú)重入屬性的間接調(diào)用函數(shù)不能包含調(diào)用參數(shù),但是可以使用定義的全局變量來(lái)進(jìn)行參數(shù)傳遞。函數(shù)類型 函數(shù)名(形式參數(shù)表) ree

53、ntrantinterruptmusing n5interrupt m修飾符interrupt m 中斷函數(shù)必須通過(guò)它進(jìn)行修飾。當(dāng)函數(shù)定義時(shí)用了interrupt m修飾符,系統(tǒng)編譯時(shí)把對(duì)應(yīng)函數(shù)轉(zhuǎn)化為中斷函數(shù),自動(dòng)加上程序頭段和尾段。 在該修飾符中,m的取值為031,對(duì)應(yīng)的中斷情況如下:0外部中斷01定時(shí)/計(jì)數(shù)器T02外部中斷13定時(shí)/計(jì)數(shù)器T14串行口中斷5定時(shí)/計(jì)數(shù)器T2其它值預(yù)留。編寫(xiě)MCS-51中斷函數(shù)注意如下:1中斷函數(shù)不能進(jìn)行參數(shù)傳遞,如果中斷函數(shù)中包含任何參數(shù)聲明都將導(dǎo)致編譯出錯(cuò)。2中斷函數(shù)沒(méi)有返回值。3在任何情況下都不能直接調(diào)用中斷函數(shù)。4如果在中斷函數(shù)中調(diào)用了其它函數(shù),那么被

54、調(diào)用函數(shù)所使用的存放器必須與中斷函數(shù)相同。5程序開(kāi)始處對(duì)ACC、B、DPH、DPL和PSW入棧,結(jié)束時(shí)出棧。中斷函數(shù)未加using n修飾符的,開(kāi)始時(shí)還要將R0R1入棧,結(jié)束時(shí)出棧。6C51編譯器從絕對(duì)地址8m+3處產(chǎn)生一個(gè)中斷向量,即到中斷函數(shù)入口地址的絕對(duì)跳轉(zhuǎn)。7中斷函數(shù)最好寫(xiě)在文件的尾部。【例4-22】編寫(xiě)一個(gè)用于統(tǒng)計(jì)外中斷0的中斷次數(shù)的中斷效勞程序extern int x;void int0() interrupt 0 using 1 x+;6using n修飾符修飾符using n用于指定本函數(shù)內(nèi)部使用的工作存放器組,其中n表示存放器組號(hào)。 1參加using n后,C51在編譯時(shí)自動(dòng)

55、的在函數(shù)的開(kāi)始處和結(jié)束處參加以下指令。PUSH PSW ;標(biāo)志存放器入棧MOV PSW,#與存放器組號(hào)相關(guān)的常量 POP PSW ;標(biāo)志存放器出棧 2using n修飾符不能用于有返回值的函數(shù),因?yàn)镃51函數(shù)的返回值是放在存放器中的。如存放器組改變了,返回值就會(huì)出錯(cuò)。4.8.2 函數(shù)的調(diào)用與聲明一函數(shù)的調(diào)用函數(shù)調(diào)用的一般形式如下: 函數(shù)名實(shí)參列表;對(duì)于有參數(shù)的函數(shù)調(diào)用,假設(shè)實(shí)參列表包含多個(gè)實(shí)參,那么各個(gè)實(shí)參之間用逗號(hào)隔開(kāi)。 按照函數(shù)調(diào)用在主調(diào)函數(shù)中出現(xiàn)的位置,函數(shù)調(diào)用方式有以下三種:1函數(shù)語(yǔ)句。把被調(diào)用函數(shù)作為主調(diào)用函數(shù)的一個(gè)語(yǔ)句。2函數(shù)表達(dá)式。函數(shù)被放在一個(gè)表達(dá)式中,以一個(gè)運(yùn)算對(duì)象的方式出現(xiàn)

56、。這時(shí)的被調(diào)用函數(shù)要求帶有返回語(yǔ)句,以返回一個(gè)明確的數(shù)值參加表達(dá)式的運(yùn)算。3函數(shù)參數(shù)。被調(diào)用函數(shù)作為另一個(gè)函數(shù)的參數(shù)。二自定義函數(shù)的聲明在C51中,函數(shù)原型一般形式如下: extern 函數(shù)類型 函數(shù)名形式參數(shù)表;函數(shù)的聲明后面要加分號(hào)。 如果聲明的函數(shù)在文件內(nèi)部,那么聲明時(shí)不用extern,如果聲明的函數(shù)不在文件內(nèi)部,而在另一個(gè)文件中,聲明時(shí)須帶extern,指明使用的函數(shù)在另一個(gè)文件中。#include /包含特殊功能存放器庫(kù)#include /包含I/O函數(shù)庫(kù)int max(int x,int y); /對(duì)max函數(shù)進(jìn)行聲明void main(void) /主函數(shù)int a,b;SCON

57、=0 x52; /串口初始化TMOD=0 x20;TH1=0XF3;TR1=1;printf(“please input a,b: );scanf(“%d,%d,&a,&b);printf(“n);printf(“max is:%dn,max(a,b);while(1);int max(int x,int y)int z;z=(x=y?x:y);return(z);【例4-23】函數(shù)的使用程序serial_initial.c#include #include void serial_initial(void) /主函數(shù)SCON=0 x52; TMOD=0 x20;TH1=0XF3;TR1=1;

58、程序y1.c#include #include extern serial_initial();void main(void)int a,b;serial_initial();printf (“please input a,b:);scanf(“%d,%d,&a,&b);printf(“n);printf(“max is:%dn,a=b?a:b);while(1);【例4-24】 外部函數(shù)的使用4.8.3 函數(shù)的嵌套與遞歸一函數(shù)的嵌套 在一個(gè)函數(shù)的調(diào)用過(guò)程中調(diào)用另一個(gè)函數(shù)。C51編譯器通常依靠堆棧來(lái)進(jìn)行參數(shù)傳遞,堆棧設(shè)在片內(nèi)RAM中,而片內(nèi)RAM的空間有限,因而嵌套的深度比較有限,一般在幾層以

59、內(nèi)。如果層數(shù)過(guò)多,就會(huì)導(dǎo)致堆??臻g不夠而出錯(cuò)。 【例4-25】 函數(shù)的嵌套調(diào)用#include #include extern serial_initial();int max(int a,int b)int z;z=a=b?a:b;return(z);int add(int c,int d,int e,int f)int result;result=max(c,d)+max(e,f); /調(diào)用maxreturn(result);main()int final;serial_initial();final=add(7,5,2,8);printf(“%d,final);while(1);二函數(shù)的

60、遞歸 遞歸調(diào)用是嵌套調(diào)用的一個(gè)特殊情況。如果在調(diào)用一個(gè)函數(shù)過(guò)程中又出現(xiàn)了直接或間接調(diào)用該函數(shù)本身,那么稱為函數(shù)的遞歸調(diào)用。 在數(shù)學(xué)計(jì)算中,一個(gè)數(shù)n的階乘等于該數(shù)本身乘以數(shù)n-1的階乘,即n!=n(n-1)!,用n-1的階乘來(lái)表示n的階乘就是一種遞歸表示方法。在程序設(shè)計(jì)中通過(guò)函數(shù)遞歸調(diào)用來(lái)實(shí)現(xiàn)。程序如下: 在函數(shù)的遞歸調(diào)用中要防止出現(xiàn)無(wú)終止的自身調(diào)用,應(yīng)通過(guò)條件控制結(jié)束遞歸調(diào)用,使得遞歸的次數(shù)有限。下面是一個(gè)利用遞歸調(diào)用求n!的例子。#include #include extern serial_initial();int fac(int n) reentrantint result;if (n

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論