版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第5章C51應(yīng)用基礎(chǔ)
5.1
KeilC51簡(jiǎn)介5.2
C51程序設(shè)計(jì)基礎(chǔ)知識(shí)
5.3
C51的函數(shù)與數(shù)組5.4
C51的編程規(guī)范5.5
C51的基本應(yīng)用
習(xí)題與思考題
C語言是一種通用的計(jì)算機(jī)語言。它既可以用來編寫系統(tǒng)程序,也可以用來編寫應(yīng)用程序。它同時(shí)具有匯編語言和高級(jí)語言的特點(diǎn)。在早期單片機(jī)開發(fā)中,基本上是使用匯編語言,也有使用BASIC等高級(jí)語言進(jìn)行開發(fā)的。20世紀(jì)90年代中期以后,使用C語言開發(fā)單片機(jī)成為一種流行的趨勢(shì),因?yàn)樗哂惺褂梅奖恪⒕幊绦矢呒胺抡嬲{(diào)試容易等突出特點(diǎn)。C51的版本很多,本章以德國KeilSoftware公司專門為8051單片機(jī)開發(fā)的KeilC51編譯器為例,對(duì)51系列單片機(jī)如何使用C51進(jìn)行編程作一簡(jiǎn)單的介紹。5.1
KeilC51簡(jiǎn)介
1.KeilC51主要模塊
KeilC51的主要模塊有:
·C51優(yōu)化C編譯器;
·A51宏匯編器;
·8051工具連接器、目標(biāo)文件轉(zhuǎn)換器、庫管理器;
·Windows版dScope源程序調(diào)試器/模擬器;
·Windows版μVision集成開發(fā)環(huán)境。
2.KeilC51編程步驟
使用KeilC51編程和用其他軟件開發(fā)項(xiàng)目時(shí)大致一樣,按下列步驟編程:
(1)創(chuàng)建C或匯編語言的源程序;
(2)編譯或匯編源文件運(yùn)算符;
(3)糾正源文件中的錯(cuò)誤;
(4)連接產(chǎn)生目標(biāo)文件;
(5)模擬調(diào)試用戶程序。
KeilC51既可以編輯、編譯和調(diào)試匯編語言程序,也可以編輯、編譯和調(diào)試C51程序,是一個(gè)基于Windows平臺(tái)的集成開發(fā)環(huán)境。它不但可以仿真模擬一般的程序運(yùn)行,而且還可以仿真模擬I/O口、定時(shí)器/計(jì)數(shù)器、串行口及中斷等單片機(jī)特有的功能部件,甚至可以模擬在某個(gè)I/O引腳上輸入一個(gè)方波或正弦波,其功能非常強(qiáng)大。鑒于本書篇幅有限,只就C51編程的一些基本方法作簡(jiǎn)要的介紹,如需深入了解可參閱有關(guān)專門介紹KeilC51的書籍。5.2
C51程序設(shè)計(jì)基礎(chǔ)知識(shí)
5.2.1
C51特點(diǎn)
C51是針對(duì)8051系列單片機(jī)開發(fā)的高級(jí)語言。它與一般的標(biāo)準(zhǔn)C語言基本一致,但根據(jù)8051單片機(jī)的硬件特點(diǎn)作了少量的擴(kuò)展和重新定義。例如,C51支持位變量,printf函數(shù)由串行口輸出而不是屏幕輸出,以及不同廠家的單片機(jī)為描述其硬件的差異需要使用特定的頭文件等。C51主要有以下特點(diǎn):(1)語言簡(jiǎn)潔、緊湊,使用方便、靈活。(2)運(yùn)算符極其豐富。(3)生成的目標(biāo)代碼質(zhì)量高,程序執(zhí)行效率高(與匯編語言相比)。(4)可移植性好(與匯編語言相比)。(5)可以直接操作硬件。5.2.2一個(gè)簡(jiǎn)單的C51例子一個(gè)完整的C51程序是由一個(gè)main()函數(shù)(又稱主函數(shù))和若干個(gè)其他函數(shù)結(jié)合而成的,或僅由一個(gè)main()函數(shù)構(gòu)成。
【例5[CD*2]1】[HT][ST]僅由main()函數(shù)構(gòu)成的C語言程序。
#include<reg51.h>
#include<stdio.h>
#include<intrins.h>
voidmain(void)
{
P0=0x00;
P1=0x01;
P2=0x02;
P3=0x03;
}程序說明:
(1)Reg51.h為寄存器說明頭文件;stdio.h為輸入/輸出說明頭文件;intrins.h為部分特殊指令說明頭文件。可根據(jù)對(duì)8051編程的需要選擇不同的頭文件,一般情況下若只用于簡(jiǎn)單控制,這三個(gè)頭文件就夠了。具體頭文件包含的內(nèi)容見相關(guān)資料。一般編程時(shí)先寫上這三個(gè)頭文件,如果編譯出錯(cuò)再根據(jù)錯(cuò)誤信息加其他的頭文件。
(2)main()函數(shù)為C51的主函數(shù)。由于P0、P1、P2及P3口在reg51.h中已有說明,故可以直接賦值。運(yùn)行結(jié)果:將P0、P1、P2及P3口依次置為0x00、0x01、0x02及0x03(其中0x00、0x01、0x02及0x03為C語言中十六進(jìn)制0、1、2及3的表示方法)。在KeilC51中的運(yùn)行結(jié)果如圖5-1所示。圖5-1例5-1的運(yùn)行結(jié)果圖5.2.3
C51的基礎(chǔ)知識(shí)標(biāo)識(shí)符為程序中某個(gè)對(duì)象的名字。這些對(duì)象可以是變量、常量、函數(shù)、數(shù)據(jù)類型及語句等。標(biāo)識(shí)符命名規(guī)則如下:(1)為有效字符,即只能由字母、數(shù)字和下劃線組成,且以字母或下劃線開頭。(2)在有效長(zhǎng)度范圍內(nèi),有效長(zhǎng)度隨系統(tǒng)而異,但至少前8個(gè)字符有效。如果超長(zhǎng),則超長(zhǎng)部分被舍棄。關(guān)鍵字是C51用于說明類型、語句功能等專門用途的標(biāo)識(shí)符,又稱保留字,如int、printf等。標(biāo)準(zhǔn)C語言的關(guān)鍵字共有32個(gè)。根據(jù)關(guān)鍵字的作用,可將其分為數(shù)據(jù)類型關(guān)鍵字、控制語句關(guān)鍵字、存儲(chǔ)類型關(guān)鍵字和其他關(guān)鍵字四類。C51結(jié)合單片機(jī)的特點(diǎn)在此基礎(chǔ)上又?jǐn)U展了一部分關(guān)鍵字,如data、sfr及bit等。5.2.4存儲(chǔ)空間定義
單片機(jī)由于體積小,因此不可能像微型計(jì)算機(jī)那樣有很大的存儲(chǔ)器,如8051內(nèi)部只有128字節(jié)的RAM。因而,首先必須根據(jù)需要指定各種變量的存放位置,這一點(diǎn)是C51與標(biāo)準(zhǔn)C語言的主要差異。C51定義的存儲(chǔ)器類型關(guān)鍵字及對(duì)應(yīng)存儲(chǔ)變量的存儲(chǔ)空間如表5-1所示。表5-1
C51定義的存儲(chǔ)器類型與存儲(chǔ)空間5.2.5
C51數(shù)據(jù)類型
C51的數(shù)據(jù)類型有以下幾類。
1)Char:字符型(8位整數(shù))字符型數(shù)據(jù)的長(zhǎng)度為1個(gè)字節(jié),可分為以下兩種:(1)unsignedchar:字符或無符號(hào)8位整數(shù)。數(shù)據(jù)范圍:0~256。(2)signedchar:有符號(hào)8位整數(shù)。其最高位為符號(hào)位,數(shù)據(jù)范圍:-128~+127。默認(rèn)值為signedchar。
2)Int:整型(16位整數(shù))整型數(shù)據(jù)的長(zhǎng)度為2個(gè)字節(jié),可分為以下兩種:(1)unsignedint:無符號(hào)16位整數(shù)。數(shù)據(jù)范圍:0~65536。(2)signedint:有符號(hào)16位整數(shù)。其最高位為符號(hào)位,數(shù)據(jù)范圍:-32768~+32768。默認(rèn)值為signedint。
3)long:長(zhǎng)整型(32位整數(shù))長(zhǎng)整型數(shù)據(jù)的長(zhǎng)度為4個(gè)字節(jié),可分為以下兩種:(1)unsignedlong:無符號(hào)16位整數(shù)。數(shù)據(jù)范圍:0~4294967295。(2)signedlong:有符號(hào)16位整數(shù)。其最高位為符號(hào)位,數(shù)據(jù)范圍:-2147483648~+2147483647。默認(rèn)值為signedlong。
4)float:單精度浮點(diǎn)型單精度浮點(diǎn)型數(shù)據(jù)的長(zhǎng)度為4個(gè)字節(jié)。
5)*:指針型指針型數(shù)據(jù)是存放數(shù)據(jù)地址的變量,即它存放的是需要尋址數(shù)據(jù)的地址。定義和使用指針型變量可以很方便地對(duì)8051單片機(jī)各部分物理地址直接進(jìn)行操作。其實(shí)際應(yīng)用參考后面的應(yīng)用實(shí)例。
6)bit:位型位型數(shù)據(jù)是C51編譯器提供的一種擴(kuò)展數(shù)據(jù)類型。使用它可以定義一個(gè)位變量,但不能定義位指針,也不能定義位數(shù)組。例如:
intbdataibase;/*Bit-addressableint*/
charbdatabary[4];/*Bit-addressablearray*/
sbitmybit0=ibase∧0;/*bit0ofibase*/
sbitmybit15=ibase∧15;/*bit15ofibase*/
sbitAry07=bary[0]∧7;/*bit7ofbary[0]*/
sbitAry37=bary[3]∧7;/*bit7ofbary[3]*/
7)sfr:特殊功能寄存器型特殊功能寄存器型數(shù)據(jù)是C51編譯器提供的一種擴(kuò)展數(shù)據(jù)類型,用于訪問8051單片機(jī)的特殊功能寄存器,長(zhǎng)度為1個(gè)字節(jié),是一個(gè)僅用于特殊功能寄存器空間的8位無符號(hào)的整型變量。例如:
SfrP0=0x80/*Port-0,address80H*/
SfrP1=0x90/*Port-1,address90H*/
SfrP2=0xA0/*Port-2,address0A0H*/
SfrP3=0xB0/*Port-3,address0B0H*/
8)sfr16:16位特殊功能寄存器型
16位特殊功能寄存器型數(shù)據(jù)是C51編譯器提供的一種擴(kuò)展數(shù)據(jù)類型。此類型數(shù)據(jù)用于以16位方式訪問8051單片機(jī)的特殊功能寄存器,數(shù)據(jù)長(zhǎng)度為2個(gè)字節(jié),也是一個(gè)僅用于特殊功能寄存器空間的16位無符號(hào)的整型變量。例如:
Sfr16T2=0xCC;/*Timer2:T2L0CCh,T2H
0CDH*/
Sfr16RCAP2=0xCA; /*RCAP2L0CAH,RCAP2H
0CBH*/
9)sbit:可尋址位型可尋址位型數(shù)據(jù)是C51寄存器提供的一種擴(kuò)展數(shù)據(jù)類型。它用于定義和訪問8051內(nèi)部RAM及特殊功能寄存器中可位尋址的空間。例如:
SfrPSW=0xD0;
SfrIE=0xA8;
SbitOV=PSW∧2;
SbitCY=PSW∧7;
SbitEA=IE∧7;表5-2為C51支持的所有數(shù)據(jù)類型一覽表。表5-2
C51支持的數(shù)據(jù)類型5.2.6
C51存儲(chǔ)空間的定義在C51中,變量存儲(chǔ)器空間按下列兩種方式定義均可:方式1[數(shù)據(jù)類型][存儲(chǔ)器類型]變量名方式2[存儲(chǔ)器類型][數(shù)據(jù)類型]變量名例如:UnsignedchardataI,num;/*在內(nèi)部RAM中定義變量1,
num*/Unsignedchardatadisplay_data_buff[8];/*數(shù)據(jù)顯示緩沖區(qū)*/Unsignedchardatadisplay_code_buff[8];/*顯示字形緩沖區(qū)*/Unsignedcharcodedisplay_code[16]={0x0C0,0x0F9,0x0A4,0x0B0,0x99,0x92,0x82,0x0F8,/*0,1,2,3,4,5,6,7*/0x80,0x90,0x88,0x83,0x0C6,0x0A1,0x86,0x8E/*8,9,A,B,C,D,E,F(xiàn)*/};其中,display_data_buff[8]、display_code_buff[8]、I、num被定義在內(nèi)部RAM中,而display_code[16]是常數(shù),因此被定義在代碼區(qū)中。5.2.7
C51的常量
C51的常量可分為以下幾種。
1.整型常量在C語言中,8位整型和16位長(zhǎng)整型量以下列方式表示:(1)十進(jìn)制整型常量。如250、-12等,其每個(gè)數(shù)字位可以是0~9。(2)十六進(jìn)制整型常量。如果整型常量以0x或0X開頭,就表示為十六進(jìn)制形式的整型常量。十進(jìn)制數(shù)128,用十六進(jìn)制表示為0x80,其每個(gè)數(shù)字位可以是0~9,a~f。
2.浮點(diǎn)型常量
C51中,浮點(diǎn)型常量用十進(jìn)制數(shù)形式表示時(shí),由數(shù)字和小數(shù)點(diǎn)組成。如3.14159、-7.2、9.9等都是用十進(jìn)制數(shù)的形式表示的浮點(diǎn)數(shù)。浮點(diǎn)型常量還可用指數(shù)法形式表示。指數(shù)法又稱為科學(xué)記數(shù)法,它是為了方便計(jì)算機(jī)對(duì)浮點(diǎn)數(shù)的處理而提出的。如十進(jìn)制數(shù)180000.0用指數(shù)法可以表示為1.8e5,其中1.8稱為尾數(shù),5稱為指數(shù),字母e也可用E表示。又如,0.00123可以表示為1.23E-3。需要注意的是,用指數(shù)形式表示浮點(diǎn)數(shù)時(shí),字母e或E之前(即尾數(shù)部分)必須有數(shù)字,且e后面的指數(shù)部分必須是整數(shù)。如e-3、9.8e2.1、e5等都是不合法的指數(shù)表示形式。
3.字符型常量字符型常量是由一對(duì)單撇號(hào)括起來的單個(gè)字符,如′a′,′*′和′8′等都是合法的字符型常量。除此之外,C51還允許使用一些特殊的字符常量,這些字符常量都是以反斜杠字符(\)開頭的字符序列,稱為“轉(zhuǎn)義字符”。表5-3給出了C51語言中由轉(zhuǎn)義字符構(gòu)成的控制符。表5-3
C51語言中的轉(zhuǎn)義字符
4.字符串常量
C51語言除了允許使用字符常量外,還允許使用字符串常量。字符串常量是由一對(duì)雙撇號(hào)括起來的字符序列,如″string″就是一個(gè)字符串常量。
C51與C語言相同,每個(gè)字符串的結(jié)尾,系統(tǒng)都會(huì)自動(dòng)加一個(gè)字符串結(jié)束標(biāo)志\0,以便系統(tǒng)判斷字符串是否結(jié)束。\0代表空操作字符,它不引起任何操作,也不會(huì)顯示到屏幕上。例如字符串″Iamastudent″在內(nèi)存中的形式如下:它的長(zhǎng)度不是14而是15,最后一個(gè)字符為\0。注意,在寫字符串時(shí)不能加\0。所以,字符串″a″與字符′a′是不同的兩個(gè)常量。前者是由字符′a′和字符\0構(gòu)成的,而后者僅由字符′a′構(gòu)成。需要注意的是,不能將字符串常量賦給一個(gè)字符變量。在C51語言中,沒有專門的字符串變量,如果要保存字符串常量,則要用一個(gè)字符數(shù)組來存放。5.2.8
C51的常用運(yùn)算符
C51的運(yùn)算符與C語言的運(yùn)算符基本上是一致的。它把除了控制語句和輸入/輸出以外的幾乎所有的基本操作都作為運(yùn)算符處理,例如將賦值符“=”作為賦值運(yùn)算符,方括號(hào)作為下標(biāo)運(yùn)算符。C51的運(yùn)算符有以下幾類:算術(shù)運(yùn)算符 (+
-*/
%
++
--)關(guān)系運(yùn)算符 (<
>
==
<=
>=
!=)邏輯運(yùn)算符(!
&&
||)位運(yùn)算符(~
&
|∧)賦值運(yùn)算符(=及擴(kuò)展賦值運(yùn)算符)條件運(yùn)算符(?:)逗號(hào)運(yùn)算符(,)指針運(yùn)算符(*&)求字節(jié)運(yùn)算符(sizeof)強(qiáng)制類型轉(zhuǎn)換運(yùn)算符(類型)下標(biāo)運(yùn)算符([])分量運(yùn)算符(.→)其他(如函數(shù)調(diào)用運(yùn)算符())1.算術(shù)運(yùn)算符
·+:加法運(yùn)算符,或正值運(yùn)算符。如2+9=11。
·-: 減法運(yùn)算符,或負(fù)值運(yùn)算符。如9-5=4。
·*:乘法運(yùn)算符。如4*5=20。
·/:除法運(yùn)算符。如7/2=3,兩個(gè)整數(shù)相除結(jié)果為整數(shù),舍去小數(shù)。
·%:求模運(yùn)算符,或稱求余運(yùn)算符,要求兩側(cè)均為整型數(shù)。如9%2=1,9%5=4。
·++:自增運(yùn)算符。++n表示在用該表達(dá)式的值之前先使n的值增1;n++表示在用該表達(dá)式的值之后再使n的值增1。
·--:自減運(yùn)算符。--n表示在用該表達(dá)式的值之前先使n的值減1;
·n--表示在用該表達(dá)式的值之后再使n的值減1。
2.關(guān)系運(yùn)算符
C51的關(guān)系運(yùn)算符如表5-4所示。表5-4關(guān)系運(yùn)算符
3.邏輯運(yùn)算符
C51提供了三種邏輯運(yùn)算符,分別為&&(邏輯與)、 ||(邏輯或)和!(邏輯非)。
4.位運(yùn)算符
位運(yùn)算本來屬于匯編語言功能,但由于C語言最初是為了編寫系統(tǒng)程序而設(shè)計(jì)的,所以,它提供了許多類似于匯編語言的處理能力。在C51中,位運(yùn)算結(jié)合8051單片機(jī)的具體特點(diǎn)得到了進(jìn)一步加強(qiáng),并專門定義了SBIT可尋址位型(數(shù)據(jù)類型)。位操作對(duì)單片機(jī)的編程非常重要,故對(duì)位操作符進(jìn)行詳細(xì)介紹。表5-5為位運(yùn)算符的定義。表5-5位運(yùn)算符
1)&:“按位與”運(yùn)算符“按位與”的運(yùn)算規(guī)則是:如果兩個(gè)運(yùn)算對(duì)象的對(duì)應(yīng)二進(jìn)制位都是1,則結(jié)果的對(duì)應(yīng)位是1,否則為0。“按位與”運(yùn)算有如下一些用途:(1)將數(shù)據(jù)中的某些指定位清0。例如,假如x是字符型變量(占8個(gè)二進(jìn)制位),則要將x的第2位置0,可進(jìn)行如下運(yùn)算:
x=x&0xfb;或x&=0xfb;(2)取出數(shù)據(jù)中的指定位。例如,為了判斷x的第4位是否為0,可進(jìn)行如下運(yùn)算:
If((x&0x10)!=0)…若條件表達(dá)式為真(即不為0),則x的第4位為1,否則為0。
2)|:“按位或”運(yùn)算符“按位或”的運(yùn)算規(guī)則是:只要兩個(gè)運(yùn)算對(duì)象的對(duì)應(yīng)位有一個(gè)是1,則結(jié)果的對(duì)應(yīng)位為1,否則為0?!鞍次换颉边\(yùn)算可將數(shù)據(jù)的某些指定位置1,而其余位不發(fā)生變化。例如,要將x中的第6位置1,可進(jìn)行如下運(yùn)算:
x=x|0x40;或x|=0x40;
3)∧:“按位異或”運(yùn)算符“按位異或”的運(yùn)算規(guī)則是:如果兩個(gè)運(yùn)算對(duì)象的對(duì)應(yīng)位不同,則結(jié)果的對(duì)應(yīng)位為1,否則為0?!鞍次划惢颉笨赡艿倪\(yùn)算組合及其結(jié)果如下:
0∧0=0;0∧1=1;1∧0=1;1∧1=0“按位異或”運(yùn)算有如下一些應(yīng)用:(1)使數(shù)據(jù)中的某些位取反,其余位保持不變,即0變1,1變0。例如,要將x中的第5位取反,可進(jìn)行如下的運(yùn)算:
x=x∧0x20;或x∧=0x20;
(2)同一個(gè)數(shù)據(jù)進(jìn)行“異或”運(yùn)算后,結(jié)果為0。例如,要將x變量清0,可進(jìn)行如下運(yùn)算:
x∧=x;“異或”運(yùn)算具有如下的性質(zhì):(x∧y)∧y=x例如,若x=0x17,y=0x06,則x∧y=0x11,0x11∧y=0x17。
4)~:“按位取反”運(yùn)算符“按位取反”的運(yùn)算規(guī)則是:將運(yùn)算對(duì)象中的各位的值取反,即將1變0,將0變1。
5)和:“左移”運(yùn)算符和“右移”運(yùn)算符“左移”的運(yùn)算規(guī)則是:將運(yùn)算對(duì)象中的每個(gè)二進(jìn)制位向左移動(dòng)若干位,從左邊移出去的高位部分被丟掉,右邊空出的低位部分補(bǔ)零?!坝乙啤钡倪\(yùn)算規(guī)則是:將運(yùn)算對(duì)象中的每個(gè)二進(jìn)制位向右移動(dòng)若干位,從右邊移出去的低位部分被丟掉,對(duì)無符號(hào)數(shù)來講,左邊空出的高位部分補(bǔ)0。例如,若x=0x17,則語句
x=x2;表示將x中的每個(gè)二進(jìn)制位左移2位后存入x中。由于0x17的二進(jìn)制數(shù)表示為00010111,所以,左移2位后,將變?yōu)?1011100,即x=x2的結(jié)果為0x5c。其中,語句
x=x2;可以寫成:
x=2;例如,x=0x08,則語句
x=x2;表示將x中的每個(gè)二進(jìn)制位右移2位后存入x中。由于0x08的二進(jìn)制表示為00001000,所以,右移2位后,將變?yōu)?0000010,即x=x2的結(jié)果為0x02。其中,語句
x=x2;可以寫成:
x=2;在進(jìn)行“左移”運(yùn)算時(shí),如果移出去的高位部分不包含1,則左移1位相當(dāng)于乘2,左移2位相當(dāng)于乘4,左移3位相當(dāng)于乘8,依此類推。因此,在實(shí)際應(yīng)用中,經(jīng)常利用“左移”運(yùn)算進(jìn)行乘以2倍的操作。在進(jìn)行“右移”運(yùn)算時(shí),如果移出去的低位部分不包含1,則右移1位相當(dāng)于除以2,右移2位相當(dāng)于除以4,右移3位相當(dāng)于除以8,依此類推。因此,在實(shí)際應(yīng)用中,經(jīng)常利用“右移”運(yùn)算進(jìn)行除以2的操作。
【例5-2】用“左移”8位的方法分離出16位數(shù)的高8位,用“與”0x00ff的方法分離出16位數(shù)的低8位。程序清單如下:
#include<reg51.h>
#include<stdio.h>
#include<intrins.h>
voidmain(void)
{
unsignedintdatax;/*定義在內(nèi)部RAM中的無符號(hào)16位整數(shù)*/
unsignedchardatah,l;/*定義在內(nèi)部RAM中的無符號(hào)8位字符*/
h=x8;/*取x的高8位*/
l=x&0x00ff;/*取x的低8位*/
}
5.賦值運(yùn)算符
C51語言的賦值運(yùn)算符是“=”,它的作用是將賦值運(yùn)算符右邊的表達(dá)式的值賦給其左邊的變量。如:
x=12;的作用是執(zhí)行一次賦值操作(運(yùn)算),將12賦給變量x。
a=5+x;的作用是將表達(dá)式5+x的值賦給變量a。在賦值號(hào)“=”左邊的只能是變量,而不能是常量或表達(dá)式,如不能寫成:
2=x;或x+y=a+b;
C語言規(guī)定,凡是雙目運(yùn)算符都可以與賦值符“=”一起組成復(fù)合的運(yùn)算符。復(fù)合的賦值運(yùn)算符一共有10種,即:+=-=*=/=
%=
=
=
&=
|=∧=例如:
a+=5等價(jià)于a=a+5
x*=y+8等價(jià)于x=x*(y+8)
a%=2等價(jià)于a=a%=2
x%=y+8等價(jià)于x=x%(y+8)
x=8等價(jià)于x=x8
y∧=0x55等價(jià)于y=y∧0x55
x&=y+8等價(jià)于x=x&(y+8)
使用這種復(fù)合的賦值運(yùn)算符有兩個(gè)優(yōu)點(diǎn):一是可以簡(jiǎn)化程序,使程序精練;二是可以提高編譯效果,產(chǎn)生質(zhì)量較高的目標(biāo)代碼。5.2.9
C51的表達(dá)式
1.算術(shù)表達(dá)式由算術(shù)運(yùn)算符和圓括號(hào)將運(yùn)算對(duì)象連接起來的有意義的式子稱為算術(shù)表達(dá)式。例如:
a*(b+c);
(7+6)%5/2;
2.關(guān)系表達(dá)式用關(guān)系運(yùn)算符將兩個(gè)表達(dá)式(可以是算術(shù)表達(dá)式或關(guān)系表達(dá)式、邏輯表達(dá)式、賦值表達(dá)式、字符表達(dá)式)連接起來構(gòu)成的式子稱為關(guān)系表達(dá)式。例如:
a+b>c
b>=c+a
c+a==b-c
d=a<b<c
f=a!=b<c若a=4,b=3,c=5,則:
·a+b>c等價(jià)于(a+b)>c。結(jié)果為“真”,表達(dá)式的值為1。
·b>=c+a等價(jià)于b>=(c+a)。結(jié)果為“假”,表達(dá)式的值為0。
·c+a==b-c等價(jià)于(c+a)=(b-c)。結(jié)果為“假”,表達(dá)式的值為0。
·d=a<b<c等價(jià)于d=(a<b<c)。d的值為1(在計(jì)算“a<b<c”時(shí),因?yàn)椤?lt;”運(yùn)算符是自左至右的結(jié)合方向,所以先執(zhí)行“a<b”得值為0,再執(zhí)行運(yùn)算“0<c”得值為1,賦給d)。
·f=a!=b<c等價(jià)于f=(a!=(b<c))。f的值為1。
3.邏輯表達(dá)式用邏輯運(yùn)算符將若干關(guān)系表達(dá)式或任意數(shù)據(jù)類型(除void外)的數(shù)據(jù)連接起來的有意義的式子稱為邏輯表達(dá)式。例如:
!a
a&&b
!b<a||5&&5<=5若a=5,b=0,則:
·!a的值為0。因?yàn)閍的值為非0,所以被認(rèn)為是“真”,對(duì)它進(jìn)行“非”運(yùn)算,得“假”,因而!a值為0。
·a&&b的值為0。因?yàn)閍的值為非0,所以被認(rèn)為是“真”,b的值為0,所以被認(rèn)為是“假”,因而a&&b的值為“假”,即為0。
·!b<a||5&&5<=5的值為1。對(duì)此表達(dá)式自左至右求解,執(zhí)行順序如下:
!b<a||5&&5<=5
①②⑤④③第①步“!b”的值為1。第②步“1<2”的值為1。第③步“5<=5”的值為1。此時(shí),要運(yùn)行的表達(dá)式變成“1||5&&1”(&&的優(yōu)先級(jí)比||高)。所以第④步“5&&1”的值為1。第⑤步“1||1”的值為1。如果需要使用復(fù)雜的邏輯表達(dá)式,建議使用括號(hào)區(qū)分邏輯表達(dá)式執(zhí)行順序(優(yōu)先級(jí)),以減少由于編譯程序在處理時(shí)帶來的不可預(yù)見的邏輯運(yùn)算錯(cuò)誤。另外,編譯程序在處理含有“&&”或“||”的表達(dá)式時(shí),往往采用優(yōu)化的算法,即在從左到右的運(yùn)算中,只要結(jié)果一確定,就不再繼續(xù)運(yùn)算下去。對(duì)于<表達(dá)式1>&&<表達(dá)式2>&&<表達(dá)式3>&&…,在所有運(yùn)算分量中,只要一個(gè)為假,則整個(gè)表達(dá)式的結(jié)果就為假。對(duì)于<表達(dá)式1>||<表達(dá)式2>||<表達(dá)式3>||…,在所有運(yùn)算分量中,只要一個(gè)為真,則整個(gè)表達(dá)式的結(jié)果就為真。例如,對(duì)于表達(dá)式
((y=7)<6)&&((y=5)<6)在自左至右計(jì)算過程中,表達(dá)式“(y=7)<6”的值為假,即可確定整個(gè)表達(dá)式的值為假。(在進(jìn)行&&運(yùn)算時(shí),只要其中一個(gè)為假,則結(jié)果就為假,所以右邊的表達(dá)式“(y=5)<6”就不再計(jì)算了。)
4.賦值表達(dá)式由賦值運(yùn)算符將一個(gè)變量和另一個(gè)表達(dá)式連接起來的式子稱為賦值表達(dá)式。賦值表達(dá)式一般形式為變量賦值運(yùn)算符表達(dá)式例如:
x=5
x=7%2+y
a=(b=6)或a=b=6(賦值表達(dá)式的值為6,a、b的值均為6)
a+=a*(若a=5,相當(dāng)于a=5+5*5)5.2.10
C51的基本語句
1.表達(dá)式語句
在表達(dá)式后加上一個(gè)“;”,就構(gòu)成了表達(dá)式語句。例如:
a=b+c;
u=3;v=4;
y=(m+n)*10/u;
j++;
2.復(fù)合語句復(fù)合語句是由若干條語句組合在一起形成的語句。它以“{”開始,以“}”結(jié)束,中間是若干條語句,語句間用“;”分隔。復(fù)合語句的一般形式為
{語句1;語句2;
語句N;
}下面為一個(gè)復(fù)合語句的例子:
If(rxd_newdata==rxd_buf[3])
{
rxd_newaddr=rxd_buf[1];
rxd_newdata=rxd_buf[2];
rxd_end=1;
}
其中:
{
rxd_newaddr=rxd_buf[1];
rxd_newdata=rxd_buf[2];
rxd_end=1;
}
為復(fù)合語句。當(dāng)條件rxd_newdata==rxd_buf[3]成立時(shí),執(zhí)行該復(fù)合語句。
3.if條件選擇語句
if條件選擇語句是通過給定條件的判斷,來決定所要執(zhí)行的操作。
if條件選擇語句的一般形式如下:
if(條件表達(dá)式)語句1[else語句2]其中,用“[”和“]”括起來的部分表示其為可選項(xiàng)。當(dāng)if語句的條件表達(dá)式成立時(shí)執(zhí)行語句1;不成立時(shí)則執(zhí)行語句2?!癳lse語句2”為可選項(xiàng)。語句1和語句2可以是任何語句,當(dāng)然也包括if語句本身。其流程圖如圖5-2所示。圖5-2
if條件選擇語句的執(zhí)行流程例如:
if(txd_point>=4)
{
txd_end=1;
txd_data_full_flag=0;
txd_point=0;
}else
{SBUF=txd_buf[txd_point];}
4.switch多分支選擇語句
if-else語句一般適合用于兩路選擇,即在兩個(gè)分支中選擇一個(gè)執(zhí)行。盡管可以通過if條件選擇語句的嵌套形式來實(shí)現(xiàn)多路選擇的目的,但這樣做的結(jié)果是使得if條件選擇語句的嵌套層次太多,降低了程序的可讀性。C51中的switch多分支選擇語句提供了更方便地進(jìn)行多路分支選擇的功能。
switch多分支選擇語句的一般形式如下:switch(表達(dá)式){
case常量表達(dá)式1:[語句1][break;]
case常量表達(dá)式2:[語句2][break;]
case常量表達(dá)式n:[語句n][break;][default:語句n+1]
}
switch的執(zhí)行過程:先計(jì)算表達(dá)式的值,然后將表達(dá)式的值與所有的常量表達(dá)式進(jìn)行比較,若與某個(gè)常量表達(dá)式的值相同則運(yùn)行相應(yīng)的語句,如該語句后有break語句,則退出,沒有break語句時(shí)則執(zhí)行下一條case語句;如果將表達(dá)式的值與所有常量表達(dá)式進(jìn)行比較后均不相等則執(zhí)行default后的語句n+1(如有default語句)。
switch語句的執(zhí)行流程如圖5-3所示。圖5-3
switch語句的執(zhí)行流程例如:
voidexecute_end(unsignedcharrecv_cmd)
{
switch(rec_cmd)
{
case0:pgm_operation();/*編程操作*/break;
case1:read_operation();/*讀數(shù)據(jù)操作*/break;
case2:pgm_lock_bit1();/*寫加密位1操作*/serial_out(CMD_2);
break;
case3:verify_data();/*數(shù)據(jù)校驗(yàn)操作*/
break;
default:/*復(fù)位*/break;
}
}
5.循環(huán)語句
1)while循環(huán)語句
while循環(huán)語句的一般形式如下:
while(表達(dá)式)循環(huán)體語句
while語句的執(zhí)行過程如下:
(1)求出while后圓括號(hào)內(nèi)表達(dá)式的值,若此值為“真”(非0),則執(zhí)行(2);若為“假”(為0),則執(zhí)行(4);(2)執(zhí)行循環(huán)體內(nèi)語句,如果循環(huán)體由一個(gè)以上的語句組成,則應(yīng)用{}將循環(huán)體括起來以形成復(fù)合語句;(3)轉(zhuǎn)向執(zhí)行(1);(4)結(jié)束while循環(huán),執(zhí)行while語句后的其他語句。while語句的特點(diǎn)是先判斷,再執(zhí)行。
while循環(huán)語句的執(zhí)行流程如圖5-4所示。圖5-4
while循環(huán)語句的執(zhí)行流程圖例如:
while(txd_point>=4)
{
txd_end=1;
txd_data_full_flag=0;
txd_point=0;
}do-while循環(huán)語句do-while循環(huán)語句的一般形式如下:
do
{循環(huán)體語句
}while(表達(dá)式);do-while語句的執(zhí)行過程如下:
(1)執(zhí)行do-while之間的循環(huán)體語句。
(2)計(jì)算while后圓括號(hào)內(nèi)表達(dá)式的值,若為“真”(非0),則重復(fù)執(zhí)行(1);若值為“假”(0),則執(zhí)行(3);
(3)結(jié)束循環(huán),執(zhí)行do-while循環(huán)語句后的其他語句。
do-while語句的特點(diǎn)是先執(zhí)行,再判斷。
do-while循環(huán)語句的執(zhí)行流程如圖5-5所示。圖5-5
do-while循環(huán)語句的執(zhí)行流程例如:
do{
txd_end=0;
txd_data_full_flag=0;
txd_point++;
}while(txd_point<4);
3)for循環(huán)語句在C語言中,for循環(huán)語句使用最為靈活,它的功能也很強(qiáng),凡是用while語句能夠完成的循環(huán)功能,用for循環(huán)都能實(shí)現(xiàn)。
for循環(huán)語句的一般形式如下:
for(循環(huán)初值設(shè)定表達(dá)式;[循環(huán)終止條件表達(dá)式];[循環(huán)變量更新表達(dá)式])循環(huán)體其中,for循環(huán)語句中的三個(gè)表達(dá)式之間用“;”隔開,一般通俗地理解為(1)循環(huán)初值設(shè)定表達(dá)式通常是循環(huán)變量賦初值;(2)循環(huán)終止條件表達(dá)式判斷循環(huán)什么時(shí)候結(jié)束;(3)循環(huán)變量更新表達(dá)式用以控制循環(huán)變量的修改;(4)“語句”即for循環(huán)語句的“循環(huán)體”部分。for循環(huán)語句的執(zhí)行過程如下:(1)計(jì)算循環(huán)初值設(shè)定表達(dá)式的值;(2)計(jì)算循環(huán)終止條件表達(dá)式的值,若值為“真”(非0),則執(zhí)行(3);若值為“假”(0),則執(zhí)行(6);(3)執(zhí)行循環(huán)體中的語句;(4)計(jì)算循環(huán)變量更新表達(dá)式的值;(5)轉(zhuǎn)向(2)繼續(xù)執(zhí)行;(6)結(jié)束循環(huán),執(zhí)行for循環(huán)語句后的其他語句。for循環(huán)語句的執(zhí)行流程如圖5-6所示。圖5-6
for循環(huán)語句的執(zhí)行流程例如:s=0;
for(i=1;i<5;i++)
{s=s+i;}
6.goto語句
和標(biāo)準(zhǔn)C語言一樣,C51也提供了無條件轉(zhuǎn)移的goto語句。goto語句的一般形式如下:
goto標(biāo)號(hào)
goto語句的執(zhí)行過程是:將程序的執(zhí)行流程轉(zhuǎn)到以該標(biāo)號(hào)為前綴的語句去執(zhí)行。在C51中,標(biāo)號(hào)可以是任意合法的標(biāo)識(shí)符,可以和變量同名,但不允許和關(guān)鍵字同名。C語言允許在任何語句前添加符號(hào),以作為goto語句的轉(zhuǎn)向目標(biāo)。標(biāo)號(hào)的一般形式如下:標(biāo)號(hào):語句;
goto語句作為一種語言成分不是必需的,沒有它照樣能編寫程序。按結(jié)構(gòu)化程序設(shè)計(jì)的原則,應(yīng)該盡量不使用goto語句,因?yàn)樗鼤?huì)影響程序的可讀性和模塊化。5.3
C51的函數(shù)與數(shù)組
函數(shù)是C語言程序的基本組成部分。在C語言中,一個(gè)程序可以由一個(gè)主函數(shù)main()和若干個(gè)子函數(shù)構(gòu)成,由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)之間也可以相互調(diào)用,程序最后在main()函數(shù)中結(jié)束。在C語言中可以從不同的角度對(duì)函數(shù)分類。從函數(shù)定義的角度看,函數(shù)可分為庫函數(shù)和用戶定義函數(shù)兩種。庫函數(shù)由C系統(tǒng)提供,用戶無需定義,也不必在程序中作類型說明,只需在程序前包含該函數(shù)原型的頭文件即可在程序中直接調(diào)用。如printf、scanf、getchar、putchar、gets、puts等函數(shù)均屬此類。不過C51與標(biāo)準(zhǔn)C語言對(duì)上述函數(shù)處理不一樣。標(biāo)準(zhǔn)C語言中上述函數(shù)的輸入來自鍵盤,輸出是顯示器,而C51的輸入、輸出則均是串行口。C51除具有與標(biāo)準(zhǔn)C語言相同的庫函數(shù)外,還有一些與單片機(jī)有關(guān)的特殊庫函數(shù)。
C語言提供了極為豐富的庫函數(shù),這些庫函數(shù)又可從功能角度作以下分類。(1)字符類型分類函數(shù)。此類函數(shù)用于對(duì)字符按ASCII碼分類:數(shù)字、控制字符、分隔符、大小寫字母等。(2)轉(zhuǎn)換函數(shù)。此類函數(shù)用于字符或字符串之間的轉(zhuǎn)換;字符量與各類數(shù)字量(整型,實(shí)型等)之間的轉(zhuǎn)換;大、小寫之間的轉(zhuǎn)換等。(3)輸入/輸出函數(shù)。此類函數(shù)用于完成輸入/輸出功能。(4)數(shù)學(xué)函數(shù)。此類函數(shù)用于數(shù)學(xué)函數(shù)計(jì)算。(5)其他函數(shù)。此類函數(shù)用于其他各種功能。用戶定義函數(shù)指由用戶按需要編寫的函數(shù)。對(duì)于用戶自定義函數(shù),不僅要在程序中定義函數(shù)本身,而且在主調(diào)函數(shù)模塊中還必須對(duì)該被調(diào)函數(shù)進(jìn)行類型說明,然后才能使用。
C語言的函數(shù)兼有其他語言中的函數(shù)和過程兩種功能,從這個(gè)角度看,又可把函數(shù)分為有返回值函數(shù)和無返回值函數(shù)兩種。有返回值函數(shù)在被調(diào)用執(zhí)行完后將向調(diào)用者返回一個(gè)執(zhí)行結(jié)果,稱為函數(shù)返回值。如數(shù)學(xué)函數(shù)即屬于此類函數(shù)。由用戶定義的這種要返回函數(shù)值的函數(shù),必須在函數(shù)定義和函數(shù)說明中明確返回值的類型。無返回值函數(shù)用于完成某項(xiàng)特定的處理任務(wù),執(zhí)行完成后不向調(diào)用者返回函數(shù)值。這類函數(shù)類似于其他語言的過程。由于函數(shù)無需返回值,因此用戶在定義此類函數(shù)時(shí)可指定他的返回為“空類型”,空類型的說明符為“void”。從主調(diào)函數(shù)和被調(diào)函數(shù)之間數(shù)據(jù)傳送的角度又可將函數(shù)分為無參函數(shù)和有參函數(shù)兩種。無參函數(shù)的函數(shù)定義、函數(shù)說明及函數(shù)調(diào)用中均不帶參數(shù)。主調(diào)函數(shù)和被調(diào)函數(shù)之間不進(jìn)行參數(shù)傳送。此類函數(shù)通常用來完成一組指定的功能,可以返回或不返回函數(shù)值。有參函數(shù)也稱帶參函數(shù),在函數(shù)定義及函數(shù)說明時(shí)都有參數(shù),稱為形式參數(shù)(簡(jiǎn)稱為形參)。有參函數(shù)在函數(shù)調(diào)用時(shí)也必須給出參數(shù),稱為實(shí)際參數(shù)(簡(jiǎn)稱為實(shí)參)。進(jìn)行函數(shù)調(diào)用時(shí),主調(diào)用函數(shù)將把實(shí)參的值傳送給形參,供被調(diào)函數(shù)使用。5.3.1函數(shù)的定義函數(shù)定義的一般形式為類型標(biāo)識(shí)符函數(shù)名(形式參數(shù)表)形式參數(shù)說明
{說明部分函數(shù)體
}
1.無參函數(shù)的一般形式
類型說明符函數(shù)名()
{類型說明語句
}其中,類型說明符和函數(shù)名稱為函數(shù)頭;類型說明符指明了本函數(shù)的類型,函數(shù)的類型實(shí)際上是函數(shù)返回值的類型;函數(shù)名是由用戶定義的標(biāo)識(shí)符,函數(shù)名后有一個(gè)空括號(hào),其中無參數(shù),但括號(hào)不可少;{}中的內(nèi)容稱為函數(shù)體,在函數(shù)體中也有類型說明,這是對(duì)函數(shù)體內(nèi)部所用到的變量的類型說明。在很多情況下都不要求無參函數(shù)有返回值,此時(shí)函數(shù)的類型可以寫為void。我們可以給出一個(gè)函數(shù)定義:
voidHello()
{
Printf(″Helloworld,\n″);
}此函數(shù)與主函數(shù)相比,只把main改為Hello,作為函數(shù)名,其余不變。Hello函數(shù)是一個(gè)無參函數(shù),當(dāng)被其他函數(shù)調(diào)用時(shí),輸出Helloworld字符串。
2.有參函數(shù)的一般形式類型說明符函數(shù)名(形式參數(shù)表)形式參數(shù)類型說明
{類型說明語句
}有參函數(shù)比無參函數(shù)多了兩個(gè)內(nèi)容,其一是形式參數(shù)表,其二是形式參數(shù)類型說明。在形參表中給出的參數(shù)稱為形式參數(shù),他們可以是各種類型的變量,各參數(shù)之間用逗號(hào)間隔。在進(jìn)行函數(shù)調(diào)用時(shí),主調(diào)函數(shù)將賦予這些形式參數(shù)實(shí)際的值。形參既然是變量,當(dāng)然必須給予類型說明。例如,定義一個(gè)函數(shù),用于確定兩個(gè)數(shù)中的大數(shù),可寫為intmax(inta,intb){if(a>b)returna;
elsereturnb;
}
5.3.2數(shù)組
在程序設(shè)計(jì)中,為了處理方便,經(jīng)常把具有相同類型的若干變量按有序的形式組織起來,這些按序排列的同類數(shù)據(jù)元素的集合稱為數(shù)組。在C語言中,數(shù)組屬于構(gòu)造數(shù)據(jù)類型。一個(gè)數(shù)組可以分解為多個(gè)數(shù)組元素,這些數(shù)組元素可以是基本數(shù)據(jù)類型或是構(gòu)造類型。因此,按數(shù)組元素的類型不同,數(shù)組又可分為數(shù)值數(shù)組、字符數(shù)組、指針數(shù)組、結(jié)構(gòu)數(shù)組等各種類別。
1.一維數(shù)組
一維數(shù)組說明的一般形式為類型說明符數(shù)組名[常量表達(dá)式],…;其中,類型說明符是任意一種基本數(shù)據(jù)類型;數(shù)組名是用戶定義的數(shù)組標(biāo)識(shí)符;方括號(hào)中的常量表達(dá)式表示數(shù)據(jù)元素的個(gè)數(shù),也稱為數(shù)組的長(zhǎng)度。例如:
inta[10];//整型數(shù)組a,有10個(gè)元素
floatb[10],c[20];//實(shí)型數(shù)組b,有10個(gè)元素;實(shí)型數(shù)組c,有20個(gè)元素
charch[20];//字符型數(shù)組ch,有20個(gè)元素對(duì)于數(shù)組類型說明應(yīng)注意以下幾點(diǎn):(1)數(shù)組的類型實(shí)際上是數(shù)組元素的取值類型。對(duì)于同一個(gè)數(shù)組,其所有元素的數(shù)據(jù)類型都是相同的。(2)數(shù)組名的書寫規(guī)則應(yīng)符合標(biāo)識(shí)符的書寫規(guī)定。(3)數(shù)組名不能與其他變量名相同,例如:
voidmain()
{
inta;
floata[10];
}是錯(cuò)誤的。
(4)方括號(hào)中的常量表達(dá)式表示數(shù)組元素的個(gè)數(shù),如a[5]表示數(shù)組a有5個(gè)元素,但其下標(biāo)是從0開始計(jì)算的,因此5個(gè)元素分別為a[0],a[1],a[2],a[3],a[4]。(5)不能在方括號(hào)中用變量來表示元素的個(gè)數(shù),但是可以是符號(hào)常數(shù)或常量表達(dá)式。例如:
#defineFD5
voidmain()
{
inta[3+2],b[7+FD];
}
是合法的。但是下述說明方式是錯(cuò)誤的:
voidmain()
{
intn=5;
inta[n];
}
(6)允許在同一個(gè)類型說明中,說明多個(gè)數(shù)組和多個(gè)變量。例如:
inta,b,c,d,k1[10],k2[20];數(shù)組元素是組成數(shù)組的基本單元。數(shù)組元素也是一種變量,其標(biāo)識(shí)方法為數(shù)組名后跟一個(gè)下標(biāo)。下標(biāo)表示了元素在數(shù)組中的順序號(hào)。數(shù)組元素的一般形式為數(shù)組名[下標(biāo)]其中,下標(biāo)只能為整型常量或整型表達(dá)式,為小數(shù)時(shí),C編譯將自動(dòng)取整。例如,a[5],a[i+j],a[i++]都是合法的數(shù)組元素。數(shù)組元素通常也稱為下標(biāo)變量。必須先定義數(shù)組,才能使用下標(biāo)變量。在C語言中只能逐個(gè)地使用下標(biāo)變量,而不能一次引用整個(gè)數(shù)組。
【例5-3】將顯示數(shù)據(jù)緩沖區(qū)display_data_buff中的數(shù)字0~15轉(zhuǎn)換成七段字型碼送顯示字型緩沖區(qū)display_code_buff。程序清單如下:#include<reg51.h>#include<stdio.h>#include<intrins.h>voidmain(void){unsignedchardatai,num;
unsignedchardatadisplay_data_buff[8];//顯示數(shù)據(jù)緩沖區(qū)
unsignedchardatadisplay_code_buff[8];//字型顯示緩沖區(qū)
unsignedcharcodedisplay_code[16]={
0x0c0,0x0f9,0x0a4,0x0b0,0x99,0x92,0x82,0x0f8,//0,1,2,3,4,5,6,7
0x80,0x90,0x88,0x83,0x0c6,0x0a1,0x86,0x8e,//8,9,A,B,C,D,E,F(xiàn)
};
for(i=0;i<=7;i++){
num=display_data_buff[i];
display_code_buff[i]=display_code[num];} }其中,display_data_buff[8]、display_code_buff[8]、i、num被定義在內(nèi)部RAM中,而display_code_buff[16]是常數(shù),因而被定義在代碼區(qū)中。
2.二維數(shù)組前面介紹的數(shù)組只有一個(gè)下標(biāo),稱為一維數(shù)組,其中數(shù)組元素也稱為單下標(biāo)變量。在實(shí)際問題中,有很多量是二維或多維的,因此,C語言允許構(gòu)造多維數(shù)組。多維數(shù)組元素有多個(gè)下標(biāo),以標(biāo)識(shí)其在數(shù)組中的位置,所以也稱為多下標(biāo)變量。多維數(shù)組可由二維數(shù)組類推而得到。二維數(shù)組類型說明的一般形式為類型說明符數(shù)組名[常量表達(dá)式1][常量表達(dá)式2]…;其中,常量表達(dá)式1表示第一維下標(biāo)的長(zhǎng)度;常量表達(dá)式2表示第二維下標(biāo)的長(zhǎng)度。例如:
inta[3][4];說明了一個(gè)三行四列的數(shù)組,數(shù)組名為a,其下標(biāo)變量的類型為整型。該數(shù)組的下標(biāo)變量共有3×4個(gè),即:
a[0][0],a[0][1],a[0][2],a[0][3]
a[1][0],a[1][1],a[1][2],a[1][3]
a[2][0],a[2][1],a[2][2],a[2][3]二維數(shù)組在概念上是二維的,即是說其下標(biāo)在兩個(gè)方向上變化,下標(biāo)變量在數(shù)組中的位置也處于一個(gè)平面之中,而不是像一維數(shù)組一樣只是一個(gè)向量。但是,實(shí)際的硬件存儲(chǔ)器卻是連續(xù)編址的,也就是說,存儲(chǔ)器單元是按一維線性方式排列的。在一維存儲(chǔ)器中存放二維數(shù)組,可有兩種方式:一種是按行排列,即放完一行后順次放入第二行;另一種是按列排列,即放完一列之后再順次放入第二列。在C語言中,二維數(shù)組是按行排列的。如上述定義的數(shù)組a[3][4]按行順次存放,先存放a[0]行,再存放a[1]行,最后存放a[2]行。每行中的四個(gè)元素也是依次存放的。由于數(shù)組a說明為int類型,該類型占2個(gè)字節(jié)的內(nèi)存空間,因此每個(gè)元素均占有2個(gè)字節(jié)。二維數(shù)組的元素也稱為雙下標(biāo)變量,其表示的形式為:數(shù)組名[下標(biāo)][下標(biāo)]其中,下標(biāo)應(yīng)為整型常量或整型表達(dá)式。例如,a[3][4]表示a數(shù)組的第三行第四列的元素。下標(biāo)變量和數(shù)組說明在形式中有些相似,但這兩者具有完全不同的含義。數(shù)組說明的方括號(hào)中給出的是某一維的長(zhǎng)度,即可取下標(biāo)的最大值;而數(shù)組元素中的下標(biāo)是該元素在數(shù)組中的位置標(biāo)識(shí)。前者只能是常量,后者可以是常量、變量或表達(dá)式。二維數(shù)組的初始化舉例如下:
Unsignedchardataoutput[2][3]=
{1,2,3,
4,5,6,
};初始化后,output[0][0]=1,output[0][1]=2,output[0][2]=3,output[1][0]=4,output[1][1]=5,output[1][2]=6。數(shù)組output[2][3]被定義在內(nèi)部RAM中。5.4
C51的編程規(guī)范現(xiàn)在,在單片機(jī)程序設(shè)計(jì)中,C51已經(jīng)得到了廣泛的推廣和應(yīng)用,成為單片機(jī)的主流程序設(shè)計(jì)語言,甚至可以說是單片機(jī)開發(fā)人員必須要掌握的一門語言了。作為一門工具,最終的目的就是實(shí)現(xiàn)功能。在滿足這個(gè)前提條件下,我們希望我們的程序能容易地被別人讀懂,或者我們能夠很容易地讀懂別人和自己以前的程序,這樣,在團(tuán)體合作開發(fā)中就能起到事半功倍之效。在網(wǎng)上請(qǐng)求幫助時(shí),如能以規(guī)范的寫法貼出程序,網(wǎng)友就會(huì)比較容易地明白你的問題,你也會(huì)比較快地得到網(wǎng)友的幫助。因此,為了便于源程序的交流,減少開發(fā)中的障礙,必須按規(guī)范對(duì)C51進(jìn)行編程。下面對(duì)C51的編程規(guī)范作簡(jiǎn)要介紹。
1.注釋一般情況下,注釋均應(yīng)采用中文。
(1)開始的注釋。文件(模塊)注釋內(nèi)容包括:公司名稱、版權(quán)、作者名稱、修改時(shí)間、模塊功能、背景介紹等,復(fù)雜的算法需要加上流程說明。例如:
/**************************************/公司名稱:模塊名:89S52編程器硬件型號(hào):89S52創(chuàng)建人:日期:20070708修改人:日期:20070819功能描述:對(duì)89S51、89S52編程其他說明:版本:2.1
/**************************************/函數(shù)開頭的注釋內(nèi)容包括:函數(shù)名稱、功能、說明、輸入、返回、函數(shù)描述、流程處理、全局變量、調(diào)用函數(shù)等,復(fù)雜的函數(shù)需要加上變量用途說明。例如:/**************************************/函數(shù)名稱:hex_to_ascii功能描述:十六進(jìn)制到ASCII碼轉(zhuǎn)換入口參數(shù):十六進(jìn)制數(shù)返回值:相應(yīng)的ASCII碼調(diào)用函數(shù):全局變量:局部變量:hex_data,ascii_code/**************************************/unsignedcharhex_to_ascii(unsignedchar);
unsignedcharhex_to_ascii(unsignedcharhex_data)
{
unsignedcharascii_code;
if(hex_data<=9){ascii_code=hex_data+0x30;}else{ascii_code=hex_data+0x37;}returnascii_code;
}
(2)程序中的注釋。程序中的注釋內(nèi)容包括:修改時(shí)間和作者、方便理解的注釋等。注釋內(nèi)容應(yīng)簡(jiǎn)練、清楚、明了,一目了然的語句不用加注釋。
2.變量和函數(shù)的命名
變量和函數(shù)的命名必須具有一定的實(shí)際意義。例如:unsignedcharascii_code;
unsignedcharhex_data;
unsignedcharhex_to_ascii(unsignedchar);
(1)常量的命名。常量的命名全部用大寫。例如:
//定義命令常量
#defineCMD_00x00
#defineCMD_10x01
#defineCMD_20x02
#defineCMD_30x03
#defineCMD_40x04(2)結(jié)構(gòu)體命名。例如:structtime_str{
unsignedcharhour;//小時(shí)
unsignedcharminute;//分
unsignedcharsecond;//秒
unsignedcharsecond20;//1/20秒
}time;(3)函數(shù)的命名。一般函數(shù)名首字母需大寫,若包含有兩個(gè)單詞,則每個(gè)單詞的首字母大寫。函數(shù)原型說明包括:引用的外部函數(shù)及內(nèi)部函數(shù),外部引用必須在右側(cè)注明函數(shù)來源,模塊名及文件名、內(nèi)部函數(shù)等只要注釋其文件名即可。
3.編輯風(fēng)格(1)縮進(jìn):縮進(jìn)以Tab為單位,一個(gè)Tab為4個(gè)空格大小。預(yù)處理語句、全局?jǐn)?shù)據(jù)、函數(shù)原型、標(biāo)題、附加說明、函數(shù)說明、標(biāo)號(hào)等均頂格書寫。語句塊的“{”和“}”配對(duì)對(duì)齊,并與其前一行對(duì)齊。(2)空格:數(shù)據(jù)和函數(shù)在其類型、修飾名稱之間加適當(dāng)空格并據(jù)情況對(duì)齊。關(guān)鍵字原則上空一格。運(yùn)算符的空格規(guī)定為:“->”、“[”、“]”、“++”、“--”、“~”、“!”、“+”、“-”、“&”(取址或引用)、“*”(指針)等幾個(gè)運(yùn)算符兩邊不空格(其中單目運(yùn)算符系指與操作數(shù)相連的一邊),其他運(yùn)算符包括大多數(shù)二目運(yùn)算符和三目運(yùn)算符“?:”兩邊均空一格,“(”、“)”運(yùn)算符在其內(nèi)側(cè)空一格。在作函數(shù)定義時(shí)還可據(jù)情況多空或不空格來對(duì)齊,但在函數(shù)實(shí)現(xiàn)時(shí)可不用空格?!埃边\(yùn)算符只在其后空一格,需對(duì)齊時(shí)也可不空或多空格,對(duì)語句行后加的注釋,應(yīng)加適當(dāng)空格使之與語句隔開,并盡可能對(duì)齊。(3)對(duì)齊:原則上,關(guān)系密切的行應(yīng)對(duì)齊。對(duì)齊包括類型、修飾、名稱、參數(shù)等各部分對(duì)齊。另外,每一行的長(zhǎng)度不應(yīng)超過屏幕太多,必要時(shí)應(yīng)適當(dāng)換行,換行時(shí)應(yīng)盡可能在“,”處或運(yùn)算符處,換行后最好以運(yùn)算符打頭,并且以下各行均以該語句為參照首行縮進(jìn),但該語句仍以首行的縮進(jìn)為準(zhǔn),即如其下一行為“{”,則應(yīng)與首行對(duì)齊。(4)空行:程序文件結(jié)構(gòu)各部分之間空兩行,若不必要也可只空一行,各函數(shù)之間一般空兩行。(5)修改:版本封存以后的修改一定要將原來的語句用/*…*/封閉,不能自行刪除或修改,并要在文件及函數(shù)的修改記錄中加以記錄。(6)形參:在定義函數(shù)時(shí),在函數(shù)名后面括號(hào)中直接進(jìn)行形式參數(shù)說明,不再另行說明。5.5
C51的基本應(yīng)用5.5.1
8051I/O口字節(jié)操作的應(yīng)用
【例5-4】將P1口輸入的8位數(shù)直接由P3口輸出。在實(shí)際應(yīng)用中,可對(duì)輸入信號(hào)進(jìn)行處理后再由P3口輸出。程序清單如下:#include<reg51.h>
#include<stdio.h>
#include<intrins.h>
sfrP1=0x90;/*定義特殊功能寄存器P1(SFR)*/
sfrP3=0xb0;/*定義特殊功能寄存器P3(SFR)*//*************主程序********************/
voidmain(void)
{
unsignedcharpval;/*臨時(shí)變量*/
P1=0xFF;/*設(shè)置P1口為輸入方式*/while(1)
{
pval=P1;/*讀P1到臨時(shí)變量pval*/
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 污水處理流程課程設(shè)計(jì)
- 消費(fèi)心理分析課程設(shè)計(jì)
- 數(shù)字出版行業(yè)相關(guān)投資計(jì)劃提議范本
- 農(nóng)用化學(xué)品相關(guān)行業(yè)投資方案
- 汽車營銷專業(yè)課程設(shè)計(jì)
- 小學(xué)四年級(jí)數(shù)學(xué)幾百幾十?dāng)?shù)乘以一位數(shù)質(zhì)量自測(cè)口算題
- 小班關(guān)于青梅的課程設(shè)計(jì)
- 有關(guān)光譜技術(shù)課程設(shè)計(jì)
- 智能電飯煲課程設(shè)計(jì)
- 小學(xué)目標(biāo)管理課程設(shè)計(jì)
- (整理)《運(yùn)籌學(xué)》期末考試試題與參考答案
- 糕點(diǎn)切片機(jī)答辯
- (完整版)《金匱要略》方劑總匯(完整版)
- 《化學(xué)實(shí)驗(yàn)室安全與環(huán)保手冊(cè)》
- 對(duì)賬函格式范本
- 美國簽證在職收入證明中英文對(duì)照模版
- 中鐵集團(tuán)會(huì)計(jì)核算手冊(cè)
- 婚禮流程準(zhǔn)備安排表需要彩排的
- 晉江市土地利用總體規(guī)劃
- 泵站質(zhì)量檢查表
- 新版atstudy系統(tǒng)測(cè)試計(jì)劃
評(píng)論
0/150
提交評(píng)論