| [編者按] 為使廣大嵌入式系統(tǒng)應(yīng)用技術(shù)人員系統(tǒng)地了解和掌握一些先進(jìn)應(yīng)用、開發(fā)技術(shù),本刊從創(chuàng)刊號起開辟《學(xué)習(xí)園地》欄目。上半年集中介紹嵌入式C編程技術(shù)(一)~(六),內(nèi)容包括單片機(jī)C語言應(yīng)用程序設(shè)計中的變量定義和變量空間、C語言編程技巧、函數(shù)有效使用及混合編程技術(shù)。 嵌入式C編程技術(shù)(二) 北京理工大學(xué)馬忠梅 (4) 靜態(tài)局部變量 在局部變量說明前加上“static”說明符就構(gòu)成靜態(tài)局部變量。它是1種在2次函數(shù)調(diào)用之間仍能保持其值的局部變量。有些例行程序須要在多次調(diào)用之間保存變量的值,自動變量做不到,若用全局變量,有時會帶來意外的副作用,這時可采用靜態(tài)局部變量。在實際應(yīng)用中,要注意靜態(tài)變量與自動變量的區(qū)別。 下述程序由2個函數(shù)組成1個文件,其中main多次調(diào)用f,在f()中既有自動變量m,又有靜態(tài)變量n,從運行結(jié)果可以分析它們的區(qū)別。 main() { int i,j,k; i=5; j=10; for(k=1;k<=5;k++) f(i,j,k); } f(x,y,z) int x,y,z; { int m; static int n; if(z= =1) { m=0; n=0; } else { m=m+x+y; n=n+x+y; } } 在主函數(shù)中,k由1到5,控制循環(huán)5次,分別調(diào)用函數(shù)f(i,j,k)。在被調(diào)用函數(shù)f(x,y,z)中,第1次z=1,給m和n賦初值,結(jié)果m=0,n=0。此后,由于n為靜態(tài)變量,在2次函數(shù)調(diào)用之間,其值仍然保存,故以后幾次運算,n的值有連續(xù)性,每次加15。但m是自動變量,從第2次循環(huán)開始,m的初值不再保存,而函數(shù)中又未對m重新賦值,故m為1個無意義的不定值。 源程序: int timeint(); int time; int list() { int flag=0; static int count=0; if(++count>=60) flag=timeint(); return(flag); } int timeint() { int temp; static int count=1000; if(!--time){ time=10; count-=60; } temp=time*count; return(temp); } “count”變量在函數(shù)的內(nèi)部定義是靜態(tài)局部變量,list()函數(shù)中定義的“count”變量和timeint()函數(shù)中定義的“count”變量在內(nèi)部RAM中分配不同的地址單元保存它們的值。參見映像文件“.M51”。 映像文件: \ \ \ \ 〖〗PROC〖〗LIST〖〗D:000EH〖〗SYMBOL〖〗flag〖〗D:0008H〖〗SYMBOL〖〗count〖〗\ \ \ \ 〖〗ENDPROC〖〗 LIST〖〗\ \ \ \ 〖〗PROC〖〗TIMEINT〖〗D:0006H〖〗SYMBOL〖〗temp〖〗D:000AH〖〗SYMBOL〖〗count〖〗\ \ \ \ 〖〗ENDPROC〖〗TIMEINT“count”變量在2個函數(shù)中分配的內(nèi)部RAM單元地址分別為08H和0AH。 靜態(tài)局部變量只在定義它的函數(shù)內(nèi)部有效,任何其他函數(shù)都不能訪問,甚至在同一編譯模塊中的函數(shù)也是如此。 3 只讀變量和變量空間 在程序執(zhí)行過程中,變量從存儲器中讀出它的值,然后再把新值寫入到存儲器中,這就是為何把變量的存儲空間定位在RAM中。RAM中的變量是可以修改的,但是,也有一些變量,如錯誤信息和固定值,程序不須要改變它們。像常規(guī)外部變量一樣,在RAM空間中保存這些只讀變量是浪費RAM空間的?梢允褂谩#define”定義只讀變量為1個常數(shù)值,這種方法可以保留RAM空間。下面程序比較了只讀值用外部變量說明和用“#define”定義成數(shù)值常數(shù)。 源程序1: int maxaddr=32767; float pai=3.14159; double list(int addr,int dia) { double length; if(maxaddr<=addr) length=dia*pai; else length=0; return(length); } 列表文件1: MODULE INFORMATION:STATIC OVERLAYABLE CODE SIZE=64\ \ \ \ CONSTANT SIZE=\ \ \ \ \ \ \ \ XDATA SIZE=\ \ \ \ \ \ \ \ PDATA SIZE=\ \ \ \ \ \ \ \ DATA SIZE=64 IDATA SIZE=\ \ \ \ \ \ \ \ BIT SIZE=\ \ \ \ \ \ \ \ END OF MODULE INFORMATION. 源程序2: #define maxaddr 32767 #define pai 3.14159 double list(int addr,int dia) { double length; if(maxaddr<=addr) length=dia*pai; else length=0; return(length); } 列表文件2: MODULE INFORMATION:STATIC OVERLAYABLE CODE SIZE=64\ \ \ \ CONSTANT SIZE=\ \ \ \ \ \ \ \ XDATA SIZE=\ \ \ \ \ \ \ \ PDATA SIZE=\ \ \ \ \ \ \ \ DATA SIZE=\ \ \ \ 4 IDATA SIZE=\ \ \ \ \ \ \ \ BIT SIZE=\ \ \ \ \ \ \ \ END OF MODULE INFORMATION. 從上面程序結(jié)果可以看到只讀變量的處理: (1) 定義成外部變量 變量在RAM中保留存儲單元,但從不寫入。靜態(tài)占用的RAM單元6個,可覆蓋的RAM單元4個。 (2) 定義成數(shù)值常數(shù) 不在RAM中保留存儲單元。靜態(tài)占用的RAM單元沒有,可覆蓋的RAM單元4個。 4. 使用自動變量減少變量占用空間 首先看外部變量。外部變量在RAM中分配變量的存儲空間。我們使用的許多C程序常常把僅在特定函數(shù)使用的變量定義成外部變量。把有限范圍使用的變量定義成外部變量無疑會增加變量存儲空間的大小。盡可能地把僅在函數(shù)內(nèi)訪問的外部變量替換成自動變量來保留變量的存儲空間。 當(dāng)函數(shù)被調(diào)用時,函數(shù)中的自動變量在RAM中保留存儲空間;當(dāng)函數(shù)完成后立即釋放。在函數(shù)中定義自動變量比在模塊中定義外部變量可以減少變量的存儲空間。當(dāng)函數(shù)嵌套調(diào)用時,保留存儲空間更為重要。 下面是外部變量和局部變量比較的例程。1個是把僅在1個函數(shù)內(nèi)部訪問的變量定義成外部變量,而另一個是定義成局部變量。 源程序1: #define MAXPROC 100 #define ERR 1 int procno; int currproc; int nextproc; int list1() { if((MAXPROC-procno)>=0){ procno++; nextproc=cur |