電子商務(wù)網(wǎng)站建設(shè)的相關(guān)流程八零云自助建站免費(fèi)建站平臺(tái)
我們?cè)趘s編譯器中寫(xiě)的代碼按下ctrl f5就可以直接運(yùn)行起來(lái),并且會(huì)將運(yùn)行的結(jié)果顯示到顯示器上,這里看上去只有一個(gè)步驟但實(shí)際上這里會(huì)存在很多的細(xì)節(jié),比如說(shuō)生成結(jié)果在這里插入代碼片
之前我們的代碼會(huì)經(jīng)過(guò)預(yù)處理,編譯,匯編,鏈接的過(guò)程,不同的過(guò)程會(huì)對(duì)應(yīng)不同的操作,那么接下來(lái)我們就會(huì)一個(gè)一個(gè)的介紹這些操作所對(duì)應(yīng)的操作。
預(yù)處理
程序運(yùn)行的第一步就是預(yù)處理,預(yù)處理的目的就是:將頭文件展開(kāi),去掉注釋,宏替換,刪除條件編譯,比如說(shuō)我們創(chuàng)建一個(gè)臨時(shí)文件test.c:
并且在這個(gè)文件里面輸入一些內(nèi)容:
1 #include<stdio.h> 2 #define NUM_A 20 3 #define NUM_B 30 4 int main()5 {6 #ifdef add7 printf("相加的結(jié)果為:%d\n",NUM_A+NUM_B);//計(jì)算相加的結(jié)果8 #else9 printf("相減的結(jié)果為:%d\n",NUM_A-NUM_B);//計(jì)算相減的結(jié)果 10 #endif 11 return 0; 12 }
然后我們就退出并且保存這個(gè)文件:
到這里我們的準(zhǔn)備工作就完成了。平時(shí)我們運(yùn)行文件使用的指令是:gcc test.c
使用這個(gè)指令會(huì)自動(dòng)的生成一個(gè)文件叫a.out,并且這個(gè)文件是一個(gè)可執(zhí)行程序,我們運(yùn)行一下這個(gè)程序就可以可以看到我們的屏幕上面出現(xiàn)了上面代碼的運(yùn)行的結(jié)果:
但是這里有個(gè)問(wèn)題,使用這個(gè)指令我們看不到預(yù)處理的結(jié)果它直接變成了可執(zhí)行程序,所以得在這個(gè)指令里面添加一個(gè)-E選項(xiàng),這個(gè)選項(xiàng)的功能就是從重現(xiàn)在開(kāi)始進(jìn)行程序的翻譯,將程序的預(yù)處理執(zhí)行完后就停下來(lái),所以使用這個(gè)選項(xiàng)我們就可以看到代碼經(jīng)過(guò)預(yù)處理之后的結(jié)果,那么這里的指令就是這樣:gcc -E test.c
執(zhí)行的結(jié)果如下:
我們可以看到這里出現(xiàn)很多亂七八糟的內(nèi)容,那是因?yàn)檫@個(gè)指令將執(zhí)行的結(jié)果全部都打印到屏幕上了,由于內(nèi)容很多就顯得很亂,不好查看,所以這里我們還可以在這個(gè)指令里面添加一個(gè)-o選項(xiàng),這個(gè)選項(xiàng)的功能就是將指令的運(yùn)行的結(jié)果放到一個(gè)文件里面,在-o的后面加上你要放的文件,如果這個(gè)文件不存在的話,這個(gè)指令會(huì)自動(dòng)生成對(duì)應(yīng)的文件,比如說(shuō)我們將上面的指令修改成這樣:gcc -E test.c -o test.i
當(dāng)前目錄下是沒(méi)有test.i這個(gè)文件的,所以使用這個(gè)指令后我們會(huì)自動(dòng)的生成test.i這個(gè)文件:
并且這個(gè)文件里面裝的內(nèi)容就是之前顯示在屏幕上的內(nèi)容:
我們可以使用vs指令將test.c文件顯示在屏幕上進(jìn)行對(duì)比:
我們使用shift+g將右邊屏幕的光標(biāo)移動(dòng)到最后一行:
我們可以看到在test.i文件的最后出現(xiàn)了test.c文件中的大致內(nèi)容,但是卻略有不同這是test.i的相關(guān)內(nèi)容:
這是test.c的全部?jī)?nèi)容:
仔細(xì)的觀察一下我們可以看到有以下幾點(diǎn)的不同:
- test.c中的2 3 行定義的宏被刪除了。
- test.c中的7 9行的注釋被刪除了。
- test.c中的7 9行中使用的宏被替換成了我們定義的值也就是說(shuō)NUM_A替換成了20,NUM_B替換成了30。
- test.c中沒(méi)有被執(zhí)行的條件編譯被刪除了也就是第6 7 8 10行的內(nèi)容被刪除了。
- test.c中的頭文件被刪除了但是在test.i中出現(xiàn)了更多雜七雜八的東西,所以在預(yù)編譯的過(guò)程中將頭文件中的內(nèi)容加載到test.i的文件里面。
那么這就是預(yù)編譯所做的一些操作將頭文件展開(kāi),去掉注釋,宏替換,刪除條件編譯,那么這里大家要注意的一點(diǎn)就是在linux操作系統(tǒng)中文件的后綴是沒(méi)有意義的,也就是說(shuō)這里的后綴i對(duì)于操作系統(tǒng)來(lái)說(shuō)是沒(méi)有什么特殊意義的,但是這個(gè)后綴對(duì)我們使用者來(lái)說(shuō)卻有很多的意義,比如說(shuō)我們看到了一個(gè)文件的后綴是i就可以想到這個(gè)文件是經(jīng)過(guò)預(yù)處理后生成的文件,所以大家在執(zhí)行這些操作生成文件的時(shí)候還是要將后綴寫(xiě)成對(duì)應(yīng)的形式以免混淆別人,那么上面就是預(yù)處理要干的事情。
編譯
經(jīng)歷完預(yù)處理之后要執(zhí)行的操作就是編譯,編譯要干的事情就是將c語(yǔ)言翻譯成匯編語(yǔ)言,那么這里要執(zhí)行的指令就是:gcc -S test.i -o test.s
那么這里-S選項(xiàng)的作用就是從現(xiàn)在開(kāi)始進(jìn)行程序的翻譯,將匯編工作完成之后工作就停止,后面加了一個(gè)-o選項(xiàng),所以這里會(huì)將執(zhí)行完之后的結(jié)果放到test.s這個(gè)文件里面,執(zhí)行完這個(gè)指令我們就可以看到這里自動(dòng)的生成了一個(gè)test.s文件,在這個(gè)文件里面有我們好多我們看不懂的內(nèi)容:
雖然下面的內(nèi)容我們看不懂,但是可以知道的一件事就是這個(gè)test.o文件里面的內(nèi)容是匯編語(yǔ)言:
我們知道計(jì)算器能夠識(shí)別的語(yǔ)言是二進(jìn)制語(yǔ)言,而test.o文件里面裝的是匯編語(yǔ)言,所以這里的test.o文件無(wú)法被運(yùn)行。
匯編
通過(guò)上面的講解我們知道編譯是將c語(yǔ)言翻譯成匯編語(yǔ)言,那么這里的匯編要干的事情就是將生成的匯編語(yǔ)言翻譯二進(jìn)制語(yǔ)言,那么這里需要的指令就是:gcc -c test.s -o test.o
,-c選項(xiàng)的作用就是從現(xiàn)在開(kāi)始進(jìn)行翻譯,將文件中的匯編語(yǔ)言翻譯成二進(jìn)制語(yǔ)言就停止,比如說(shuō)下面的操作:
這里就自動(dòng)生成一個(gè)test.o文件,我們打開(kāi)這個(gè)文件就可以看到文件中的內(nèi)容就變成了各種奇奇怪怪的符號(hào):
這就是文件經(jīng)過(guò)匯編之后的結(jié)果,那么這時(shí)肯定會(huì)有小伙伴想啊,既然這個(gè)文件的內(nèi)容是二進(jìn)制的話,我們是不是就可以運(yùn)行這個(gè)文件呢?那么這里可以試一下看看能不能運(yùn)行
結(jié)果很明顯這個(gè)文件是無(wú)法運(yùn)行的,原因也非常的簡(jiǎn)單因?yàn)槲覀兩鲜龅娜齻€(gè)過(guò)程(預(yù)處理 編譯 匯編)所干的事情是翻譯的過(guò)程,也就是把你的代碼進(jìn)行修剪然后翻譯成二進(jìn)制文件,但是這里有個(gè)問(wèn)題就是你的代碼里面用了很多別人的函數(shù),你沒(méi)有在這個(gè)文件里面實(shí)現(xiàn)這些函數(shù),比如說(shuō)printf函數(shù),scanf函數(shù),main函數(shù)等等,這些函數(shù)你都沒(méi)有實(shí)現(xiàn),雖然你包含了頭文件stdio.h,但是這個(gè)文件里面只有這些函數(shù)的聲明,沒(méi)有這些實(shí)現(xiàn),所以將我們的代碼翻譯成二進(jìn)制文件還是無(wú)法滿足運(yùn)行的需求,所以這里我們還得進(jìn)行下一步鏈接。
鏈接
鏈接干的事情就是把我們自己寫(xiě)的代碼代碼和c標(biāo)準(zhǔn)庫(kù)的代碼合并起來(lái),這個(gè)標(biāo)準(zhǔn)庫(kù)里面裝的就是各種c語(yǔ)言函數(shù)的具體實(shí)現(xiàn)等等,所以當(dāng)二進(jìn)制文件經(jīng)過(guò)鏈接后,里面使用的函數(shù)就有了具體的實(shí)現(xiàn),就可以正常的被執(zhí)行了,那么這里的用的之指令就是:gcc test.o
這里我們不使用-o選項(xiàng)的話,這里就會(huì)自動(dòng)生成一個(gè)名為a.out的可執(zhí)行程序,當(dāng)然這里我們也可以人為的生成一個(gè)可執(zhí)行程序,那么這里就得加上一個(gè)-o選項(xiàng),那么這里的指令就是:gcc test.o -o mytest
當(dāng)生成完可執(zhí)行程序之后就可以運(yùn)行以下這里的可執(zhí)行文件:
那么上述就是這篇文章的全部?jī)?nèi)容希望大家可以理解謝謝。