linux下的c编程
vi編譯器簡(jiǎn)介
vi的三種模式,分別為命令行模式,插入模式以及底行模式,這里游客去看,這里提供好幾個(gè)小技巧:G表示移動(dòng)到文件末尾nG表示移動(dòng)到第幾行
gcc優(yōu)化選項(xiàng)
gcc可以對(duì)代碼進(jìn)行優(yōu)化,他可以通過(guò)編譯選項(xiàng)“-On”來(lái)控制優(yōu)化代碼的生成,其實(shí)你是一個(gè)代表優(yōu)化級(jí)別的整數(shù),對(duì)于不同的版本的gcc來(lái)講,n的取值范圍以及對(duì)應(yīng)的優(yōu)化效果可能并不完全相同,比較典型的是從0到2或者3
不同的優(yōu)化級(jí)別對(duì)應(yīng)不同的優(yōu)化處理工作,如使用優(yōu)化選項(xiàng)-O 主要進(jìn)行線程跳轉(zhuǎn)和延遲退棧,使用優(yōu)化選項(xiàng)-O2除了完成所有的-O1級(jí)別的優(yōu)化之外,同時(shí)還進(jìn)行一些額外的調(diào)整工作,比如優(yōu)化處理器指令調(diào)度,選項(xiàng)“-O3”則還包括循環(huán)展開和其他一些與處理器相關(guān)的優(yōu)化工作
雖然優(yōu)化選項(xiàng)可以加速代碼的運(yùn)行速度,但是,對(duì)于調(diào)試而言將會(huì)是一個(gè)很大的挑戰(zhàn),因?yàn)榇a在進(jìn)行優(yōu)化之后,原先在源程序中聲明和使用的變量很有可能不在使用,控制流也可能突然跳轉(zhuǎn)到意外的地方,循環(huán)語(yǔ)句也有可能因?yàn)檠h(huán)的展開而變得到處都有,所有的這些優(yōu)化對(duì)調(diào)試來(lái)講都將是一場(chǎng)噩夢(mèng),所以筆者建議在調(diào)試的時(shí)候最好不適用任何優(yōu)化選項(xiàng),只有當(dāng)程序在最終發(fā)行時(shí)才考慮對(duì)其進(jìn)行優(yōu)化
?在gdb中的命令都可以使用縮略形式的命令《保存退出前使用gcc編譯要加上 -g這個(gè)參數(shù)》
l 代表list
b 代表breakpoint
p代表print?
設(shè)置斷點(diǎn) b 6 //在第六行設(shè)置斷點(diǎn),查看斷點(diǎn) info b?
程序調(diào)試的大致7步
1:查看文件 (l)2:設(shè)置斷點(diǎn)(b)3:查看斷點(diǎn)情況(info b)4:運(yùn)行代碼(r)5:查看變量的值 (p 變量)
6:單步運(yùn)行(n 和s)7:恢復(fù)程序運(yùn)行(c)
小技巧1:在設(shè)置完斷點(diǎn)之后,運(yùn)行程序,當(dāng)程序運(yùn)行到斷點(diǎn)處時(shí)用戶可以鍵入backrace ,或者是(bt)可以查找到調(diào)用函數(shù)(堆棧)的情況,這個(gè)功能在程序調(diào)試之中使用非常廣泛,經(jīng)常用于排除錯(cuò)誤或者監(jiān)視調(diào)用堆棧的情況
?小技巧2:gdb在顯示變量時(shí)都會(huì)在對(duì)應(yīng)值之前加上“$N”標(biāo)記,他是當(dāng)前變量值得應(yīng)用標(biāo)記,所以以后若想再次引用此變量就可以直接寫作“$N",而無(wú)需寫冗長(zhǎng)的變量名
?
小知識(shí):在gdb中,程序的運(yùn)行狀態(tài)有 運(yùn)行 暫停 和停止 其中 暫停 狀態(tài)為程序遇到斷點(diǎn)或者觀察點(diǎn)之類的,函數(shù)暫時(shí)停止運(yùn)行,此時(shí)函數(shù)的地址,函數(shù)參數(shù),函數(shù)內(nèi)的局部變量都會(huì)被壓入“棧”中。故在這種狀態(tài)下可以查看函數(shù)的變量值等各種屬性,但是函數(shù)處于停止?fàn)顟B(tài)之后,棧就會(huì)自動(dòng)撤銷,他就無(wú)法查看各種信息了。
?
make 工程管理器
所謂工程管理器,顧名思義,是用于管理較多的文件,讀者可以試想一下,有成百上千個(gè)文件構(gòu)成的項(xiàng)目,如果其中只有一個(gè)或者少數(shù)幾個(gè)文件進(jìn)行了修改,按照之前所學(xué)的gcc編譯工具,就不得不把這些文件重新編譯一遍,因?yàn)榫幾g器并不知道那些文件是最近更新的,而只知道需要包含這些文件才能把源代碼編譯成可執(zhí)行文件,于是,程序員就不得不重新輸入數(shù)目如此龐大的文件名已完成最后的編譯工作
編譯過(guò)程分為編譯 匯編 連接階段,其中編譯階段僅僅是檢查語(yǔ)法錯(cuò)誤以及函數(shù)與變量是否被正確的聲明了,在鏈接階段這主要是完成函數(shù)鏈接和全局變量的鏈接,因此,那些沒(méi)有改動(dòng)的源代碼根本不需要重新編譯,而只是要把他們重新鏈接進(jìn)去就可以了,所以,人們就希望有一個(gè)工程管理器能夠自動(dòng)的識(shí)別更新了的文件代碼,而不需要重復(fù)輸入冗長(zhǎng)的命令行,這樣make工程管理器就用運(yùn)而生了
實(shí)際上,make 工程管理器也是個(gè) 自動(dòng)編譯管理器 這里的自動(dòng)是指他能夠 根據(jù)文件時(shí)間戳自動(dòng)發(fā)現(xiàn)更新過(guò)的文件而減少編譯的工作量,同時(shí) 他通過(guò)讀入makefile 文件的內(nèi)容來(lái)執(zhí)行大量的編譯工作,用戶只需要編寫一次簡(jiǎn)單的編譯語(yǔ)句就可以了,他大大提高了實(shí)際項(xiàng)目的工作效率,而幾乎所有l(wèi)inux下的項(xiàng)目編程均會(huì)涉及它
?makefile基本結(jié)構(gòu)
makefile是make讀入的唯一配置文件,因此要講一下makefile的編寫規(guī)則,在一個(gè)makefile文件中通常包括如下內(nèi)容:
1:需要由make 工具創(chuàng)建的目標(biāo)體,通常是目標(biāo)文件或者是可執(zhí)行文件
2:要?jiǎng)?chuàng)建目標(biāo)體所依賴的文件
3:創(chuàng)建每個(gè)目標(biāo)體需要運(yùn)行的命令,這一行必須以制表符(tab鍵開頭)
他的格式為
target:denpdency_files
command: /*該行必須以tab鍵開頭*/
例如:有兩個(gè)文件分別為hello.c和hello.h ,創(chuàng)建的目標(biāo)體為hello.c,執(zhí)行的命令為gcc編譯指令 gcc -c hello.c,那么對(duì)應(yīng)的makefile就可以寫為:
hello.o:hello.c hello.h
gcc -c hello.c -o hello.o
接下來(lái)就可以只用make了,使用make的格式為make target 這樣make就會(huì)自動(dòng)讀入
?makefile,并執(zhí)行target中的command 語(yǔ)句,并未找到相應(yīng)的依賴文件
?makefile變量
上面示例的makefile在實(shí)際中是幾乎不存在的,因?yàn)樗^(guò)于簡(jiǎn)單,僅僅包含兩個(gè)文件和一個(gè)命令,在這種情況完全不需要寫makefile,而只需在shell中直接輸入即可,在實(shí)際中使用的makefile往往是包含很多的文件和命令的,這也是makefile出現(xiàn)的原因
下面是一個(gè)例子
?
這個(gè)makefile中有3個(gè)目標(biāo)體(target),分別是david kang.o yu.o 其中第一個(gè)目標(biāo)體的依賴文件就是后面兩個(gè)目標(biāo)體,如果用戶使用命令make david ?,則make管理器就是找到david目標(biāo)體開始執(zhí)行。這時(shí)make會(huì)自動(dòng)檢查相關(guān)文件的時(shí)間戳,首先,在檢查kang.o,yul.o和david 3 個(gè)文件的時(shí)間戳之前,他會(huì)向下查找那些把kang.o或yul.o作為目標(biāo)文件的時(shí)間戳,比如kang.o依賴文件為kang.c kang.h head.h 如果這些文件中任何一個(gè)的時(shí)間戳比kang.o新,則命令gcc -Wall ?-O -g -c kang.c -o kang.o就會(huì)執(zhí)行,從而更新kang.o,在更新完kang.o或yul.o之后,make會(huì)檢查最初的kang.o yul.o和david 3個(gè)文件,只要文件kang.o或者yul.o中的至少有一個(gè)文件的時(shí)間戳比david新,則第二行命令就會(huì)被執(zhí)行,這樣,make就完成了自動(dòng)檢查時(shí)間戳的工作,開始執(zhí)行編譯工作,這也是make工作的基本流程
?
為了進(jìn)一步簡(jiǎn)化編輯和維護(hù)makefile ,make允許在makefile中創(chuàng)建和使用變量,變量是在makefile中定義的名字,用來(lái)代替一個(gè)文本字符串,該文本字符串成為該變量的值,在具體要求下,這些值可以代替目標(biāo)體,依賴文件,命令以及makefile文件中的其他部分
?
makefile中的變量的定義有兩種,一種是遞歸展開方式,另一種是簡(jiǎn)單方式,
遞歸展開方式定義的變量是在引用該變量是進(jìn)行替換,即如果該變量包含了對(duì)其他變量的引用,則在引用變量時(shí)一次性將內(nèi)嵌的變量全部展開,雖然這種類型的變量能夠很好地完成用戶的指令,但是他也有嚴(yán)重的缺點(diǎn),如 不能在變量后追加內(nèi)容(因?yàn)檎Z(yǔ)句:CRLAGS = $(CFLAGS) -O 在變量擴(kuò)展過(guò)程中可能袋子無(wú)窮循環(huán)
?
為了避免上述問(wèn)題,簡(jiǎn)單擴(kuò)展型變量的值在定義處展開,并且只展開一次,因此他不包含任何變來(lái)那個(gè)對(duì)其他變量的引用,從而消除變量的嵌套引用。
遞歸展開方式的定義格式為:VAR = var
簡(jiǎn)單擴(kuò)展方式的定義格式為:VAR:=var
make中的變量均使用的格式為:$(VAR) ?//注意變量名是大小寫敏感的,例如變量名foo FOO Foo代表不同的變量,推薦在makefile內(nèi)部使用小寫字母作為變量名,預(yù)留大寫字母作為控制隱含規(guī)則參數(shù)或用戶重載命令選項(xiàng)參數(shù)的變量名
下面給出了上例中用變量替換修改的makefile 這里用OBJS 代替kang.o和yul.o 用CC代替gcc 用CRLAGS 代替-Wall -O -g 這樣在以后修改時(shí),就可以只修改變量定義,而不需要修改下面的定義實(shí)體,從而大大簡(jiǎn)化了makefile的維護(hù)工作量
?
下文待續(xù)~~~
版權(quán)所有,轉(zhuǎn)載請(qǐng)標(biāo)明鏈接地址http://www.cnblogs.com/fengdashen
轉(zhuǎn)載于:https://www.cnblogs.com/fengdashen/p/3286575.html
總結(jié)
以上是生活随笔為你收集整理的linux下的c编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JUC.Condition学习笔记[附详
- 下一篇: llinux环境变量查看和修改