朋友圈

400-850-8622

全國統(tǒng)一學(xué)習(xí)專線 9:00-21:00

位置:影視設(shè)計(jì)培訓(xùn)資訊 > 動畫設(shè)計(jì)培訓(xùn)資訊 > 在嵌入式軟件編程中深入理解關(guān)鍵字

在嵌入式軟件編程中深入理解關(guān)鍵字

日期:2021-07-09 01:16:11     瀏覽:265    來源:東莞電工培訓(xùn)網(wǎng)
計(jì)算機(jī)編程語言的關(guān)鍵字就好比是它的靈魂,只有深入理解了它們的含義才能編寫出優(yōu)秀的代碼。C語言以其簡潔、高效和強(qiáng)大等特性成為嵌入式軟件編程的*語言,但是某些關(guān)鍵字,例如const、static、extern和volatile等,在不同的場合具有不同的含義,而且某些用法晦澀難懂,為此本文詳細(xì)介紹這些關(guān)鍵字的用法及其背后的原理。


1 const
    const限定的對象表示編譯器可以將它放在只讀存儲器中,也就意味著在對其進(jìn)行初始化之后就不能改變它的值。根據(jù)const使用的不同場合,大致可以分為三種情況,其一限定普通變量,其二限定函數(shù)參數(shù),其三限定指針變量。
    *和第二種情況最為簡單,語句①和語句②分別展示了它的用法。語句①定義了一個(gè)值為10的整型常量。語句②中的const表示在函數(shù)體中不能修改src指向的區(qū)域中的數(shù)據(jù),這與函數(shù)的拷貝功能相對應(yīng),只做它應(yīng)該做的事情而不應(yīng)該有其他副作用,編譯器可以利用這些信息進(jìn)行適當(dāng)?shù)膬?yōu)化。
    ①const int i=10;
    ②void*memcpy(void * dst,const void * src,size_t size);
    ③const int *ptr;
    ④int const *ptr;
    ⑤int*const ptr;
    ⑥int const*cons ptr;
    第3種情況最為復(fù)雜,雖然只是const位置不同,但是卻可能具有完全不同的意義。一般,一個(gè)聲明語句由聲明說明符(decl-specifier)和一系列聲明子(declarator)兩部分組成,而且聲明說明符中的符號可以以任何次序出現(xiàn)。理解聲明的*步是定位說明符和聲明子的邊界。這很容易:所有的說明符都是關(guān)鍵字或者類型名,因此說明符終止于*個(gè)不是以上類型之一的符號。例如,在語句③和④中*個(gè)既不是關(guān)鍵字也不是類型名的符號是“*”,即聲明說明符分別為const.int和int const,由于聲明說明符中的符號可以以任意次序出現(xiàn),因此語句③和④的含義是相同的。
    為了迅速弄清語句表達(dá)的含義,參考文獻(xiàn)[1]介紹了一種簡便的方法,其要點(diǎn)就是“逆序讀出定義”,如圖1所示。

2 static與extem
    static的含義隨著出現(xiàn)位置(全局變量還是局部變量)和修飾對象(變量還是函數(shù))的不同而有很大的差別。下面各條目中的模塊指的是一個(gè)源文件或者一個(gè)翻譯單元:

    ①位于函數(shù)體中的靜態(tài)變量在多次函數(shù)調(diào)用間會維持其值。
    ②位于模塊內(nèi)(但在函數(shù)體外)的靜態(tài)變量可以被模塊內(nèi)的所有函數(shù)訪問,但不能被模塊外其他函數(shù)訪問。也就是說,它是一個(gè)本地的全局變量。

③位于模塊內(nèi)的靜態(tài)函數(shù)只能被此模塊內(nèi)的其他函數(shù)調(diào)用。也就是說,這個(gè)函數(shù)的作用域?yàn)槁暶魉诘哪K。

   
    為了清楚地理解static的3種用法,必須首先了解C語言中每個(gè)標(biāo)識符都具有的作用域、鏈接和存儲持續(xù)期等特性的含義。在ISO C99標(biāo)準(zhǔn)中,其定義如下:
    ①對象的作用域指的是它僅在程序的某個(gè)區(qū)域中是可見的(即可以使用)。常見的作用域有文件作用域和塊作用域。
    ②對象的存儲持續(xù)期決定對象的生命周期,即在程序執(zhí)行某段區(qū)間中為對象保留存儲區(qū)。有兩種類型的存儲持續(xù)期:靜態(tài)的和自動的。靜態(tài)存儲持續(xù)期的對象的生命周期為程序執(zhí)行的全過程,它的值在程序啟動前僅初始化一次。
    ③鏈接指的是在不同作用域中聲明的或者同一個(gè)作用域中多次聲明的標(biāo)識符可以引用相同的對象或函數(shù)。有3種類型的鏈接:外部、內(nèi)部和無。在情況②和③中,static分別用來修飾全局變量glob-al和函數(shù)foo,改變它們的鏈接特性,使它們具有內(nèi)部鏈接。也就是說,只有在定義它們的翻譯單元或者文件內(nèi)才能使用它們,這對于創(chuàng)建模塊化的軟件非常重要。
    與static相反,extern修飾的對象或函數(shù)具有外部鏈接。對于那些暴露給外部使用的接口函數(shù)應(yīng)該使用ex-tern限定,那些非接口函數(shù),例如工具函數(shù)或與實(shí)現(xiàn)細(xì)節(jié)相關(guān)的函數(shù),則應(yīng)該顯式地使用static限定。這是因?yàn)槿绻瘮?shù)聲明不帶任何存儲類說明符,那么它具有外部鏈接就好像使用了extern一樣。
    在情況①中,static用來修飾局部變量local,將local的存儲持續(xù)期由自動的改變?yōu)殪o態(tài)的,這樣在foo函數(shù)的多次調(diào)用間會為其保留值。注意作用域、鏈接和存儲持續(xù)期特性之間是正交的。例如在情況①中,雖然變量local的存儲持續(xù)期變成靜態(tài)的,但是它的作用域仍然是塊作用域。


3 volatile
    volatile關(guān)鍵字用來聲明這樣的對象,它們的值可能由于程序控制之外的事件而被潛在改變。volatile強(qiáng)制編譯器不會對其所限定的對象進(jìn)行任何優(yōu)化,每次讀寫都必須訪問實(shí)際的存儲器而不能使用寄存器中的副本。在實(shí)踐中,它大量的用來描述一個(gè)對應(yīng)于內(nèi)存映射的輸入/輸出端口,例如飛利浦公司LPC21xx系列ARM處理器的向量地址寄存器定義為:
    #define VICVectAddr (*((volatile unsigned long*)0xFFFFF030))
    其次,中斷服務(wù)例程中使用的非自動變量或者多線程應(yīng)用程序中多個(gè)任務(wù)共享的變量也必須使用volatile進(jìn)行限定。例如在下面的示例中,如果沒有使用volatile限定g_Flag變量,編譯器看到在foo函數(shù)中并沒有修改g_Flag,可能只執(zhí)行一次g_Flag讀操作并將g_Flag的值緩存在寄存器中,以后每次g_Flag讀操作都使用寄存器中的緩存值而不進(jìn)行存儲器訪問,導(dǎo)致some_action函數(shù)永遠(yuǎn)無法執(zhí)行。

   


4 Dacked
    在嵌入式軟件編程中,經(jīng)常需要精確控

如果本頁不是您要找的課程,您也可以百度查找一下: