銷(xiāo)項(xiàng)稅和進(jìn)項(xiàng)導(dǎo)入是在國(guó)稅網(wǎng)站做嗎制作網(wǎng)站費(fèi)用
目錄
一,gcc簡(jiǎn)介
二,C語(yǔ)言源文件的編譯過(guò)程
1.預(yù)處理
2.編譯
3.匯編
?4.鏈接
5.動(dòng)靜態(tài)庫(kù)?
一,gcc簡(jiǎn)介
相信有不少的小白和我一樣在學(xué)習(xí)Linux之前只聽(tīng)說(shuō)過(guò)visual? studio。其實(shí)這個(gè)gcc這個(gè)編譯器實(shí)現(xiàn)的功能便是和visual studio一樣的功能,但是gcc只能夠支持c語(yǔ)言。如果要支持C++的話便要用到g++。
二,C語(yǔ)言源文件的編譯過(guò)程
1.預(yù)處理
在C源文件運(yùn)行時(shí)做的第一步便是預(yù)處理,在預(yù)處理的過(guò)程中要做的便是:
1.頭文件展開(kāi)。
2.去掉注釋。
3.條件編譯。
4.宏替換。
這上面的四步便是預(yù)處理時(shí)要做的四步。那我們?cè)贚inux中要如何的去觀察這一個(gè)過(guò)程呢?這個(gè)時(shí)候便要使用到一個(gè)Linux的指令了。這個(gè)指令便是——gcc -E:代表的意思便是開(kāi)始編譯C源文件等到預(yù)處理結(jié)束以后便停止翻譯??梢詠?lái)段代碼來(lái)看看效果。如以下代碼:
#include<stdio.h> //頭文件2 #define M 123 //宏定義3 #define v1 1 4 #define v2 0 5 #define v3 0 6 int main() 7 { 8 printf("hello Linux:%d \n",M); 9 printf("hello C++ :%d \n",M); 10 11 // printf("hello Linux:%d \n",M);//注釋 12 // printf("hello C++ :%d \n",M); 13 // 14 // printf("hello Linux:%d \n",M); 15 // printf("hello C++ :%d \n",M); 16 17 #if(v1) //條件編譯 18 printf("普通版本\n"); 19 #elif(v2) 20 printf("會(huì)員版本\n"); 21 #else 22 printf("超級(jí)會(huì)員版本\n"); 23 #endif 24 25 return 0 ; 26 }
當(dāng)我執(zhí)行如下指令時(shí):gcc -E texe2.c -o code.i。當(dāng)我們輸入這條指令時(shí)便會(huì)得到一個(gè)code.i文件。當(dāng)用vim進(jìn)到這個(gè)文件里面是便會(huì)看到頭文件被展開(kāi)了,宏被替換掉了,注釋被刪掉了,預(yù)處理指令只有條件成立的那一部分被留下來(lái)。
2.編譯
這個(gè)編譯便是代碼翻譯的第二步,在這個(gè)過(guò)程中我們要做的便是將英文代碼變成匯編代碼。在Linux 系統(tǒng)下輸入gcc -S ,這條指令便可以生成一個(gè)經(jīng)過(guò)編譯后的匯編文件。比如對(duì)上述的code.i文件進(jìn)行編譯-gcc -S code.i -o code.s,便會(huì)得到這樣一個(gè)匯編文件:
這樣子便將c源文件給弄成了匯編文件了。
3.匯編
在這個(gè)過(guò)程中要做到的便是將匯編文件翻譯為重定向的二進(jìn)制文件。在Linux系統(tǒng)下輸入指令:gcc -c便可。如對(duì)上述的code.s文件進(jìn)行翻譯便可以輸入指令-code -c code.s -o code.o。在執(zhí)行完這個(gè)指令以后便會(huì)形成一個(gè)code.o文件。用vim打開(kāi)該文件便會(huì)是這樣一個(gè)光景:
因?yàn)関im是文本編輯器,但是code.o文件卻是二進(jìn)制文件所以就會(huì)出現(xiàn)這樣的錯(cuò)誤。要打開(kāi)二進(jìn)制文件要調(diào)用另一個(gè)指令——od。打開(kāi)后便是這樣的:
我們自然是看不懂的,但是計(jì)算機(jī)就能看懂。在進(jìn)行到這一步以后一個(gè)二進(jìn)制文件也就是目標(biāo)文件便生成了。但是此時(shí)我們還不能運(yùn)行。
?4.鏈接
生成目標(biāo)文件以后,如果要運(yùn)行的話便要經(jīng)過(guò)鏈接這一步。經(jīng)過(guò)了鏈接這一步以后代碼才可以變成一個(gè)可執(zhí)行文件。在Linux環(huán)境下就是輸入指令gcc 。對(duì)于上述的code.o文件也就是輸入指令 ——gcc code.o -o mybin:
5.動(dòng)靜態(tài)庫(kù)?
1.庫(kù)的分類(lèi)
其實(shí)可執(zhí)行文件 = 頭文件+代碼+庫(kù)。在這里頭文件相當(dāng)于一個(gè)功能函數(shù)聲明的集合,代碼就是我們調(diào)用功能函數(shù)的指令,庫(kù)便是各種功能函數(shù)的定義。在這里的庫(kù)便分為兩種庫(kù),一種叫做動(dòng)態(tài)庫(kù),一種叫做靜態(tài)庫(kù)。動(dòng)態(tài)庫(kù)的后綴是so,靜態(tài)庫(kù)的后綴是.a。在Linux環(huán)境下輸入指令ls /usr/lib64/libc.so.6便可以查看這個(gè)動(dòng)態(tài)庫(kù)。
得到這個(gè)藍(lán)色的路徑便是動(dòng)態(tài)庫(kù)的路徑。lib表示庫(kù),c表示動(dòng)態(tài)庫(kù)的名字,so表示是動(dòng)態(tài)庫(kù),6表示版本。
2.鏈接方式
在Linux中有兩種鏈接方式。一種是動(dòng)態(tài)連接方式,一種是靜態(tài)鏈接方式。這兩種不同的鏈接方式各自有各自的優(yōu)點(diǎn)。動(dòng)態(tài)鏈接形成的可執(zhí)行程序比較小,靜態(tài)鏈接形成的可執(zhí)行序比較大。這兩種差別是因?yàn)檫@兩種鏈接調(diào)用庫(kù)中功能函數(shù)的方式的不同導(dǎo)致的。
1.動(dòng)態(tài)鏈接是通過(guò)函數(shù)的地址來(lái)調(diào)用的,靜態(tài)鏈接是通過(guò)將函數(shù)拷貝到可執(zhí)行文件中來(lái)調(diào)用的。
2.動(dòng)態(tài)庫(kù)的函數(shù)調(diào)用會(huì)受到動(dòng)態(tài)庫(kù)的存在與否影響,但是靜態(tài)庫(kù)則不受這個(gè)影響。
?