在C51中對變量進行定義的格式如下:
【存儲種類】資料類型 【存儲器類型】 變量名清單;
其中存儲種類和存儲器類型是可選項,當變量名清單中的變量不止一個時,用逗号隔開。
存儲種類:4種
自動(auto),外部(extern),靜态(static)和寄存器(register)
存儲器類型:6種
DATA區、BDATA區、IDATA區、PDATA區、XDATA區、CODE區 指明該變量所處的記憶體空間
存儲模式: 3種
SMALL、COMPACT和LARGE 指明了變量在沒有指明存儲器類型時預設的存儲區域
1、存儲種類
自動(auto)變量
當變量的生命周期結束時,它所占的記憶體單元也就被釋放。定義變量時省略存儲種類,則該變量預設為自動變量。
int i=10;
……
}
main()
{……
add();在調用add()子函數時為i配置設定記憶體單元,調用結束後變量i所占用的記憶體被釋放。
……
}
外部(extern)變量
假設一個變量在函數體外或别的程式中已被定義過,并且在本函數體内要使用該變量,則該變量要在本函數體内用extern 說明。用extern定義的變量稱為外部變量。外部變量被定義後,在程式的執行過程中都是有效的。
靜态(static)變量
用static定義的變量稱為靜态變量。靜态變量在程式調用結束後其占用的記憶體單元并不被釋放(其值保持不變)。
寄存器(register)變量
用register聲明的變量稱為寄存器變量。該類變量速度最快,應該存放使用頻率最高的變量。通常C51編譯器會自動識别程式中使用頻率最高的變量,并自動将其作為寄存器變量,程式員無需專門聲明。
變量的存儲種類和存儲器類型是不一樣的。存儲器類型指明該變量所處的記憶體空間。單片機内部有程式存儲器和資料存儲器。資料存儲器又分為片記憶體儲器和片外存儲器。而片記憶體儲器又分為低128位元組和SFR特殊功能寄存器。
使用不同的存儲器類型,程式會有不同的執行效率,在編寫C51程式時,推薦指定變量的存儲器類型,這樣有利于提高程式的執行效率。
若省略存儲器類型,編譯器将根據使用的存儲器模式(SMALL,COMPACT,LARGE)來規定預設的存儲器類型。
六種存儲器類型
(1) DATA區
該區速度最快,是以應該存放使用頻率最高的變量。但是該區資源有限,除了存放變量外,還包含堆棧和寄存器組。一旦該區資源不夠,會使程式發生莫名其妙的錯誤。
變量定義舉例: char data i[10];
(2) BDATA區
在該區定義的變量,可以進行位尋址,并且可以聲明位變量。它可以單獨使用變量的某一位,而不一定要用位變量名引用位變量。
例如:
unsigned char bdata status;
if(status^5)
{
…………
}
注意該區不允許定義float類型的變量。
(3) IDATA區
該區使用寄存器間接尋址,可以存放使用比較頻繁的變量。變量定義舉例: float idata var;
(4) PDATA區
該區隻有一頁即256位元組,具體哪一頁有P2口指定。使用MOVX指令進行資料傳送。
變量定義舉例: long PDATA var
(5) XDATA區
該區和PDATA區類似,隻是空間增大了——64KB。對XDATA的尋址比對PDATA的尋址要慢(前者需要裝入16位位址,而後者隻需要裝載8位位址)。進行資料傳送時同樣需要使用MOVX指令。
變量定義舉例:unsigned char XDATA i;
(6) CODE區
該區為程式存儲器,代碼區中的資料一旦寫入不可擦除不可重寫。在該區中一般存放資料表,跳轉向量和狀态表等。變量定義舉例:
變量定義舉例:unsigned char CODE da[3]={0x04,0x58,0x56};
對于片外擴充I/O口,則要根據其硬體譯碼位址,将其視為片外資料存儲器的一個單元,在程式的開始位置使用#define 定義:
例:
#define <absacc.h>
#define
/*将PORTA定義為外部I/O口,其位址為0x8003*/,長度為一個位元組。
- 一旦在頭檔案或程式中對這些片内外I/O口進行定義以後,在程式中就可以自由使用這些I/O口了。
2、存儲模式
存儲模式指明了變量在沒有指明存儲器類型時預設的存儲區域,共有:SMALL、COMPACT和LARGE三種。
(1)SMALL模式
所有的預設變量,參數都存儲在内部RAM中,優點:存儲速度快,執行效率高。缺點:内部RAM有限,隻适合小程式。
(2)COMPACT模式
所有預設變量都存儲在外部RAM的一頁(256位元組)中。具體哪一頁可有P2口指定,該模式空間較SMALL模式充裕,速度較SMALL模式慢,較LARGE模式快,是一種中間模式。
(3)LARGE模式
所有參數變量都放在片外資料存儲器中,容量大,但速度慢。
- 通過#pragma定義,例如#pragma small。
3、指針的存儲類型
C51編譯器支援兩種不同類型的指針:存儲器指針和通用指針
(1)通用指針
通用或未定型的指針的聲明和标準C語言中一樣。
如 : char *s; /* string ptr */
int *numptr; /* int ptr */
long *state; /* long ptr */
通用指針總是需要三個位元組來存儲,第一個位元組是用來表示存儲
器類型,第二個位元組是指針的高位元組,第三位元組是指針的低位元組
存儲類型部分代表了該指針所指向的變量的存儲器類型,存儲類型的代碼如下表所示:
通用指針可以用來通路所有類型的變量,而不管變量存儲在哪個存儲空間中,因而許多庫函數都使用通用指針。通用指針很友善,但是也很慢,在所指向目标的存儲空間不明确的情況下它們用的最多。
(2)存儲器指針
存儲器指針或類型确定的指針,在定義時包括一個存儲器類型說明,并且總是指向此說明的特定存儲器空間,例如:
char data *str; /* ptr to string in data */
int xdata *numtab; /* ptr to int(s) in xdata */
long code *powtab; /* ptr to long(s) in code */
正是由于存儲器類型在編譯時已經确定,通用指針中用來表示存儲器類型的位元組就不再需要了。指向idata、data、bdata和pdata的存儲器指針用一個位元組儲存,指向code和xdata的存儲器指針用兩個位元組儲存,使用存儲器指針比通用指針效率要高,速度要快。