機(jī)電之家資源網(wǎng)
單片機(jī)首頁|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
嵌入式C編程技術(shù)(一)
嵌入式C編程技術(shù)(一)
 更新時(shí)間:2008-8-18 14:35:54  點(diǎn)擊數(shù):56
【字體: 字體顏色
 

  在C語言中每個(gè)變量和函數(shù)都有其存儲(chǔ)屬性。存儲(chǔ)屬性關(guān)系到變量和函數(shù)的可見性與生存期,即變量和函數(shù)所占存儲(chǔ)位置的作用域和時(shí)限。

  變量的可見性:指變量在其作用域內(nèi)是可以訪問的,或者說是變量的可見區(qū)域。變量的生存期:指在一定范圍內(nèi)變量值保存的時(shí)限。

  由于變量的存儲(chǔ)屬性不同,有的變量可在程序的各個(gè)函數(shù)中使用,稱全局變量或全程變量;有的只能在特定函數(shù)中使用,稱局部變量;有些可為所屬文件中的函數(shù)使用,稱局部于文件函數(shù)的局部變量。

  C語言的存儲(chǔ)屬性分為三類:自動(dòng)的、外部的和靜態(tài)的,其相應(yīng)的存儲(chǔ)類別說明符分別是:

  auto自動(dòng)的
  extern外部的
  static靜態(tài)的

  Franklin C51支持“基于存儲(chǔ)器的指針”和“一般指針”;诖鎯(chǔ)器的指針由C源程序中的存儲(chǔ)類型決定其存儲(chǔ)單元數(shù)。用這種指針可高效訪問對(duì)象,且只需1至2字節(jié)。而一般指針需要3字節(jié):2字節(jié)偏移和1字節(jié)存儲(chǔ)類型。指針的定義如表3所列。

  例:

  char xdata*px;指針自身在默認(rèn)存儲(chǔ)區(qū)(取決于存儲(chǔ)模式)
  char xdata*data pdx;指針明確位于內(nèi)部數(shù)據(jù)存儲(chǔ)區(qū)(data)
  data char xdata*pdx;與上同

表3
 

2. 動(dòng)態(tài)和靜態(tài)分配的變量

  在C程序中,在一個(gè)函數(shù)中定義的自動(dòng)變量是動(dòng)態(tài)分配的變量。

  自動(dòng)變量是:
  -局部變量的一種;
  -在一個(gè)函數(shù)中定義的變量;
  -只能在其定義的函數(shù)內(nèi)部訪問。

  當(dāng)調(diào)用一個(gè)函數(shù)時(shí),函數(shù)中的自動(dòng)變量在RAM或寄存器中分配存儲(chǔ)。當(dāng)一個(gè)函數(shù)執(zhí)行完時(shí),分配的RAM單元或寄存器釋放。因此,自動(dòng)變量?jī)H在定義它們的函數(shù)內(nèi)部可以訪問。

  在C程序中,外部變量(在函數(shù)外用“extern”說明定義)和靜態(tài)變量(用“static”說明定義)是靜態(tài)分配的變量。

  ·外部變量(extern)
  -在函數(shù)外部定義;
  -在模塊中任何位置可以訪問;
  -在存儲(chǔ)器中分配固定的存儲(chǔ)單元。

  ·靜態(tài)變量(static)
  -只能在定義的有效范圍內(nèi)使用;
  -在存儲(chǔ)器中分配固定的存儲(chǔ)單元。

  變量的存儲(chǔ)空間是動(dòng)態(tài)分配還是靜態(tài)分配取決于它在程序中定義的位置。外部變量在函數(shù)外定義,在RAM中分配變量的存儲(chǔ)空間。由于變量的RAM單元已分配,因而,它可以在程序模塊中的任何地方訪問。

  “static”定義的靜態(tài)變量雖然也在RAM中分配單元,但“靜態(tài)變量有效范圍”的存在,使得靜態(tài)變量的可見性取決于它在程序中定義的位置。在函數(shù)外定義的靜態(tài)變量稱作靜態(tài)全局變量,而在函數(shù)內(nèi)部定義的靜態(tài)變量稱作靜態(tài)局部變量。

  靜態(tài)局部變量又稱內(nèi)部靜態(tài)變量。它在函數(shù)內(nèi)定義,但不像自動(dòng)變量那樣,當(dāng)函數(shù)調(diào)用它時(shí)就存在,退出函數(shù)它就消失。靜態(tài)變量始終存在著,但函數(shù)外部不能存取它,只能在函數(shù)內(nèi)部訪問,退出函數(shù)后,雖然數(shù)據(jù)仍保存,但不能訪問。

  靜態(tài)全局變量又稱外部靜態(tài)變量。它在函數(shù)外面被定義,它的作用域從被定義的地方開始,一直到源文件結(jié)束。但一個(gè)程序由若干個(gè)文件組成時(shí),靜態(tài)全局變量始終存在著,但它只能在被定義的文件內(nèi)訪問,可供該文件內(nèi)的所有函數(shù)共享此數(shù)據(jù),退出文件后,雖然數(shù)據(jù)仍保存,但不能被其他文件訪問。

文件1:

init();
extern
int numproc;
int currid;
int semno;
int nextsem=0;
static int nextproc=100;
null()
{
  int userpid=10;
  init();
  currid=userpid;
  nextsem++;
  semno=100-nextsem;
  return(semno); }
init()
{
  static int num=50;
  int i=0;
  int j;
  return(num--);
}

文件2:

extern null();
extern int numproc;
extern int currid;
extern int semno;
extern int nextsem;
int numproc=100;
static int nextproc=50;
start()
{
  int pid=0;
  if(null()>0) pid++;
}

  “num”是靜態(tài)局部變量,它分配的RAM單元僅有定義它的init()函數(shù)可以使用!皀extproc”是靜態(tài)全局變量,“nextproc”變量?jī)H在定義它的源程序文件中可見。另一個(gè)程序文件不能訪問到它分配的單元,因而,兩個(gè)“nextproc”變量分配不同的存儲(chǔ)單元。

  綜上可知,靜態(tài)變量在定義它的函數(shù)或文件之外是不可訪問的、未知的,但它們?cè)诤瘮?shù)調(diào)用之間可以保存其值,這一特征使靜態(tài)變量很有用處,如用它編寫通用函數(shù)和庫函數(shù)時(shí),這些函數(shù)可被其他編程者使用。

(1)  自動(dòng)變量

  自動(dòng)的存儲(chǔ)屬性是C語言中使用最廣泛的一類。按照缺省規(guī)則,在C語言程序中,每個(gè)函數(shù)的函數(shù)體所說明的變量,凡不加存儲(chǔ)屬性說明的,都表示為自動(dòng)存儲(chǔ)類別。當(dāng)然,對(duì)這些變量說明時(shí),也可以在前面綴以說明符auto,但習(xí)慣上通常都采用缺省形式,例如:

  char c;

等價(jià)于

  auto char c;

  自動(dòng)變量的作用域,僅局限于定義該變量的函數(shù),因而是局部變量。其可見性與生命期和作用域相同。

  自動(dòng)變量只在定義它的函數(shù)調(diào)用時(shí),系統(tǒng)才對(duì)它分配存儲(chǔ)空間,開始它的生命期;在從函數(shù)返回時(shí),它所占的存儲(chǔ)位置就自動(dòng)被抹除,從而結(jié)束它的生存期。因此,C語言將這種局部于函數(shù)的變量稱為自動(dòng)變量。

  由于自動(dòng)變量隨函數(shù)的返回而消失,其存儲(chǔ)位置被抹除,故其值不能被保留。若程序下次再調(diào)用該函數(shù),雖然又對(duì)此自動(dòng)變量分配存儲(chǔ)空間,但它不會(huì)保留前次運(yùn)算得到的結(jié)果,故在函數(shù)體中必須給它進(jìn)行賦值。

  因?yàn)樽詣?dòng)變量的可見性局限于定義它的函數(shù),對(duì)其他函數(shù)來說,它是不可見的,故其名可以被其他函數(shù)重復(fù)使用,它們各有自己的作用域,不會(huì)產(chǎn)生誤解,例如:

  main()
  { int i,j,k;
  …
  }
  fun()
  {int i,j,k;
  …
  }

  其中兩個(gè)函數(shù)main()和fun()都定義了變量i、j、k,雖然它們都是自動(dòng)變量,各自局限于定義它們的函數(shù),兩者之間沒有相關(guān)的聯(lián)系。

  局部變量的概念可以擴(kuò)充到分程序,即對(duì)于分程序中的自動(dòng)變量,其作用域只局限于該程序內(nèi)。在分程序嵌套使用時(shí),若同名變量,其內(nèi)層變量的作用域也是局限于定義它的那個(gè)層次。

  C編譯器總是嘗試在寄存器里保持局部變量。這樣,將索引變量(如for和while循環(huán)中計(jì)數(shù)變量)定義為局部變量是最好的。只要有可能,在函數(shù)中使用自動(dòng)變量。

(2)  外部變量

  外部變量的存儲(chǔ)屬性說明符是extern。按照缺省規(guī)則,凡是在所有函數(shù)之前,在函數(shù)外面定義的變量都是外部變量,定義時(shí)可以不寫說明符extern,但在函數(shù)體內(nèi)定義外部變量時(shí),必須要用extern說明。

  一個(gè)外部變量定義后,系統(tǒng)就給它分配固定的存儲(chǔ)空間,所有的函數(shù)和分程序都可以使用它。當(dāng)退出一個(gè)分程序,或從某一函數(shù)返回后,外部變量的空間并不回收,其值也仍然保留,可供其他函數(shù)所公用。故此,外部變量是全局變量。其作用域、可見性和生存期是整個(gè)程序。

  C語言允許將大型程序分解為若干個(gè)獨(dú)立文件,分別進(jìn)行編譯,然后連接在一起,從而提高編譯速度,且便于管理。此時(shí),當(dāng)某變量需要在所有文件中通用時(shí),則只要在一個(gè)文件中說明其為全局變量,而在其他文件中用extern說明該變量就可以了。

  例如,現(xiàn)有兩個(gè)文件File1和File2,它們都要用到3個(gè)變量i、j和ch,則在分別編譯的程序模塊中,對(duì)全局變量的說明如下:

File1

int i,j;
char ch;
main()
{
  …
}
func11()
{
  i=120;
  …
}

File2

extern int i,j;
extern char ch;
func21()
{
  …
  i=j/10;
  …
}
func22()
{
  …
  j=10;
  …
}

  其中,File2的extern通知編譯程序,它所定義的變量已在別的文件中說明,使編譯程序知其類型和名稱,而不用再為它們分配存儲(chǔ)空間。

(3)  靜態(tài)全局變量

  在全局變量說明前加上static說明符就構(gòu)成靜態(tài)全局變量。它是一種作用域受限制的外部變量。其作用域是從說明處開始直至該文件的末尾,即它只在被定義的這個(gè)文件中是可見的。雖然它也是全局變量,但其他文件無法改變其內(nèi)容,從而可以避免其他文件可能引起的錯(cuò)誤。

  源文件:

int timeint();
int time;
static int count=0;
int list()
{
  int flag=0;
  if(++count>=60)/* line 8 */
    flag=timeint();
  return(flag);
}
int timeint()
{
  int temp;
  if(!--temp){
    time=10;
    count-=60;/* line 18 */
  }
  temp=time*count;/* line 20 */
  return(temp);
}

  “count”變量在函數(shù)的外部定義是靜態(tài)全局變量!癱ount"變量在RAM中分配存儲(chǔ)單元保存它的值,可以在它編譯連接后生成的映像文件(.M51)中看到它分配的內(nèi)部RAM單元的地址,在列表文件(.LST)中可以看到其存儲(chǔ)單元的訪問和存儲(chǔ)器的使用情況。

  映像文件:

D:000AH  SYMBOL  count
D:000CH  PUBLIC  time
D:0008H  SYMBOL  flag
D:0002H  SYMBOL  temp

  “count”變量分配的內(nèi)部RAM單元的地址是0AH。

  列表文件:

; SOURCE LINE # 8
0005 0500  R  INC count+01H
0007 E500  R  MOV A,count+01H
0009 7002    JNZ ?C0005
000B 0500  R  INC count
000D    ?C0005:
000D C3     CLR C
000E 943C    SUBB A,#03CH
0010 E500  R  MOV A,count
0012 6480    XRL A,#080H
0014 9480    SUBB A,#080H
0016 4007    JC ?C0001
; SOURCE LINE # 18
000E 74C4    MOV A,#0C4H
0010 2500  R  ADD A,count+01H
0012 F500  R  MOV count+01H,A
0014 74FF    MOV A,#0FFH
0016 3500  R  ADDC A,count
0018 F500  R  MOV count,A
; SOURCE LINE # 20
001A AC00  R  MOV R4,count
001C AD00  R  MOV R5,count+01H
001E AE00  R  MOV R6,time
0020 AF00  R  MOV R7,time+01H
0022 120000E  LCALL ?CIMUL
0025 AA06    MOV R2,AR6
0027 AB07    MOV R3,AR7
  MODULE INFORMATION:STATIC OVERLAYABLE
  CODE SIZE  =  78  ---
  CONSTANT SIZE  =  ---  ---
  XDATA SIZE  =  ---  ---
  PDATA SIZE  =  ---  ---
  DATA SIZE  =  4  2
  IDATA SIZE  =  ---  ---
  BIT SIZE  =  ---  ---
END OF MODULE INFORMATION.

  上面是和“count”變量有關(guān)源程序行對(duì)應(yīng)的匯編程序以及程序存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器的使用情況。(待續(xù))

  • 上一篇: 采用TL431及光耦合器反饋情況下的增益考慮
  • 下一篇: 嵌入式C編程技術(shù)(二)
  • 發(fā)表評(píng)論   告訴好友   打印此文  收藏此頁  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評(píng)論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對(duì)此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請(qǐng)聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國(guó)行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營(yíng)許可證:浙B2-20080178-1