- 單片機應(yīng)用技術(shù)(第4版)
- 倪志蓮
- 3795字
- 2021-08-20 17:13:05
2.5 C51的數(shù)據(jù)結(jié)構(gòu)
C51與C語言相同,其數(shù)據(jù)有常量和變量之分。常量是在程序運行中不能改變值的量,可以是字符、十進制數(shù)或十六進制數(shù)(用0x表示)。變量是在程序運行過程中不斷變化的量。無論是常量還是變量,其數(shù)據(jù)結(jié)構(gòu)是以數(shù)據(jù)類型決定的。
2.5.1 C51的常量
常量就是在程序執(zhí)行過程中不能改變值的量。常量的數(shù)據(jù)類型有整型、浮點型、字符型、字符串型及位類型。
1.整型常量
整型常量可用十進制、十六進制表示,如果是長整數(shù)則在數(shù)字后面加L。舉例如下。十進制整數(shù):1234,-56;十六進制整數(shù):0x123,-0xFF;長整數(shù):6789L、0xAB12L。
2.浮點型常量
浮點型常量可用十進制和指數(shù)兩種形式表示。
十進制由數(shù)字和小數(shù)點組成,整數(shù)和小數(shù)部分為0可以省略,但小數(shù)點不能省略。例如:0.1234,.1234,1234.,0.0等。
指數(shù)表示形式為 [±] 數(shù)字 [.數(shù)字] e [±] 數(shù)字。例如:123.4e5,-6e-7等。
3.字符型常量
字符型常量為單引號內(nèi)的字符,如 ‘e’、‘k’ 等。對于不可顯示的控制符,可在該字符前用反斜杠“\”構(gòu)成轉(zhuǎn)義字符表示。如表2-7所示為一些常用的轉(zhuǎn)義字符。
4.字符串型常量
字符串型常量為雙引號內(nèi)的字符,如“ ABCD” “@#%”等。當(dāng)雙引號內(nèi)沒有字符時,表示空字符串。在C51中字符串常量是作為字符型數(shù)組來處理的,在存儲字符串時系統(tǒng)會在字符串的尾部加上轉(zhuǎn)義字符“\ 0”作為該字符串的結(jié)束符。所以字符串常量“ A”與字符常量 ‘A’ 是不同的。
5.位常量
位常量的值只能取1或0兩種。
2.5.2 C51的變量與存儲類型
變量是一種在程序執(zhí)行過程中值不斷變化的量。變量在使用之前,必須進行定義,用一個標(biāo)識符作為變量名并指出它的數(shù)據(jù)類型和存儲模式,以便編譯系統(tǒng)為它分配相應(yīng)的存儲單元。C51對變量的定義格式如下:

微課:C51變量的定義
[存儲種類] 數(shù)據(jù)類型 [存儲器類型] 變量名表
常用的轉(zhuǎn)義字符如表2-7所示。
表2-7 常用的轉(zhuǎn)義字符表

下面分別介紹變量定義格式中的各項。
1.存儲種類
存儲種類項為可選項。變量的存儲種類有4 種:自動(auto)、外部(extern)、靜態(tài)(static)和寄存器(register)。如果在定義變量時省略該項,則默認(rèn)為自動(auto)變量。
自動變量(auto)指被說明的對象放在內(nèi)存的堆棧中。只有在定義它的函數(shù)被調(diào)用或是定義它的復(fù)合語句被執(zhí)行時,編譯器才為其分配內(nèi)存空間。當(dāng)函數(shù)調(diào)用結(jié)束返回時,自動變量所占用的空間就被釋放。
外部變量(extern)指在函數(shù)外部定義的變量,也稱為全局變量。只要一個外部變量被定義后,它就被分配了固定的內(nèi)存空間,即使函數(shù)調(diào)用結(jié)束返回,其存儲空間也不被釋放。
靜態(tài)變量(static)分為內(nèi)部靜態(tài)變量和外部靜態(tài)變量兩種。如果希望定義的變量在離開函數(shù)后到下次進入函數(shù)前變量值保持不變,就需要使用靜態(tài)變量說明。使用這種類型對變量進行說明后,變量的地址是固定的。
寄存器變量(register)指定將變量放在CPU的寄存器中,程序執(zhí)行效率最高。
2.?dāng)?shù)據(jù)類型
C語言的數(shù)據(jù)類型可分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型,其中復(fù)雜數(shù)據(jù)類型又是由基本數(shù)據(jù)類型構(gòu)造而成。C51中的數(shù)據(jù)類型既包含與C語言中相同的數(shù)據(jù)類型,也包含其特有的數(shù)據(jù)類型。

微課:C51中的基本數(shù)據(jù)類型
(1)char:字符型
字符型數(shù)據(jù)的長度為一個字節(jié)。有signed char (有符號數(shù))和unsigned char (無符號數(shù))兩種,默認(rèn)值為signed char。unsigned char類型數(shù)據(jù)可以表達(dá)的數(shù)值范圍是0~255; signed char類型數(shù)據(jù)的最高位表示符號位,“ 0”為正數(shù),“1”為負(fù)數(shù)。負(fù)數(shù)用補碼表示,其表達(dá)的數(shù)值范圍是-128~+127。
(2)int:整型
整型數(shù)據(jù)的長度為雙字節(jié)。有 signed int 和 unsigned int 兩種,默認(rèn)值為 signed int。unsigned int類型數(shù)據(jù)可以表達(dá)的數(shù)值范圍是0~65 535; signed int類型數(shù)據(jù)的最高位表示符號位,“0”為正數(shù),“1”為負(fù)數(shù),其表達(dá)的數(shù)值范圍是-32 768~+32 767。
(3)long:長整型
長整型數(shù)據(jù)的長度為4個字節(jié)。有signed long和unsigned long 兩種,默認(rèn)值為signed long。unsigned long類型數(shù)據(jù)可以表達(dá)的數(shù)值范圍是0~4 294 967 295; signed long類型數(shù)據(jù)的最高位表示符號位,“0”為正數(shù),“1”為負(fù)數(shù),其表達(dá)的數(shù)值范圍是-2 147 483 648~+2 147 483 647。
(4)float:浮點型
浮點型數(shù)據(jù)是指符合IEEE-754標(biāo)準(zhǔn)的單精度浮點型數(shù)據(jù),其長度為4個字節(jié)。在內(nèi)存中的存放格式如下。

其中,S表示符號位,“0”為正數(shù),“1”為負(fù)數(shù)。E為階碼,占8位二進制數(shù)。階碼的E值是以2為底的指數(shù)再加上偏移量127表示的,其取值范圍是1~254。M為尾數(shù)的小數(shù)部分,用23位二進制數(shù)表示,尾數(shù)的整數(shù)部分永遠(yuǎn)是“1”,因此被省略,但實際是隱含存在的。一個浮點數(shù)的數(shù)值可表示為(-1)S×2E-127×(1.M)。
例如,-7.5=0xC0F00000,以下為該數(shù)在內(nèi)存中的格式。

除以上幾種基本數(shù)據(jù)類型外,還有以下一些數(shù)據(jù)類型。
(5)?:指針型
指針型數(shù)據(jù)與前4種數(shù)據(jù)結(jié)構(gòu)不同的是,它本身就是一個變量,在這個變量中存放的不是數(shù)據(jù)而是指向另一個數(shù)據(jù)的地址。C51中的指針變量的長度一般為1~3 B。其變量類型的表示方法是在指針符號“?”的前面冠以數(shù)據(jù)類型的符號,如char ? point1表示point1是一個字符型的指針變量。
指針型變量的用法與匯編語言中的間接尋址方式類似,表2-8 表示兩種語言的對照用法。
表2-8 匯編語言與C語言的對照用法

(6)bit:位類型
位類型是C51編譯器的一種擴充數(shù)據(jù)類型,利用它可以定義一個位變量,但不能定義位指針,也不能定義位數(shù)組。它的值只可能為0或1。
(7)sfr:特殊功能寄存器類型
特殊功能寄存器類型也是C51編譯器的一種擴充數(shù)據(jù)類型,利用它可以定義51系列單片機的所有內(nèi)部8位特殊功能寄存器。sfr型數(shù)據(jù)占用一個內(nèi)存單元,取值范圍為0~255。例如:sfr P0=0x80,表示定義P0為特殊功能寄存器型數(shù)據(jù),且為P0口的內(nèi)部寄存器,在程序中就可以使用P0=255對P0口的所有引腳置高電平。
(8)sfr16:16位特殊功能寄存器類型
與sfr一樣,sfr16是用于定義51系列單片機內(nèi)部的16位特殊功能寄存器。它占用兩個內(nèi)存單元,取值范圍為0~65 535。
(9)sbit:可尋址位類型
可尋址位類型也是C51編譯器的一種擴充數(shù)據(jù)類型,利用它可以訪問51系列單片機內(nèi)部RAM的可尋址位及特殊功能寄存器中的可尋址位。例如:
sfr P1=0x90
sbit P1_1=P1^1
sbit OV=0xD0^2
表2-9列出了C51的所有數(shù)據(jù)類型。
表2-9 C51的所有數(shù)據(jù)類型

在C51中,如果出現(xiàn)運算對象的數(shù)據(jù)類型不一致的情況,按以下優(yōu)先級(由低到高)順序自動進行隱式轉(zhuǎn)換。
bit → char → int → long → float → singed → unsigned,轉(zhuǎn)換時由低向高進行。
(10)數(shù)組
C51編譯器除了能支持以上這些基本數(shù)據(jù)類型外,還能支持復(fù)雜的構(gòu)造類型,如數(shù)組、結(jié)構(gòu)體、聯(lián)合體等,數(shù)組就是一種常用的數(shù)據(jù)類型。
1)數(shù)組定義
在C51中,數(shù)組必須先定義后使用。一維數(shù)組的定義格式如下:
類型說明符 數(shù)組名 [常量表達(dá)式];
類型說明符是指數(shù)組中的各個數(shù)組元素的數(shù)據(jù)類型;數(shù)組名是用戶定義的數(shù)組標(biāo)識符;方括號中的常量表達(dá)式表示數(shù)組元素的個數(shù),也稱為數(shù)組的長度。
例如:
int a[10]; / /定義整型數(shù)組a,有10個元素 char ch[20]; / /定義字符數(shù)組ch,有20個元素
定義數(shù)組時,應(yīng)注意以下幾點:
[1] 數(shù)組的類型實際上是指數(shù)組元素的取值類型。對于同一個數(shù)組,所有元素的數(shù)據(jù)類型都是相同的。
[2] 數(shù)組名的書寫規(guī)則應(yīng)符合標(biāo)識符的書寫規(guī)定。
[3] 數(shù)組名不能與其他變量名相同。
[4] 方括號中常量表達(dá)式表示數(shù)組元素的個數(shù),如a[5] 表示數(shù)組a有5個元素。數(shù)組元素的下標(biāo)從0開始計算,5個元素分別為a[0]、a[1]、a[2]、a[3]、a[4]。
[5] 方括號中的常量表達(dá)式不可以是變量,但可以是符號常數(shù)或常量表達(dá)式。
2)數(shù)組元素
數(shù)組元素也是一種變量,其標(biāo)志方法為數(shù)組名后跟一個下標(biāo)。下標(biāo)表示該數(shù)組元素在數(shù)組中的順序號,只能為整型常量或整型表達(dá)式。如為小數(shù)時,C51編譯器將自動取整。定義數(shù)組元素的一般形式為:
數(shù)組名[下標(biāo)]
在程序中不能一次引用整個數(shù)組,只能逐個使用數(shù)組元素。例如,數(shù)組a包括10個數(shù)組元素,累加10個數(shù)組元素之和,必須使用下面的循環(huán)語句逐個累加各數(shù)組元素:
int a[10],sum; sum=0; for (i=0; i<10; i++)sum=sum+a[ i] ;
不能用一個語句累加整個數(shù)組,下面的寫法是錯誤的:
sum=sum+a;
3)數(shù)組賦值
結(jié)合數(shù)組賦值的方法有賦值語句和初始化賦值兩種。
[1] 數(shù)組賦值語句賦值。在程序執(zhí)行過程中,可以用賦值語句對數(shù)組元素逐個賦值,例如:
for (i=0; i<10; i++) num[ i] =i;
[2] 數(shù)組初始化賦值。這種方式在數(shù)組定義時給數(shù)組元素賦予初值,是在編譯階段進行的,可以減少程序運行時間,提高程序執(zhí)行效率。初始化賦值的一般形式為:
類型說明符 數(shù)組名 [常量表達(dá)式] = {值,值,…,值};
其中,在 {} 中的各數(shù)據(jù)值即為相應(yīng)數(shù)組元素的初值,各值之間用逗號間隔,例如:
int num[10] = {0,1,2,3,4,5,6,7,8,9};
相當(dāng)于:
num[0] =0; num[1] =1; …; num[9] =9;
3.存儲器類型
該項為可選項。Keil Cx51編譯器完全支持51系列單片機的硬件結(jié)構(gòu)和存儲器組織,對每個變量可以定義表2-10中的存儲器類型。
表2-10 Keil Cx51編譯器所能識別的存儲器類型

若在定義變量時省略了存儲器類型項,則按編譯時使用的存儲器模式來確定變量的存儲器空間。Keil Cx51編譯器的3種存儲器模式為SMALL、LARGE和COMPACT,這3種模式對變量的影響如表2-11所示。
表2-11 存儲器模式對變量的影響

變量應(yīng)用舉例如下。
char data var; /? 在data區(qū)定義字符型變量var ?/ int a=5; /? 定義整型變量a,同時賦初值等于5,變量a 位于由編譯器的存儲器模式確定的默認(rèn)存儲 區(qū)中 ?/ char code text[ ] = “ HELLO!” ; /? 在code區(qū)定義字符串?dāng)?shù)組 ?/ unsigned int xdata time; /? 在xdata區(qū)定義無符號整型變量time ?/ extern float idata x,y,z; /? 在idata區(qū)定義外部浮點型變量x,y,z ?/ char xdata ?px; /? 指針 px 指向 char 型 xdata 區(qū),指針 px 自身 在默認(rèn)存儲區(qū),指針長度為雙字節(jié) ?/ char pdata ?data py; /? 指針py 指向 char 型 pdata 區(qū),指針 py 自身 在data區(qū),指針長度為單字節(jié) ?/ static bit data port; /? 在data區(qū)定義了一個靜態(tài)位變量port ?/ int bdata x; /? 在bdata區(qū)定義了一個整型變量x ?/ sbit x0=x^0; /? 在bdata區(qū)定義了一個位變量x0 ?/ sfr P0=0x80; /? 定義特殊功能寄存器名P0 ?/ sfr16 T2=0xCC; /? 定義特殊功能寄存器名T2 ?/
- MC9S12XS單片機原理及嵌入式系統(tǒng)開發(fā)
- 嵌入式Linux接口開發(fā)技術(shù)
- 基于HCS12的嵌入式系統(tǒng)設(shè)計
- 單片機應(yīng)用技術(shù)
- 嵌入式產(chǎn)品分析與設(shè)計
- 嵌入式軟件自動化測試
- 零起點學(xué)Proteus單片機仿真技術(shù)
- PIC單片機常用模塊與綜合系統(tǒng)設(shè)計實例精講
- ANSYS Workbench 17.0有限元分析從入門到精通
- 單片微型計算機原理及應(yīng)用
- 零基礎(chǔ)學(xué)51單片機(C語言版)
- 51單片機工程師是怎樣煉成的:基于C語言+Proteus仿真
- 單片機技術(shù)及應(yīng)用(第2版)
- AVR單片機原理與應(yīng)用實例
- 嵌入式通信系統(tǒng)