- 單片機C語言程序設(shè)計實訓(xùn)100例
- 彭偉編著
- 1682字
- 2018-12-27 05:11:56
1.7 數(shù)組、字符串與指針
本書大量案例使用了數(shù)組定義,例如,下面的數(shù)組DSY_CODE定義了0~9的七段數(shù)碼管段碼表:
uchar code DSY_CODE[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
由于在程序運行過程中DSY_CODE的數(shù)據(jù)保持不變,因此,這里將存儲類型設(shè)為code,如果將code改為data也不會影響程序的運行,只是在程序運行時數(shù)組會被分配到數(shù)據(jù)RAM,而不是僅占用程序ROM空間,在Small模式下,省略code相當于將程序存儲類型設(shè)為默認的data類型。
讀者在實際設(shè)計時,如果要將變化的數(shù)組定義在數(shù)據(jù)RAM中,由于data類型僅允許使用128B,如果編譯時提示數(shù)據(jù)RAM空間不夠,可嘗試將data改為idata,例如:
uchar idata Sort_Result[200];
另外,存儲類型code、data和idata還可以放到數(shù)據(jù)類型前面。
字符串類型也在本書大量案例中使用,例如,下面的字節(jié)串定義:
char s[20] = "Current Voltage:"; char s[20] = {"Current Voltage:"}; char s[20] = {'R','e','s','u','l','t',':'};
這3種定義是完全相同的,它們都占用20B空間,實際串長為16個字符,最后未明確賦值的4B全部為0x00(即'\0'),在液晶屏上顯示這類字符串時,可用以下方法:
(1)for(i = 0; i < 16; i++){//顯示字符s[i]}; (2)for(i = 0; i < strlen(s1); i++){//顯示字符s[i]}; (3)i = 0; while (s[i++]!= '\0') {//顯示字符s[i]};
要注意的是,如果字符串長為16,而字符數(shù)據(jù)空間也只固定給出了16B,那么上述方法中的后兩種就不可靠了,因為最后一個字符后面不一定是字符串結(jié)束標志'\0'。
字符串還可以這樣定義:
char s[] = "Current Voltage:"; char *s = "Current Voltage:";
這兩種定義也是相同的,其串長均為16 個字符,所占用的字節(jié)空間均為17B,因為字符串末尾被自動附加了結(jié)束標志字節(jié)0x00(即'\0')。
在已知串長時,上述三種字符串顯示方法均可使用,在字符串長未知時可使用上述方法中的后兩種,另外,上述顯示方法還可以改寫成:
(1)for(i = 0; i < 16; i++){//顯示字符*(s+i)}; (2)for(i = 0; i < strlen(s1); i++){//顯示字符*(s+i)}; (3)i = 0; while (*(s+i)!= '\0') {//顯示字符*(s+i);i++;};
在編寫C語言程序時,除使用字符數(shù)組(字符串)外,還會使用字符串數(shù)組,例如:
char s[][20] = {"Current Voltage:","Counter: ","TH: TL: "};
如果要在液晶上顯示“Counter:”這個字符串,可用以下語句實現(xiàn):
for(i = 0; i < strlen(s[1]);i++){//顯示字符s[1][i]};
在英文字符液晶上顯示數(shù)值時需要將待顯示數(shù)據(jù)轉(zhuǎn)換為字符串,這時可用此前提到的數(shù)據(jù)位分解方法,先分解出各位數(shù)字,然后加上0x30(即'0')得到對應(yīng)數(shù)字的ASCII編碼。另一種更為簡單的方法是使用sprintf函數(shù),示例代碼如下:
char Buf[10]; float x = -123.45; sprintf(Buf , "%5.2f" , x);
上述語句運行后,Buf會被以下字節(jié)填充:
0x2D,0x31,0x32,0x33,0x2E,0x34,0x35,0x00,0x00,0x00
這些字節(jié)代表字符串"-123.45",該字符串可直接送字符至液晶屏顯示。
如果已經(jīng)有語句:
char Buf[25] = "Result: "; 語句sprintf(Buf + 7 , "%5.2f" , x)會使Buf中的字符串會變?yōu)椋?Result: -123.45"
讀者還可以使用下面的語句得到同樣的結(jié)果:
char Buf[25]; sprintf(Buf , "Result:%5.2f" , x) ;
另外,C語言還提供了與字符串有關(guān)的數(shù)據(jù)轉(zhuǎn)換函數(shù)atoi、atol、atof、strtod、strtol、strtoul,讀者在程序設(shè)計中涉及數(shù)據(jù)輸入/輸出及運算與顯示時可以恰當使用這些函數(shù)。
指針是C語言的重要特色之一,對于語句:
uchar d[10] = {1,2,3,4,5,6,7,8,9,10}; uchar *pd = d;
pd指向數(shù)組d中的第0個字節(jié),顯示數(shù)組內(nèi)容可使用下面的代碼:
for(i = 0;i < 10; i++) {//輸出d[i]、*(pd+i)、*pd++ 或 *(d+i)};
但是不能使用下面的代碼:
for(i = 0;i < 10; i++) {//輸出*d++};
因為數(shù)組名d雖然也是第0個字節(jié)的地址,但它不能在運行過程中改變,也正是因為數(shù)組名同樣也是第0個元素的指針,因此,某些函數(shù)定義中的形參為數(shù)組,調(diào)用函數(shù)時給出的實參常為指向同類型數(shù)據(jù)的指針,反之形參為指針,實參為數(shù)組名也很常見。
前面字符串示例中也出現(xiàn)了指針應(yīng)用,讀者同樣要能熟練運用它們。
由于8051及其派生系列具有獨特結(jié)構(gòu),Keil C51支持以下兩種不同類型的指針。
1)通用指針
上述示例uchar *pd中的pd就是通用指針,指針聲明與標準C語言完全一樣,其特點是總是用3B來存儲指針,第一字節(jié)表示存儲器類型,第二、三字節(jié)分別是指針所指向數(shù)據(jù)地址的高字節(jié)和低字節(jié),這種定義很方便但速度較慢,在所指向的目標空間不明確時普遍使用。
2)存儲器指針
這種指針在定義時指明了存儲器類型,并且指針總是指向特定的存儲器空間(片內(nèi)數(shù)據(jù)RAM、片外數(shù)據(jù)RAM或程序ROM),例如:
char data *str; int xdata *pd; ulong code *pul;
由于定義中已經(jīng)指明了存儲器類型,因此,相對于通用指針而言,指針第一字節(jié)省略,對于data、bdata、idata存儲器類型,指針僅需要1B,因為它們的尋址空間都在256B以內(nèi),而code和xdata存儲類型則需要2B指針,因為它們的尋址空間最大為64KB。
使用存儲器指針比使用通用指針效率高,指針所占空間小,速度更快,在存儲器空間明確時,建議使用存儲器指針,如果存儲器空間不明確則使用通用指針。
- Spring 5.0 Microservices(Second Edition)
- 國際大學(xué)生程序設(shè)計競賽中山大學(xué)內(nèi)部選拔真題解(二)
- What's New in TensorFlow 2.0
- Visual Basic程序開發(fā)(學(xué)習(xí)筆記)
- Learning ELK Stack
- Building Android UIs with Custom Views
- 深度學(xué)習(xí)原理與PyTorch實戰(zhàn)(第2版)
- iOS開發(fā)項目化入門教程
- 百萬在線:大型游戲服務(wù)端開發(fā)
- MongoDB Administrator’s Guide
- 零基礎(chǔ)學(xué)Java(第5版)
- Improving your Penetration Testing Skills
- Spring MVC Blueprints
- Mastering Swift 4(Fourth Edition)
- HTML 5與CSS 3權(quán)威指南(第4版·上冊)