當前位置:首頁 > 嵌入式 > 嵌入式硬件
[導讀]引 言計算機編程語言的關鍵字就好比是它的靈魂,只有深入理解了它們的含義才能編寫出優(yōu)秀的代碼。C語言以其簡潔、高效和強大等特性成為嵌入式軟件編程的首選語言,但是某些

引 言

計算機編程語言的關鍵字就好比是它的靈魂,只有深入理解了它們的含義才能編寫出優(yōu)秀的代碼。C語言以其簡潔、高效和強大等特性成為嵌入式軟件編程的首選語言,但是某些關鍵字,例如const、static、extern和volatile等,在不同的場合具有不同的含義,而且某些用法晦澀難懂,為此本文詳細介紹這些關鍵字的用法及其背后的原理。

1 const

const限定的對象表示編譯器可以將它放在只讀存儲器中,也就意味著在對其進行初始化之后就不能改變它的值。根據const使用的不同場合,大致可以分為三種情況,其一限定普通變量,其二限定函數參數,其三限定指針變量。

第一和第二種情況最為簡單,語句①和語句②分別展示了它的用法。語句①定義了一個值為10的整型常量。語句②中的const表示在函數體中不能修改src 指向的區(qū)域中的數據,這與函數的拷貝功能相對應,只做它應該做的事情而不應該有其他副作用,編譯器可以利用這些信息進行適當的優(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種情況最為復雜,雖然只是const位置不同,但是卻可能具有完全不同的意義。一般,一個聲明語句由聲明說明符(decl-specifier)和一系列聲明子(declarator)兩部分組成,而且聲明說明符中的符號可以以任何次序出現。理解聲明的第一步是定位說明符和聲明子的邊界。這很容易:所有的說明符都是關鍵字或者類型名,因此說明符終止于第一個不是以上類型之一的符號。例如,在語句③和④中第一個既不是關鍵字也不是類型名的符號是“*”,即聲明說明符分別為const.int和int const,由于聲明說明符中的符號可以以任意次序出現,因此語句③和④的含義是相同的。

為了迅速弄清語句表達的含義,參考文獻[1]介紹了一種簡便的方法,其要點就是“逆序讀出定義”,如圖1所示。

 

 

2 static與extem

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

①位于函數體中的靜態(tài)變量在多次函數調用間會維持其值。

②位于模塊內(但在函數體外)的靜態(tài)變量可以被模塊內的所有函數訪問,但不能被模塊外其他函數訪問。也就是說,它是一個本地的全局變量。

③位于模塊內的靜態(tài)函數只能被此模塊內的其他函數調用。也就是說,這個函數的作用域為聲明所在的模塊。

 

為了清楚地理解static的3種用法,必須首先了解C語言中每個標識符都具有的作用域、鏈接和存儲持續(xù)期等特性的含義。在ISO C99標準中,其定義如下:

①對象的作用域指的是它僅在程序的某個區(qū)域中是可見的(即可以使用)。常見的作用域有文件作用域和塊作用域。

②對象的存儲持續(xù)期決定對象的生命周期,即在程序執(zhí)行某段區(qū)間中為對象保留存儲區(qū)。有兩種類型的存儲持續(xù)期:靜態(tài)的和自動的。靜態(tài)存儲持續(xù)期的對象的生命周期為程序執(zhí)行的全過程,它的值在程序啟動前僅初始化一次。

③鏈接指的是在不同作用域中聲明的或者同一個作用域中多次聲明的標識符可以引用相同的對象或函數。有3種類型的鏈接:外部、內部和無。在情況②和③ 中,static分別用來修飾全局變量glob-al和函數foo,改變它們的鏈接特性,使它們具有內部鏈接。也就是說,只有在定義它們的翻譯單元或者文件內才能使用它們,這對于創(chuàng)建模塊化的軟件非常重要。

與static相反,extern修飾的對象或函數具有外部鏈接。對于那些暴露給外部使用的接口函數應該使用ex-tern限定,那些非接口函數,例如工具函數或與實現細節(jié)相關的函數,則應該顯式地使用static限定。這是因為如果函數聲明不帶任何存儲類說明符,那么它具有外部鏈接就好像使用了 extern一樣。

在情況①中,static用來修飾局部變量local,將local的存儲持續(xù)期由自動的改變?yōu)殪o態(tài)的,這樣在foo函數的多次調用間會為其保留值。注意作用域、鏈接和存儲持續(xù)期特性之間是正交的。例如在情況①中,雖然變量local的存儲持續(xù)期變成靜態(tài)的,但是它的作用域仍然是塊作用域。

3 volatile

volatile關鍵字用來聲明這樣的對象,它們的值可能由于程序控制之外的事件而被潛在改變。volatile強制編譯器不會對其所限定的對象進行任何優(yōu)化,每次讀寫都必須訪問實際的存儲器而不能使用寄存器中的副本。在實踐中,它大量的用來描述一個對應于內存映射的輸入/輸出端口,例如飛利浦公司 LPC21xx系列ARM處理器的向量地址寄存器定義為:

#define VICVectAddr (*((volatile unsigned long*)0xFFFFF030))

其次,中斷服務例程中使用的非自動變量或者多線程應用程序中多個任務共享的變量也必須使用volatile進行限定。例如在下面的示例中,如果沒有使用 volatile限定g_Flag變量,編譯器看到在foo函數中并沒有修改g_Flag,可能只執(zhí)行一次g_Flag讀操作并將g_Flag的值緩存在寄存器中,以后每次g_Flag讀操作都使用寄存器中的緩存值而不進行存儲器訪問,導致some_action函數永遠無法執(zhí)行。

 

[!--empirenews.page--]

4 Dacked

嵌入式軟件編程中,經常需要精確控制結構體在內存中的布局和訪問非自然對齊的數據,但是C語言標準中并沒有統(tǒng)一的規(guī)定而是留給編譯器廠商自行處理。在 ARM C編譯器中,使用__packed關鍵字將任何類型的對齊設置為1字節(jié)。在實踐中,__packed主要有兩個功能:其一,當它修飾指針時,表示此指針指向的地址是非自然對齊的,編譯器會生成特殊的代碼以確保獲得正確的結果;其二,當它修飾結構體、聯合或它們中的域時,可以用來創(chuàng)建沒有填充的結構。

與其他RISC架構一樣,ARM處理器能夠高效地訪問對齊的數據,即字地址的末尾兩位為零,半字地址的最后一位為零,也稱這樣的數據位于它的自然大小邊界或者是自然對齊的。ARM編譯器希望普通的“C”指針指向一個4字節(jié)對齊內存地址,這樣它可以在代碼中使用LDR/STR指令一次操作4個字節(jié),否則只能使用LDRB/LDRH等字節(jié)/半字操作指令。相反如果指針指向一個非自然對齊的地址,例如如果一個整型指針指向地址0x8006,當然希望裝載地址 0xS006-0xS007-0x8008-0xS009處的數據,但是實際上ARM會對非自然對齊的地址進行轉換而從裝載地址 0xS004-0xS005-0x8006-0xS007處的數據。在下面的示例中(測試環(huán)境為uVision3),首先定義了一個大小為16字節(jié)的整型數組,依次初始化為0,1,2,…,15。由于array是一個整型數組,編譯器會確保它是4字節(jié)對齊的,即指針pc指向一個4字節(jié)對齊的地址。運行程序后,可以看到如果對pc指針不加__packed標記進行修飾,將得到一個奇怪的0x01000302;而在添加了__packed關鍵字之后,就得到了正確的結果。也就是說,如果要訪問非自然對齊的數據,必須使用__packed關鍵字顯式地標記出來。

 

ARM編譯器總是保證程序中的變量、結構體或聯合中的域分配到自然對齊的地址。這意味著編譯器經常需要在各個域之間插入填充,以確保每個域的自然對齊。通常來說,程序員可以對這些填充視而不見,但是也有例外,例如為了節(jié)省結構體占用的空間,可以利用__packed去除填充。在了解了編譯器的填充行為之后,可以通過調整域的順序來減小結構體占用的空間。例如雖然結構體s1和s2的域相同,但是sizeof(s1)等于16,而sizeof(s2)等于 12。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據媒體報道,騰訊和網易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數據產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數據產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數字經濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯合牽頭組建的NVI技術創(chuàng)新聯盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現場 NVI技術創(chuàng)新聯...

關鍵字: VI 傳輸協議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉