linux嵌入式課程 c語言之三大結構和除錯

2022-10-14 20:15:04 字數 3157 閱讀 6185

c語言之三大結構和除錯

1.順序結構

1.1c語言中的結構

c語言中有3種結構,順序結構、選擇結構、迴圈結構。順序結構就是按照**的編碼順序依次執行,**執行的過程中,如果沒有遇到判斷跳轉或者迴圈,預設的是順序執行。順序結構的特點就是執行完上一句則開始執行下一句。

選擇結構,又稱分支結構,細分有單分支,雙分支,多分支。單分支結構一般是指if結構,用於判斷。雙分支結構一般是指if...

else...,多分支結構一般多指的是switch結構,當然用if...else...

巢狀同樣也可以實現。迴圈結構就是在特定的條件下要重複執行的語句。有for結構、while結構、do...

while()結構。在c語言程式很大一部分**都是按照順序結構來執行的,在選擇結構或者迴圈結構中的**段也是按照順序結構執行的。譬如單分支選擇if(){},在{}內部是if的**段,在**段內部還是按照順序結構來執行的。

1.2編譯過程中的順序結構

(1)乙個c程式有多個.c檔案組成,編譯的時候多個.c檔案是獨立分開編譯的。每個c檔案編譯的時候,編譯器是按照從前到後的順序逐行進行編譯的。

(2)編譯器程式設計時的順序編譯會導致函式/變數必須先定義/宣告才能呼叫,這也是c語言中函式/變數宣告的**。

(3)鏈結過程中呢?應該說鏈結過程鏈結器實際上是在鏈結指令碼指導下完成的。所以鏈結時的.

o檔案的順序是由鏈結指令碼指定的。如果鏈結指令碼中明確指定了順序則會優先考慮這個規則按照這個指定的順序排布,如果鏈結指令碼中沒有指定具體的順序則鏈結器會自動的排布。

1.3思考:為什麼本質都是順序結構?

因為順序結構本質上符合cpu的設計原理,因為cpu就是以順序的方式去執行每條指令的,cpu是人設計的,所以cpu的設計符合人的思考原理。

2、程式除錯

2.1、程式除錯手段

軟體開發的過程中,乙個很重要的步驟就是軟體測試和排除錯誤。在乙個大型的程式中,程式設計錯誤(bug)是無可避免的。特別的,像c語言這種自由度很強的程式語言,開發者不可避免的會出現各種各樣的bug。

bug有時候對程式沒有多大的影響,有時候會返回錯誤的結果,但嚴重的bug甚至會造成程式跑飛,系統宕機。開發者找到這些錯誤並消滅它們,這樣的行為我們稱之為「除錯」(debug)。

當bug出現的時候,如果我們僅僅去檢視源**是很難找出太多的bug。這時候我們就要借助一些手段去找出這些bug,並消滅它們。程式除錯常見的手段:

單步除錯、硬體除錯、列印資訊、log檔案。

單步除錯:利用偵錯程式進行單步除錯(譬如ide中,jlink)適用於新手,最大的好處就是直觀,能夠幫助找到問題。缺點是限制性大、速度慢。

硬體除錯:利用產品的硬體如led、蜂鳴器等進行除錯。這種手段,比較合適裸機程式。

列印資訊:利用printf函式列印除錯,比較常用,作為程式設計師必須學會使用列印資訊除錯。好處是具有普遍性,幾乎在所有的情況下都能用。

log檔案:log檔案(日誌檔案)是系統執行過程中在特定時候會列印一些除錯資訊,日誌檔案記錄下來這些除錯資訊以供後續查詢追查問題。適合於系統級或者大型程式的除錯。

注意:(1)除錯資訊太少會導致資訊不夠找不到問題所在。

(2)除錯資訊太多會有大量的無用的資訊淹沒有用資訊,導致有用資訊無法看見,等於沒有。

2.2、除錯(debug)版本和發行(release)版本的區別

debug版本就是包含了除錯資訊輸出的版本,在程式測試過程中會發布debug 版本,這種版本的程式執行時會列印出來除錯資訊的log檔案,這些資訊可以輔助測試人員判斷程式的問題所在。debug版本的壞處是輸出除錯資訊占用了系統資源,拖慢了系統執行速度。因此debug版本的效能低於release版本。

release 版本就是最終的發布版本,相較於debug版本的功能**是一樣的,但是去掉了所有的除錯資訊。適合最終測試通過要發布的程式,因為去掉了除錯資訊所以程式的執行效率要更高。

debug和relase版本其實是一套源**,不同的是debug版本源**中是有很多的列印除錯資訊的語句。如何來控制生成debug和releease版本?靠條件編譯,靠乙個巨集。

#ifdef debug

#define dbg()printf()

#else

#define dbg()

#endif

debug巨集的實現原理:

如果我們要輸出debug版本則在條件編譯語句前加上#define debug即可,這樣程式中的除錯語句dbg()就會被替換成printf從而輸出;如果我們要輸出release版本則去掉#define debug,則dbg()就會被替換成空,則程式中所有的dbg()語句直接蒸發了,這樣的程式編譯時就會生成沒有任何除錯資訊的**。

2.3、debug巨集的使用方法

#ifdef debug

#define debug(fmt,args...)printf(fmt,##args)

#define debugx(level,fmt,args...)if(debug>=level) printf(fmt,##args);

#else

#define debug(fmt,args...)

#define debugx(level,fmt,args...)

#endif/*debug*/

上述**來自u-boot(標頭檔案),從前面的學習我們知道如果定義了debug這個巨集,則使用debug會輸出自定義的資訊,如果沒有定義,則什麼也不會輸出--不執行任何語句。我們再看乙個比較常用的資訊列印:

#define print_error(str)/

dowhile(0)

它不僅列印導致出錯的檔案、行號、函式,還列印這個出錯的原因。exit_failure 在系統中定義為1。當然,也可以使用exit(1),等等。

注意__file__等是c語言中的預定義巨集,就是說這個東西是個巨集定義,但是是c語言自己定義的。這些巨集具有特殊的含義,譬如__file__表示當前正在編譯的c檔案的檔名。這裡要注意一點,在linux中有一些約定的習慣,比如表示判斷的函式,返回非零表示成功,返回0表示失敗;表示操作性質的函式,返回0表示操作成功,返回非零表示操作失敗。

這裡我們同樣還要注意一點,輸出除錯資訊與出錯資訊是兩回事,除錯資訊是幫助我們更好地理解程式的執行、各個變數或程式的走向,這些資訊是可有可無的。但是出錯資訊卻不同,程式已經出錯了,沒理由也不能繼續執行下去了。比如給某一指標分配記憶體空間,如果分配失敗,我們必須返回或退出函式(有些面試題會考這個的)。

這些都是我們需要注意的。上面只是講了一種方法,方法沒有絕對的好與不好,找到合適自己的才是最好的。

嵌入式linux筆試總結

bin bash if語句 if expression then code block fiif expression then code block else code block fiif expression then code block else if expression then co...

嵌入式LINUX脫產班入學測試題 C語言

gec 嵌入式linux就業班入學測試題 姓名報名班次手機號碼 1.對於乙個正常執行的c程式,以下敘述中正確的是 a 程式的執行總是從main函式開始。b 程式的執行總是從程式的第乙個函式開始。c 程式的執行總是從最後乙個函式開始。d 程式的執行從哪個函式開始是不確定的。2.設有定義 int k 0...

嵌入式C語言迴圈結構程式設計

實驗五迴圈結構程式設計 實驗內容 熟練掌握while do while和for三種迴圈語句的應用。實驗目的 通過實驗,熟練掌握while do while和for三種迴圈語句,為以後開發打下基礎。實驗平台 pc機 實驗步驟 編寫程式,完成下列題目 1 求5!2 求和s 1 2 3 3 求和s 1 3...