嵌入式C語言教案_第1頁
嵌入式C語言教案_第2頁
嵌入式C語言教案_第3頁
嵌入式C語言教案_第4頁
嵌入式C語言教案_第5頁
已閱讀5頁,還剩154頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

1、一、linuxc環(huán)境說明61.c語言簡介62.嵌入式c與pc機c63.linux下c語言編程的環(huán)境概述6a.編輯器:vi6b.編譯連接器:gcc6c.調(diào)試器:gdb11d.項目管理器:makefile14二、編碼規(guī)范191.基本原則192.文件布局193.基本格式214.對齊215.空行空格226.注釋規(guī)則227.其它22三、第一個程序25四、數(shù)據(jù)類型261.常量與變量261)常量262)變量273)const定義的常量272.整型變量281)分類:282)占內(nèi)存:283)類型自動轉(zhuǎn)換294)const定義的常量303.實型變量304.字符變量305.字符串常量311)字符串常量的概念和字符串

2、長度312)字符串的存儲31五、運算符321)算術(shù)運算符:+,-,*,/,%322)關(guān)系運算符:,=,=,=,!=323)邏輯運算符:&, |324)自增運算符:+,-325)位運算:&,|,326)賦值運算符:=,+=,-=,/=,%=337)條件運算符:?:338)逗號運算符:返回最右邊表達式的值。339)sizeof運算符33六、順序程序結(jié)構(gòu)設計361.格式化輸出printf()函數(shù)362.格式化輸入scanf()函數(shù)36七、選擇結(jié)構(gòu)程序設計381.關(guān)系運算符及其表達式381)關(guān)系運算符382)邏輯運算符383)邏輯運算規(guī)則382.if語句393.條件運算符404.switch405.g

3、oto語句41八、循環(huán)結(jié)構(gòu)程序設計451.for語句452.while語句463.do-while語句474.break語句與continue語句48九、數(shù)組551.定義552.一維數(shù)組的初始化551)格式:552)注意:553)使用:563.二維數(shù)組的初始化561)初始化格式:562)引用格式:563)地址級別:574) 地址類型584.字符數(shù)組581)定義:582)一些字符操作的函數(shù)593)字符串:593)一些字符串的操作函數(shù)60十、函數(shù)681.函數(shù)的聲明682.函數(shù)的定義691)無參函數(shù)的一般形式:692)有參函數(shù)的一般形式693.函數(shù)的返回值與函數(shù)類型70a.函數(shù)返回值與return語

4、句70b.函數(shù)類型70c.說明704.函數(shù)中形參與定義的變量715.函數(shù)的嵌套調(diào)用和遞歸調(diào)用71a)函數(shù)的嵌套調(diào)用71b)函數(shù)的遞歸調(diào)用716.函數(shù)中的變量72a)變量的作用域72b)變量的生存期72c)局部變量72d)全局變量73e)自動變量73f)靜態(tài)變量73g)寄存器變量74h)volatile變量74i)變量的初始化74j)棧幀結(jié)構(gòu)與程序內(nèi)存空間74十一、編譯欲處理821. 宏定義82a)無參數(shù)宏定義82b)帶參數(shù)的宏定義82c)宏定義的優(yōu)點822.預編譯條件編譯83a)#ifdef #endif和#ifndef #endif命令83b)#if #endif833.防止頭文件xxx.h

5、被重復包含844.#與#在宏定義中的使用84十二、指針871.指針概念872.指針的運算893.數(shù)組和指針904.指針數(shù)組與數(shù)組指針90a)指針數(shù)組90b)數(shù)組指針925.野指針936.指針的步長937.定義字符串常量948.內(nèi)存的動態(tài)分配與釋放94a)malloc()94b)free()94c)動態(tài)分配內(nèi)存的特點959.常量修飾符const95a)函數(shù)體內(nèi)修飾局部變量95b)在函數(shù)聲明時修飾參數(shù)9510.二級指針9611.函數(shù)指針97a)定義97b)賦值97c)調(diào)用97d)與指針函數(shù)的區(qū)別97e)函數(shù)指針數(shù)組的定義9712.理解復雜的聲明98十三、結(jié)構(gòu)體1141.結(jié)構(gòu)體變量的定義1142.結(jié)

6、構(gòu)體變量的成員引用規(guī)則和初始化1153.結(jié)構(gòu)體數(shù)組1154.共用體1165.枚舉類型117a)什么事枚舉類型117b)枚舉類型的定義117c)枚舉變量的定義117d)枚舉類型是有序的類型1176.結(jié)構(gòu)體和共用體在實際工作中的巨大作用118十四、位運算1371.數(shù)值源碼表示1372.數(shù)值的反碼表示1373.數(shù)值的補碼表示1374.位運算138a.按位與&138b.按位或|138c.按位異或138d.按位取反139e按位左移139g.實現(xiàn)&、|、運算主要用途的方法1395.位段結(jié)構(gòu)140a.定義140b.位段數(shù)據(jù)的引用:141十五、文件1451.文件的分類1452.文件類型file1453.文件的

7、打開與關(guān)閉145a.打開文件fopen()函數(shù)145b.關(guān)閉文件fclose()1474.讀/寫文件中的一個字符147a.讀一個字符fgetc()147b.寫一個字符fputc()147c.eof148d.feof()1485.讀/寫文件中的一個字符串148a.讀一個字符串fgets()148b.寫一個字符串fputs()1486.讀/寫一個數(shù)據(jù)塊149a.讀一個數(shù)據(jù)塊fread()149b.寫一個數(shù)據(jù)塊fwrite()1497.文件定位150a.位置指針重定位fseek()150b.獲得位置指針的位置ftell()150c.文件指針定位到文件流的開始rewind1508.格式化輸出函數(shù)150

8、a.printf()函數(shù)150b.格式化字符串輸出到文件fprintf()150c.格式化字符串輸出到buffer內(nèi)sprintf()150一、linuxc環(huán)境說明1.c語言簡介最早是由貝爾實驗室的丹尼斯利奇(dennis ritchie)為了unix的輔助開發(fā)而編寫的。他的硬件無關(guān)性和可移植性,使c語言逐步成為世界上使用最廣泛的計算機語言。1987年,美國國家標準協(xié)會(ansi)制定了c語言的標準,稱為ansi c,目前流行的c語言編譯系統(tǒng)都是以它為基礎的。特點:是“中級語言”,把高級語言的基本結(jié)構(gòu)和語句與低級語言的實用結(jié)合起來,可以像匯編一樣對位、字節(jié)和地址進行操作,而這三者是計算機的最基

9、本單元結(jié)構(gòu)化語言,層次清晰,便于使用、維護以及調(diào)試c語言功能齊全、可移植性強。2.嵌入式c與pc機c(正確性、效率、移植)嵌入式的c語言與pc機的c語言編寫程序絕對不能簡單等同,pc機資源十分豐富,運算能里強大,因此程序員在寫pc機的應用程序時幾乎不用關(guān)心編譯后的可執(zhí)行在運行過程中需要占用多少系統(tǒng)資源,也基本不用擔心運行效率有多高。嵌入式c在程序編寫和編譯時都要考慮運行的速度和效率。在程序設計時都要考慮。嵌入式有很多時候會受到硬件的限制,同時,在編寫嵌入式的程序時,對于實時性要求可能會很高,同時,由于嵌入式系統(tǒng)一般內(nèi)存,cpu等資源有限,編程時需要特別考慮系統(tǒng)的高效性。為什么不選擇匯編?-移植

10、性3.linux下c語言編程的環(huán)境概述a. 編輯器:vib. 編譯連接器:gccgcc是gnu推出的功能強大、性能優(yōu)越的多平臺編譯器。編譯是指源代碼轉(zhuǎn)化生成可執(zhí)行代碼的過程。編譯過程十分復雜包括:詞法、語法和語義的分析、中間代碼的生成和優(yōu)化、符號表的管理和出錯處理等。gnu cc(簡稱為gcc)是gnu項目中符合ansi c標準的編譯系統(tǒng),能編譯c、c+、objiecc、java、fortran、pascal、ada等多種語言,并且是個交叉平臺編譯器,適合于嵌入式領域的開發(fā)編譯。gcc所支持的后綴名解釋gcc編譯流程:l 預處理(pre-processing)調(diào)用cpp命令。對包含的頭文件(#

11、include)和宏定義(#define、#ifdef等)進行處理??梢允褂胓cc的選項-e進行查看,該選項的作用是讓gcc在預處理結(jié)束后停止編譯過程。后綴為“.i”的文件為已經(jīng)預處理過的c程序。gcc -e hello.c -o hello,il 編譯(compiling)調(diào)用cc1命令。首先檢查代碼的完整性、是否有語法錯誤等,以確定代碼實際要做的工作,在檢查無誤后,gcc把代碼翻譯成匯編語言。可用-s選項進行查看,該選項只進行編譯不進行匯編。后綴為“.s”的文件為已經(jīng)編譯過的匯編代碼。gcc -s hello.i -o hello.sl 匯編(assembling)as命令。把編譯階段生成

12、的“.s”文件轉(zhuǎn)成目標文件,讀者在此選項“-c”就可以看到匯編代碼已轉(zhuǎn)化為“.o”的二進制目標代碼了。gcc -c hello.s -o hello.ol 鏈接(linking)ld命令。所有的目標文件被安排在可執(zhí)行程序中的恰當位置,同時該程序所調(diào)用的庫函數(shù)也從各自所在的庫目錄中連到合適的位置。關(guān)于函數(shù)庫:如中的printf函數(shù)的實現(xiàn),它被定義在stdio.h中,但它的實現(xiàn)在哪?系統(tǒng)把這些函數(shù)的實現(xiàn)都放在名為libc.so.6的庫文件中;沒有特殊指定的前提下,gcc會到系統(tǒng)默認的搜索路徑“/usr/lib”下進行查找,也就是說鏈接到libc.so.6中去了,這樣就可以調(diào)用printf這樣的函數(shù)

13、了,這也正是鏈接的作用了。函數(shù)庫有靜態(tài)庫和動態(tài)庫兩種: 什么是庫:本質(zhì)上來說是一種可執(zhí)行代碼的二進制形式,可被os載入內(nèi)存執(zhí)行。 庫的意義:是別人編好的,成熟的,可以復用的代碼,可以使用但必須遵循其接口的規(guī)范?,F(xiàn)實中我們用到的每個程序都要依賴很多基礎的底層庫,不可能每個人的代碼都是從零開始寫的;不同的應用程序如果調(diào)用相同的庫,那么內(nèi)存中只需要一份共享庫。 庫文件的命名和規(guī)范:一般放在/usr/lib中。靜態(tài)庫的名字一般為libxxxx.a,其中xxxx是該lib的名稱動態(tài)庫的名字一般為libxxxx.so.major.minor,xxxx是該lib的名稱,major是主版本號, minor是副

14、版本號 如何定位到共享庫:系統(tǒng)加載可執(zhí)行代碼時,獲取所依賴的庫的名字、絕對路徑。 靜態(tài)庫是指編譯鏈接時,將庫文件的代碼全部加入可執(zhí)行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了,其后綴名通常為“.a”。靜態(tài)庫是一系列的目標文件(.o文件)的歸檔文件,如果在編譯某個程序時鏈接靜態(tài)庫,則鏈接器將會搜索靜態(tài)庫,從中提取它所需要的目標文件并直接復制到該程序的可執(zhí)行二進制文件(elf格式文件)之中。動態(tài)庫與之相反,在編譯鏈接時并沒有將庫文件的代碼加入可執(zhí)行文件中,而是在程序執(zhí)行時加載庫,這樣就可以節(jié)省系統(tǒng)的開銷。一般動態(tài)庫的后綴名為“.so”,如前面所述的libc.so.6就是動態(tài)庫。g

15、cc在編譯時默認使用動態(tài)庫。完成了鏈接之后,gcc就可以生成可執(zhí)行文件。動態(tài)庫(文件名格式為libname.so.主版本號.次版本號.發(fā)行號)在程序編譯時并不會被鏈接到目標代碼中,而是在程序運行時才被載入。windows稱為動態(tài)鏈接庫(dynamic link library,dll)。linux稱為共享庫技術(shù)(shared library)。隱式鏈接:在編譯鏈接階段完成,由編譯系統(tǒng)根據(jù)動態(tài)庫的頭文件和庫文件進行編譯鏈接,從而確定待調(diào)用的函數(shù)原行和地址。顯式鏈接:利用api函數(shù)實現(xiàn)加載和卸載共享庫,獲取帶調(diào)用函數(shù)地址,錯誤信息等功能。靜態(tài)庫的創(chuàng)建和使用:使用歸檔工具ar將一些目標文件集成在一起

16、。如:hello.h hello.c和main.c:1將hello.c編譯成.o文件,gcc -c hello.c -o hello.o2由.o文件創(chuàng)建靜態(tài)庫,必須是lib開頭,后綴為.aar crv libmyhello.a hello.o3在程序中使用靜態(tài)庫:只需要在使用這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標文件時指明靜態(tài)庫名,gcc將會從靜態(tài)庫中將公用函數(shù)連接到目標文件中:gcc main.c -l. -lmyhello -o hello 。我們可以刪除靜態(tài)庫文件,試試公用函數(shù)hello程序看看結(jié)果如何。其中,選項“-l dir”與“-i dir”類

17、似,能夠在庫文件的搜索路徑列表中添加dir目錄,而“-lname”選項指示編譯時鏈接到庫文件libname.a或者libname.so。動態(tài)庫的創(chuàng)建和使用:首先也是編譯一個.o文件gcc shared fpic hello.o o libmyhello.so編譯主程序,它會鏈接到剛生成的動態(tài)庫hello.so:gcc main.c -l. -lmyhello -o hello在運行可執(zhí)行程序之前,需要注冊動態(tài)庫的路徑名??梢孕薷?etc/ld.so.conf文件,或者修改ld_library_path環(huán)境變量,或者將庫文件直接復制到/lib或者/usr/lib目錄下(這兩個目錄為系統(tǒng)默認的庫路

18、徑名)運行程序如何找到自己的庫1.#cp libhello.so /lib2.#vim /etc/ld.so.conf 加入庫所在路徑 #ldconfig3.#export ld_library_path=庫所在路徑:$ld_library_path如果出現(xiàn)權(quán)限不允許,這是由selinux造成的,解決:chcon t texrel_shlib_t /usr/lib/libhello.so動態(tài)庫只有當使用它的程序執(zhí)行時才被鏈接使用,而不是將需要的部分直接編譯入可執(zhí)行文件中,并且一個動態(tài)庫可以被多個程序使用故可稱為共享庫,而靜態(tài)庫將會整合到程序中,因此在程序執(zhí)行時不用加載靜態(tài)庫??芍烘溄拥届o態(tài)庫

19、會使用戶的程序臃腫,并且難以升級,但較易部署,而鏈接到動態(tài)庫會使程序輕便,并且易于升級,但會難以部署。gcc常用選項列表gcc庫選項列表gcc警告和出錯選項列表gcc可以對代碼進行優(yōu)化,它通過編譯選項“-on”來控制優(yōu)化代碼的生成,其中n是一個代表優(yōu)化級別的整數(shù)。-o1主要進行線程跳轉(zhuǎn)(thread jump)和延遲退棧(deferred stack pops)優(yōu)化。-o2除了“-o1”的優(yōu)化外,同時還要進行一些額外的調(diào)整工作,如處理器指令調(diào)度等。-o3則還包括循環(huán)展開和其他一些與處理器特性相關(guān)的優(yōu)化工作。優(yōu)化會為調(diào)試帶來大量的麻煩,所以盡量不要進行優(yōu)化,只有當程序最終發(fā)行的時候才考慮對其優(yōu)化

20、。c. 調(diào)試器:gdb方便程序員調(diào)試程序而用的,gdb可以方便地設置斷點、單步跟蹤等。比如windows平臺下的一些調(diào)試工具,vs自帶的設置斷點、單步調(diào)試等。gdb調(diào)試器是gnu開發(fā)組織并發(fā)布的unix/linux下的程序調(diào)試工具。首先使用gcc對hello.c進行變異,一定要加上“-g”,這樣編譯出的可執(zhí)行代碼中才包含調(diào)試信息,否則之后gdb無法載入可執(zhí)行文件。注意gdb調(diào)試的是可執(zhí)行文件而非源代碼。gdb hello1) 查看文件:鍵入“l(fā)”(list)就可以查看載入的文件2) 設置斷點:在“b”(breakpoint)后面加入對應的行號即可(是對應行之前暫停,并沒有運行當行)3) 查看斷

21、點情況:鍵入“info b”來查看設置斷點情況,gdb是可以設置多個斷點的。用戶可以在斷點處鍵入“bt”(backrace)就可以查到調(diào)用函數(shù)(堆棧)的情況。4) 運行代碼:鍵入“r”(run),或者在r后面加上行號,在指定行開始運行。5) 查看變量值:鍵入“p”加上變量值即可。6) 單步運行:使用“n”(next)或“s”(step),區(qū)別在于:若有函數(shù)調(diào)用的時候,“s”會進入該函數(shù)而“n”不會進入該函數(shù)。7) 恢復程序運行:在斷點處,使用命令“c”就可以回復程序的正常運行了。8) 命令查找?guī)椭篽elp,help callgdb工作環(huán)境相關(guān)命令gdb設置斷點與恢復相關(guān)命令兩種設置斷點的方法

22、:函數(shù)斷點:只需把函數(shù)名列在命令“b”后條件斷點:b加上行數(shù)或者if表達式gdb源碼查看相關(guān)gdb查看運行數(shù)據(jù)相關(guān)gdb還可以修改運行參數(shù),并使該變量按照此參數(shù)值繼續(xù)運行。設置方法:鍵入“set 變量=設定值”。gdb使用的注意的地方:gcc編譯選項一定要有-g;只有在“運行”或“暫停”狀態(tài)時才能查看變量值;設置斷點后程序在指定行之前停止。d. 項目管理器:makefile類似于windows的vc里的“工程”,是控制編譯或者重復編譯軟件的工具。自動管理軟件編譯的內(nèi)容、方式和時機,使程序員能把精力集中在代碼的編寫上而不是在源代碼的組織上。用于管理較多的文件,人們希望有一個工程管理器能夠自動識別

23、更新了的文件代碼,而不需要重復輸入冗長的命令行,這樣makefile工具就誕生了。makefile是make讀入的唯一配置文件,makefile中通常包括:1. 需要由make工具創(chuàng)建的目標體(target),通常是目標文件或可執(zhí)行文件;2. 要創(chuàng)建的目標所依賴的文件3. 創(chuàng)建每個目標時需要運行的命令,這一行必須以制表符(tab)開頭格式為:target:dependency_filescommand /* 必須tab開頭 */makefile變量在makefile中變量定義有兩種方式:一種是遞歸展開方式,另一種是簡單方式。遞歸展開方式,是再引用時進行替換,并且將內(nèi)嵌的變量全部展開,但若是這樣

24、的語句:cflags = $(cflags) -o就會導致無窮循環(huán)。簡單擴展型變量的值在定義出展開,并只展開一次,不包含任何對其他變量的引用,從而消除了變量的嵌套引用。遞歸展開方式:var=var。簡單擴展方式:var:=varmake中的變量使用均使用格式:$(var)。例子如下:makefile中的變量分為用戶自定義變量、預定義變量、自動變量及環(huán)境變量。預定義變量包含了常見編譯器、匯編器的名稱及其編譯選項。makefile中常見的預定定義變量注意:需要“cc=gcc”明確列出來自動變量通??梢源砭幾g語句中出現(xiàn)¥目標文件和依賴文件等,并且具有本地含義(即下一語句中出現(xiàn)的相同變量代表的是下一

25、語句的目標文件和依賴文件)。makefile中常見的自動變量makefile中還可以使用的環(huán)境變量,使用變量的方法相對比較簡單,make在啟動時會自動讀取系統(tǒng)當前已經(jīng)定義了的環(huán)境變量,并且會創(chuàng)建與之具有相同名稱和數(shù)值的變量。但是,如果用戶在makefile中定義了相同名稱的變量,那么用戶自定義變量將會覆蓋同名的環(huán)境變量。makefile規(guī)則它包括了目標體、依賴文件及其之間的命名語句。make還定義了隱式規(guī)則和模式規(guī)則:1)隱式規(guī)則:makefile中常見隱式規(guī)則目錄例如,我們有下面的一個makefile:foo : foo.o bar.occ o foo foo.o bar.o $(cflag

26、s) $(ldflags)我們可以注意到,這個makefile中并沒有寫下如何生成foo.o和bar.o這兩目標的規(guī)則和命令。因為make的“隱含規(guī)則”功能會自動為我們自動去推導這兩個目標的依賴目標和生成命令。make會在自己的“隱含規(guī)則”庫中尋找可以用的規(guī)則,如果找到,那么就會使用。如果找不到,那么就會報錯。在上面的那個例子中,make調(diào)用的隱含規(guī)則是,把.o的目標的依賴文件置成.c,并使用c的編譯命令“cc c $(cflags) .c”來生成.o的目標。也就是說,我們完全沒有必要寫下下面的兩條規(guī)則:foo.o : foo.ccc c foo.c $(cflags)bar.o : bar.

27、ccc c bar.c $(cflags)因為,這已經(jīng)是“約定”好了的事了,make和我們約定好了用c編譯器“cc”生成.o文件的規(guī)則,這就是隱含規(guī)則。再如本章例子中:2)模式規(guī)則是用來定義相同處理規(guī)則的多個文件的,模式規(guī)則相對于隱式規(guī)則還能引入用戶自定義變量,為多個文件建立相同的規(guī)則,從而簡化makefile的編寫。格式類似于普通規(guī)則,這個規(guī)則的相關(guān)文件前必須用“%”標明,使用模式規(guī)則修改后的makefile的編寫如下:make管理器的使用只需要在make命令的后面鍵入目標名即可建立指定的目標,如果直接運行make,則建立makefile中的第一個目標。此外,make還有豐富的命令行選項,可

28、以完成各種不同功能。make的命令行選項all:darraydarray:main.o darray.ogcc o $ $%.o:%.cgcc c $ -o $clean:rm rf *.o darray.phony:clean all darray二、編碼規(guī)范1.基本原則a. 首先是為人編寫程序,其次才是計算機這是軟件開發(fā)的基本要點,軟件的生命周期貫穿產(chǎn)品的開發(fā)、測試、生產(chǎn)、用戶使用、版本升級和后期維護等長期過程,只有易讀、易維護的軟件代碼才具有生命力。模塊周期(三分之一寫報告,三分之一寫程序,三分之一調(diào)試);注意健壯性(即容錯能力)b. 保持代碼的簡明清晰,避免過分的編程技巧簡單是最美。保

29、持代碼的簡單化是軟件工程化的基本要求。不要過分追求技巧,否則會降低程序的可讀性。面試時會用到技巧,自己編程時不要用技巧如 a+=b;c. 所有的代碼盡量遵循ansi c標準一個函數(shù)定義類型,則返回值默認是什么類型d. 編程時首先達到正確性,其次考慮效率編程首先考慮的是滿足正確性、健壯性、可維護性、可移植性等質(zhì)量因素,最后才考慮程序的效率和資源占用。e. 避免或少用全局變量過多地使用全局變量,會導致模塊間的緊耦合,違反模塊化的要求。apue中的多進程、多線程通信中。f. 盡量避免使用goto語句(就當c語言中沒有)g. 盡可能重用、修正老的代碼h. 盡量減少同樣的錯誤出現(xiàn)的次數(shù)2.文件布局目的是

30、顯示出程序良好的邏輯結(jié)構(gòu),提高程序的準確性、連續(xù)性、可讀性、可維護性。更重要的是,統(tǒng)一的程序布局和編程風格,有助于提高整個項目的開發(fā)質(zhì)量,提高開發(fā)效率,降低開發(fā)成本。同時,對于普通程序員來說,養(yǎng)成良好的編程習慣有助于提高自己的編程水平,提高編程效率。因此,統(tǒng)一的、良好的程序布局和編程風格不僅僅是個人主觀美學上的或是形式上的問題,而且會涉及到產(chǎn)品質(zhì)量,涉及到個人編程能力的提高,必須引起大家重視。a. 遵循統(tǒng)一的布局順序來書寫頭文件#ifndef 文件名_h(全大寫)#define 文件名_h其它條件編譯選項#include(依次為標準庫頭文件、非標準庫頭文件)常量定義全局宏全局數(shù)據(jù)類型類定義模板

31、(template)(包括c+中的類模板和函數(shù)模板)全局函數(shù)原型#endifb. 遵循統(tǒng)一的布局順序來書寫實現(xiàn)文件文件頭(參見第三章“注釋”)#include(依次為標準庫頭文件、非標準庫頭文件)常量定義文件內(nèi)部使用的宏文件內(nèi)部使用的數(shù)據(jù)類型全局變量本地變量(即靜態(tài)全局變量)局部函數(shù)原型類的實現(xiàn)全局函數(shù)局部函數(shù)c. 使用注釋塊分離上面定義的節(jié)d. 頭文件必須要避免重復包含e. 包含標準庫頭文件用尖括號 ,包含非標準庫頭文件用雙引號 “ ”f. 遵循統(tǒng)一的順序書寫類的定義及實現(xiàn)類的定義(在定義文件中)按如下順序書寫:公有屬性公有函數(shù)保護屬性保護函數(shù)私有屬性私有函數(shù)類的實現(xiàn)(在實現(xiàn)文件中)按如下順

32、序書寫:構(gòu)造函數(shù)析構(gòu)函數(shù)公有函數(shù)保護函數(shù)私有函數(shù)3.基本格式a. 程序中一行的代碼和注釋不能超過80列b. if、else、else if、for、while、do等語句自占一行,執(zhí)行語句不得緊跟其后。不論執(zhí)行語句有多少都要加 4.對齊a. 程序的分界符和應獨占一行并且位于同一列,同時與引用它們的語句左對齊。 之內(nèi)的代碼塊使用縮進規(guī)則對齊do while語句和結(jié)構(gòu)的類型化時可以例外,while條件和結(jié)構(gòu)名可與 在同一行。b. 結(jié)構(gòu)型的數(shù)組、多維的數(shù)組如果在定義時初始化,按照數(shù)組的矩陣結(jié)構(gòu)分行書寫c. 相關(guān)的賦值語句等號對齊tpdbres.whead= 0;tpdbres.wtail= wmax

33、numofpdb - 1;tpdbres.wfree= wmaxnumofpdb;tpdbres.waddress= wpdbaddr;tpdbres.wsize= wpdbsize;d. 在switch語句中,每一個case分支和default要用 括起來, 中的內(nèi)容需要縮進(建議)5.空行空格a. 不同邏輯程序塊之間要使用空行分隔b. 一元操作符如“!”、“”、“+”、“-”、“*”、“&”(地址運算符)等前后不加空格?!啊?、“.”、“-”這類操作符前后不加空格。c. 多元運算符和它們的操作數(shù)之間至少需要一個空格d. 關(guān)鍵字(如for while if等)之后要留空格e. 函數(shù)名之后不要留

34、空格f. (向后緊跟,)、,、;向前緊跟,緊跟處不留空格。,之后要留空格。;不是行結(jié)束符號時其后要留空格g. 注釋符與注釋內(nèi)容之間要用一個空格進行分隔h. 長表達式(超過80列)要在低優(yōu)先級操作符處拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要進行適當?shù)目s進,使排版整齊i. 函數(shù)聲明時,類型與名稱不允許分行書寫6.注釋規(guī)則a. 文件頭部必須進行注釋,包括:.h文件、.c文件、.cpp文件、.inc文件、.def文件、編譯說明文件.cfg等b. 函數(shù)頭部應進行注釋,列出:函數(shù)的目的/功能、輸入?yún)?shù)、輸出參數(shù)、返回值、訪問和修改的表、修改信息等(一般是在“”之后)c. 包含在 中

35、代碼塊的結(jié)束處應加注釋,便于閱讀。特別是多分支、多重嵌套的條件語句或循環(huán)語句(一般是在“”之后)d. 程序中不要出現(xiàn)僅靠大小寫區(qū)分的相似的標識符e. 標識符要采用英文單詞或其組合,便于記憶和閱讀,切忌使用漢語拼音來命名7.其它a. 循環(huán)語句與判斷語句中,不允許對其它變量進行計算與賦值循環(huán)語句只完成循環(huán)控制功能,if語句只完成邏輯判斷功能,不能完成計算賦值功能b. 一條語句只完成一個功能c. 在表達式中使用括號,使表達式的運算順序更清晰d. 避免表達式中的附加功能,不要編寫太復雜的復合表達式e. 在條件判斷語句中,當整型變量與0 比較時,不可模仿布爾變量的風格,應當將整型變量用“=”或“!=”直

36、接與0比較f. 應當將指針變量用“=”或“!=”與null比較g. 在switch語句中,每一個case分支必須使用break結(jié)尾,最后一個分支必須是default分支h. 如果循環(huán)體內(nèi)存在邏輯判斷,并且循環(huán)次數(shù)很大,宜將邏輯判斷移到循環(huán)體的外面(建議)i. 避免函數(shù)有太多的參數(shù),參數(shù)個數(shù)盡量控制在5個以內(nèi)(建議)j. 不要省略返回值的類型,如果函數(shù)沒有返回值,那么應聲明為void類型k. 對于有返回值的函數(shù),每一個分支都必須有返回值l. 如果返回值表示函數(shù)運行是否正常,規(guī)定0為正常退出,不同非0值標識不同異常退出。避免使用true或false作為返回值(建議)(就當沒有布爾型變量)m. 對輸

37、入?yún)?shù)的正確性和有效性進行檢查n. 函數(shù)的功能要單一,不要設計多用途的函數(shù)(建議)o. 函數(shù)體的規(guī)模不能太大,盡量控制在200行代碼之內(nèi)(建議)p. 必須對所調(diào)用函數(shù)的錯誤返回值進行處理q. 名應當直觀且可以拼讀,可望文知意,便于記憶和閱讀r. 命名的長度應當符合“min-length & max-information”原則s. 盡量避免名字中出現(xiàn)數(shù)字編號,如value1,value2 等t. 對在多個文件之間共同使用的全局變量或函數(shù)要加范圍限定符(建議使用模塊名(縮寫)作為范圍限定符)u. 標識符名分為兩部分:規(guī)范標識符前綴(后綴) + 含義標識。非全局變量可以不用使用范圍限定符前綴三、第

38、一個程序編譯:gcc hello.c -o hello-o 生成的目標文件-wall 顯示所有警告執(zhí)行:./hello 可運行生成的目標文件time ./hello 運行結(jié)束后可顯示運行使用的時間real:真實使用時間,包括進程被掛起、用戶輸入等所用的時間user:用戶態(tài)所用的時間 sys:系統(tǒng)態(tài)所用的時間比較程序的運行速度,一般把后兩項相加來進行比較。/* hello.c */ #ansi c規(guī)定的注釋,注意/是c+標準的注釋#但加入了c99中。/* */是不能嵌套的#如:a/b;#include /e/ */f = g/*/h;/# #define glue(x,y) x#yglue(/,

39、/) k();/*/*/ l();# m = n/*/o+ p;#include #頭文件#標準庫頭文件用尖括號,非標準庫頭文件用雙引號“ ”#標準庫在/usr/include中int main(void)#是主函數(shù),int為返回值是整型,0為正常,負數(shù)為不正常#void是傳遞的參數(shù),void表示空printf(hello worldn);#是中定義的輸出函數(shù)#中放置需要打印的字符串#n表示換行treturn 0;#返回0四、數(shù)據(jù)類型數(shù)據(jù)結(jié)構(gòu) + 算法 = 程序c語言提供的數(shù)據(jù)結(jié)構(gòu),是以數(shù)據(jù)類型形式出現(xiàn)的。具體分類如下: 基本類型 分為整型、實型(又稱浮點型)、字符型和枚舉型四種。 構(gòu)造類型

40、分為數(shù)組類型、結(jié)構(gòu)類型和共用類型三種。 指針類型。 空類型c語言中的數(shù)據(jù),有常量和變量之分,它們分別屬于上述這些類型。1.常量與變量1)常量在程序運行過程中,其值不能被改變的量稱為常量分類: 整型常量:123(十進制),0123(0開頭八進制),0x123(0x開頭十六進制),123u(無符號整型),123ul(無符號長整型) 浮點類型常量:12.3f, 12.3d 字符常量:a b字符常量用整數(shù)存儲,占sizeof(int)個字節(jié)。注意:“a”“b”是字符串,不是字符常量。語言還允許使用一種特殊形式的字符常量,就是以反斜杠“ ”開頭的轉(zhuǎn)義字符。注意:如果反斜杠或單引號本身作為字符常量,必須使

41、用轉(zhuǎn)義字符:、。 枚舉常量:enumno,yes;第一個no默認從0開會四分配整數(shù)值,以后每個遞增1。為其中的某個賦值(正負均可)前面的數(shù)值不會隨之改變,而其后的隨之改變。枚舉舉例見enum_changliang.c 字符串常量:hello,world常量關(guān)鍵字是const,一般用于函數(shù)中參數(shù)的定義,避免對形參進行修改。例如:int fun(int a, const int b, int *p)2)變量在程序運行過程中,其值可以被改變的量稱為變量。變量的使用:定義、聲明(即賦值)、引用變量的兩個要素: 變量名:每個變量都必須有一個名字變量名,變量命名遵循標識符命名規(guī)則。 變量值:在程序運行過程

42、中,變量值存儲在內(nèi)存中。在程序中,通過變量名來引用變量的值。,標識符命名規(guī)則 有效字符:只能由字母、數(shù)字和下劃線組成,且以字母或下劃線開頭。 有效長度:隨系統(tǒng)而異,但至少前個字符有效。如果超長,則超長部分被舍棄。例如,由于student_name和student_number的前個字符相同,有的系統(tǒng)認為這兩個變量,是一回事而不加區(qū)別。 c語言的關(guān)鍵字不能用作變量名。 c語言對英文字母的大小敏感,即同一字母的大小寫,被認為是兩個不同的字符。習慣上,變量名和函數(shù)名中的英文字母用小寫,以增加可讀性。所謂“見名知意”是指,通過變量名就知道變量值的含義。通常應選擇能表示數(shù)據(jù)含義的英文單詞(或縮寫)作變量

43、名,或漢語拼音字頭作變量名。全局變量與局部變量:全局變量:在函數(shù)外部定義,不初始化則為0,但最好也初始化賦值局部變量:在函數(shù)內(nèi)部定義,不初始化則為一隨即數(shù),所以一般都要初始化賦值3)const定義的常量const int a;int const a;a是一個常整型數(shù)const int *a;int const *a指向常整型數(shù)的指針int * const a;指向整數(shù)的常指針const int * const a;a是一個指向常整型數(shù)的常指針如果應試者能正確回答這些問題,那么他就給我留下了一個好印象。順帶提一句,也許你可能會問,即使不用關(guān)鍵字const,也還是能很容易寫出功能正確的程序,那么我

44、為什么還要如此看重關(guān)鍵字const呢?我也如下的幾下理由:a. 給讀你代碼的人傳達非常有用的信息,b. 通過給優(yōu)化器一些附加的信息,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。c. 減少bug的出現(xiàn)。2.整型變量1)分類:根據(jù)占用內(nèi)存字節(jié)數(shù)的不同,整型變量又分為類: 基本整型(類型關(guān)鍵字為int) 短整型(類型關(guān)鍵字為short int) 長整型(類型關(guān)鍵字為long int) 無符號整型。無符號型又分為無符號基本整型(unsigned int)、無符號短整型(unsigned short)和無符號長整型(unsigned long)三種,只能用來存儲無符號整數(shù)。2)占內(nèi)存:上述各類型整型變量

45、占用的內(nèi)存字節(jié)數(shù),隨系統(tǒng)而異。在16位操作系統(tǒng)中,一般用字節(jié)表示一個int型變量,且long型(字節(jié))int型(字節(jié))short型(字節(jié))。在32位系統(tǒng)中,一般用4字節(jié)表示一個int型變量,且long型(4字節(jié))int型(4字節(jié))short型(字節(jié))。例子int_size.c無符號變量:例子unsigned_char.c測試結(jié)果。顯然,不同類型的整型變量,其值域不同。占用內(nèi)存字節(jié)數(shù)為n的(有符號)整型變量,其值域為:-2n*8-1(2n*8-1-1);無符號整型變量的值域為:0(2n*8-1)。例如,pc機中的一個int型變量,其值域為-22*8-1(22*8-1-1),即-327683276

46、7;一個unsigned型變量的值域為:0(22*8-1),即065535。將變量賦值為最大的整型數(shù):體現(xiàn)了移植性unsigned int zero = 0;unsigned int compzero = 0xffffffff; /*1s complement of zero */對于一個int型不是16位的處理器為說,上面的代碼是不正確的。應編寫如下:unsigned int compzero = 0;混合運算:下面的代碼輸出是什么,為什么?void foo(void)unsigned int a = 6;int b = -20;(a+b 6) ? puts( 6) : puts(6”。原因

47、是當表達式中存在有符號類型和無符號類型時所有的操作數(shù)都自動轉(zhuǎn)換為無符號類型。 因此-20變成了一個非常大的正整數(shù),所以該表達式計算出的結(jié)果大于6。這一點對于應當頻繁用到無符號數(shù)據(jù)類型的嵌入式系統(tǒng)來說是豐常重要的。如果你答錯了這個問題,你也就到了得不到這份工作的邊緣。3)類型自動轉(zhuǎn)換 若類型所占字節(jié)數(shù)不同,向數(shù)據(jù)長度增長的方向轉(zhuǎn)換,確保精度不會下降。 若有無符號不同,有符號數(shù)向無符號數(shù)轉(zhuǎn)換。 char型與short型運算,先轉(zhuǎn)換成int型。 賦值運算中,兩邊的不同,則右邊的變量自動轉(zhuǎn)換為左邊的類型。如果右邊的比左邊的長,則丟失一部分數(shù)據(jù),這樣會降低精度,丟失的部分按四舍五入向前舍入。補充:類型轉(zhuǎn)

48、換a.將實型數(shù)據(jù)(單,雙精度)賦給整形變量時,舍棄實數(shù)的小數(shù)部分。如i = 3.56 .(int)i為3。b.將整形數(shù)據(jù)賦給單,雙精度變量時,數(shù)值不變,但以浮點數(shù)形式存儲到變量中。int i=23,將其轉(zhuǎn)換為float型后變?yōu)?3.00000c.強制類型轉(zhuǎn)換注意:強制轉(zhuǎn)換類型得到的是一個所需類型的中間量,原表達式類型并不發(fā)生變化。例如,(double)a 只是將變量a的值轉(zhuǎn)換成一個double型的中間量,其數(shù)據(jù)類型并未轉(zhuǎn)換成double型。4)const定義的常量3.實型變量實型常量又稱實數(shù)或浮點數(shù)。語言的實型變量,分為兩種:a.單精度型。類型關(guān)鍵字為float,一般占字節(jié)(位)、提供位有效數(shù)

49、字。b.雙精度型。類型關(guān)鍵字為double,一般占個字節(jié)、提供1516位有效數(shù)字。在語言中可以用兩種形式表示一個實型常量。1)小數(shù)形式小數(shù)形式是有效數(shù)字和小數(shù)點組成的一種實數(shù)表示形式,例如0.123、.123、123.、0.0等都是合法的實型常量。注意:小數(shù)形式表示的實型常量必須要有小數(shù)點。2)指數(shù)形式這種形式類似數(shù)學中的指數(shù)形式。以“e”或“e”后跟一個整數(shù)來表示以“10”為底數(shù)的冪數(shù)。2.3026可以表示為0.23026e1、2.3026e0、23.026e-1。c語言語法規(guī)定,字母e或e之前必須要有數(shù)字,且e或e后面的指數(shù)必須為整數(shù)。如e3、5e3.6、.e、e等都是非法的指數(shù)形式。注意

50、:在字母e或e的前后以及數(shù)字之間不得插入空格。一個32位的signed int 類型整數(shù)其值表示法范圍為:-2(31)2(31)-1;8位的char類型數(shù)其值表示的范圍為-2(7)2(7)-1。一個32位的unsigned in 類型整數(shù)其值表示法范圍為:02(32)-1;8位的char類型數(shù)其值表示的范圍為02(8)-1。4.字符變量字符變量用來存儲字符常量。將一個字符常量存儲到一個字符變量中,實際上是將該字符的ascii碼值(無符號整數(shù))存儲到內(nèi)存單元中。例如,char ch1, ch2;/* 定義兩個字符變量:ch1,ch2 */ch1=a; ch2=98;/*給字符變量賦值*/特性:字

51、符數(shù)據(jù)在內(nèi)存中存儲的是字符的ascii碼(用man ascii查看),一個無符號整數(shù),其形式與整數(shù)的存儲形式一樣(如圖2-4所示),所以語言允許字符型數(shù)據(jù)與整型數(shù)據(jù)之間通用。例子:char_int.c定義一個字符型變量temp,將變量temp賦值為1,并將變量temp以%c輸出。定義兩個字符型變量tempa,tempb分別賦值為a,b,分別以%d和%c打印。5.字符串常量1)字符串常量的概念和字符串長度字符串常量是用一對雙引號括起來的若干字符序列。字符串中字符的個數(shù)稱為字符串長度。長度為0的字符串(即一個字符都沒有的字符串)稱為空串,表示為“”(一對緊連的雙引號)。例如,“how do you

52、 do.”、“good morning.”等,都是字符串常量,其長度分別為14和13(空格也是一個字符)。如果反斜杠和雙引號作為字符串中的有效字符,則必須使用轉(zhuǎn)義字符。2)字符串的存儲c語言規(guī)定:在存儲字符串常量時,由系統(tǒng)在字符串的末尾自動加一個0作為字符串的結(jié)束標志。注意:在源程序中書寫字符串常量時,不必加結(jié)束字符0,否則畫蛇添足??芍?,字符常量a與字符串常量a是兩回事:a.定界符不同:字符常量使用單引號,而字符串常量使用雙引號;b.長度不同:字符常量的長度固定為1,而字符串常量的長度,可以是0,也可以是某個整數(shù);c.存儲要求不同:字符常量存儲的是字符的ascii碼值,而字符串常量,除了要存儲有效的字符外,還要存儲一個結(jié)束標志0。五、運算符c語言運算符優(yōu)先級1)算術(shù)運算符:+,-,*,/,%除了%操作符,其余幾個操作符都是既適用浮點類型又用于整數(shù)類型。對于q = a/b;r = a%b;c語言的定義只保證了q = a/b;r = a%b;以及當a=0且b0時,保證|r|=0。當執(zhí)行算術(shù)運算時,操作數(shù)的類型如果不同,就會發(fā)生轉(zhuǎn)換。數(shù)據(jù)類型一般朝著浮點精度更高,長度更長的方向轉(zhuǎn)換,整形數(shù)如果轉(zhuǎn)換為signed不會丟失信息,就轉(zhuǎn)換為signed,否則轉(zhuǎn)換為unsigned。2)關(guān)系運算符:,=,=,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論