導航:首頁 > 源碼編譯 > 編譯原理講不講鏈接

編譯原理講不講鏈接

發布時間:2022-12-14 19:45:44

㈠ C++ 程序的編譯過程…

一般來講,編好的代碼(源代碼)經過編譯,鏈接,生成可執行的文件,然後就可以執行。即編輯的代碼要最重生成可執行的程序(可執行的文件),需要經過編譯、鏈接兩個步驟。編譯的作用是對代碼進行語法檢查,而鏈接的作用是鏈接代碼中用到的編譯器提供的資源。所以,通常通過編譯、鏈接後形成的只形成一個可執行的文件。

但是,假如你是採用工程的形式進行編程的話,工程包括很多個文件,比如,VC編程中MFC編程。這個時候源代碼通過鏈接後就形成的是多個文件!

中型程序是什麼語言寫的,這個問題恐怕語言專家也不好回答,因為每種語言,比如C、C++、JAVA等等都可以寫中型程序,而且都是各有優缺點。但是,根據編程的用途,各種語言根據自身的特點可以針對性的使用,如游戲編程一般使用...語言,而系統軟體編程一般使用...語言,這種說法可能更有使用價值一些。

㈡ 《編譯原理》講的是什麼

1.看完龍書應該是牛人了,特別對普通大學生來說,計算機專業很多都弄不下來,除非211學校。當然你的數學背景很不錯。
2.看完龍書不知道編譯學的是什麼,有點對不起龍書。
3.編譯經典部分主要講識別token的演算法和構建語法樹的演算法,同時也講了怎麼樣在樹上進行標記。這些演算法很經典,體現了計算機編程解決問題的很多基本思想。
4.你非計算機專業學這個做什麼?也就是你自學的目的是什麼?知道這個才能回答你的問題。如果你是想搞其它的研究,僅是了解下,則當純粹理論就OK。如果你想考試,則弄本習題書做,如果你想學編程,當然最要緊的是寫個編譯器來實踐。

㈢ 編譯原理課程講什麼內容

《編譯原理》課程介紹編譯器構造的一般原理和基本實現方法,主要介紹編譯器的各個階段:詞法分析、語法分析、語義分析、中間代碼生成、代碼優化和目標代碼生成。本課程在介紹命令式程序設計語言實現技術的同時,強調一些相關的理論知識,如形式語言和自動機理論、語法制導的定義和屬性文法、類型論等。它們是計算機專業理論知識的重要一部分,在本書中結合應用來介紹這些知識,有助於學生較快領會和掌握。本課程強調形式化描述技術,並以語法制導定義作為翻譯的主要描述工具。本課程強調對編譯原理和技術在宏觀上的理解,作為原理性的教學,本課程主要介紹基本的理論和方法,不偏向於某種源語言或目標機器。

㈣ 用VS編譯和C++源文件的時候,源文件和庫文件是如何鏈接到源文件的具體細節

因為我是學習計算機軟體專業的,故可以給你講一下大概意思,我也不敢保證我講得都是正確的。個人講解僅供參考。這個是需要學習《計算機編譯原理》這門課程的。而且《計算機編譯原理》這門課程在軟體專業中幾乎是最抽象的、難於理解的。
首先關於 Visual Studio編譯器(或者是別的 C/C++編譯器)是如何將用戶親自編寫的源程序經過若干步驟之後,最終變成計算機可執行的二進制代碼程序?這裡面經過了如下步驟:
(1)、詞法分析/語法分析。也就是說當編譯器對用戶編寫的源程序進行編譯時,首先檢查你的詞法(或者是語法)是否正確,這是第一步(這里以 C 語言為例,假如將定義一個整型變數 n 的語句 int n ; 誤寫成了:intt n ; 屬於語法錯誤)。如果這一步都沒有通過編譯器的檢查的話,那麼絕對不會進入第二步。繼續返回編輯狀態進行語法檢查。這種錯誤是最容易檢查的。
(2)、語義分析。這類錯誤就要比(1)困難得多。這類錯誤舉例如下(這類錯誤編譯器只是會給出一個警告信息,但是編譯器是會放過這類錯誤的。故需要編程人員具有較豐富的編程經驗)
void main( )
{
int num ; /* 定義一個整型變數 num */
scanf("%d", &num ) ; /* 從鍵盤上輸入一個整數 */
if( num == 10 ) /* 在這個語句中,如果將邏輯判斷等於號 ==,誤寫為數值等於 =(即:if( num = 10 )),那麼該程序的執行結果始終輸出:Correct。因為該邏輯表達式 if( 10 ) 的真值始終為 1。 */
printf( "Correct !\n" ) ; /* 實際上程序的本意是:如果輸入的數值等於 10,則輸出:Correct ! */
else /* 如果輸入的數值不等於 10 的話,則輸出:Error ! */
printf( "Error !\n" ) ;
}
(3)、在(1)和(2)的基礎上進行中間代碼生成(例如:在linux 系統下面生成的 *.o 文件、或者是在 WINDOWS 系統下面生成的 *.obj 文件),這類文件還不是最終的可執行文件。
在此過程中,會應用到各種符號表,以便處理用戶程序中使用的各種常量、變數、以及各種函數,等等。
(4)、在前三個階段的基礎上,最終 VS 編譯器再將中間代碼(*.obj 文件)和其本身提供的庫文件(*.LIB)進行鏈接,最終產生可執行程序(Linux 系統使用的編譯器是:gcc,Linux 系統下面的可執行文件名可以任意,WINDOWS 系統下面的可執行文件名為:*.EXE 文件)。
到此為止,一個用戶編寫的源程序,經過上面若干步驟之後,最終產生了可執行程序,此時就可以在機器上的相應的操作系統上執行了。

㈤ C語言編譯原理是什麼

編譯共分為四個階段:預處理階段、編譯階段、匯編階段、鏈接階段。
1、預處理階段:
主要工作是將頭文件插入到所寫的代碼中,生成擴展名為「.i」的文件替換原來的擴展名為「.c」的文件,但是原來的文件仍然保留,只是執行過程中的實際文件發生了改變。(這里所說的替換並不是指原來的文件被刪除)
2、匯編階段:
插入匯編語言程序,將代碼翻譯成匯編語言。編譯器首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤後,編譯器把代碼翻譯成匯編語言,同時將擴展名為「.i」的文件翻譯成擴展名為「.s」的文件。
3、編譯階段:
將匯編語言翻譯成機器語言指令,並將指令打包封存成可重定位目標程序的格式,將擴展名為「.s」的文件翻譯成擴展名為「.o」的二進制文件。
4、鏈接階段:
在示例代碼中,改代碼文件調用了標准庫中printf函數。而printf函數的實際存儲位置是一個單獨編譯的目標文件(編譯的結果也是擴展名為「.o」的文件),所以此時主函數調用的時候,需要將該文件(即printf函數所在的編譯文件)與hello
world文件整合到一起,此時鏈接器就可以大顯神通了,將兩個文件合並後生成一個可執行目標文件。

㈥ 編譯原理課程講什麼內容

編譯原理是計算機專業的一門重要專業課,旨在介紹編譯程序構造的一般原理和基本方法。內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、代碼優化和目標代碼生成。 編譯原理是計算機專業設置的一門重要的專業課程。雖然只有少數人從事編譯方面的工作,但是這門課在理論、技術、方法上都對學生提供了系統而有效的訓練,有利於提高軟體人員的素質和能力。

㈦ 程序編譯連接的過程中各幹了什麼事情

呵呵,樓主應該看看《編譯原理》。

我的空間里的一篇日誌或許對樓主也有幫助。

鏈接是把程序代碼與所需要的其他目標代碼,或函數庫,Run-time 庫連接在一起。

比如 printf,程序代碼里沒有它內部實現的代碼,只是說要調用這個功能。
連接程序會把它內部實現代碼從 Run-time 庫里提出來,放在一起,這樣程序才可以單獨執行。

對於使用了第三方函數庫的代碼來說,鏈接程序同樣會在第三方函數庫中提取相關內容,加在一個可執行文件(Exe 或其他)中。

另外,一些比較大的程序,可能會分若干個文件,它們互相調用彼此的函數。可以獨立編譯成若干個目標代碼。如果這些函數有的缺失了,編譯也可以通過。
這樣做的好處是,對於大型程序,分成若幹部分分別編譯,加快了編譯過程。同時,減少每個源碼文件的行數。
比如,寫一個計算程序。後台計算有一個文件,可以編譯成功。前台界面有一個文件,也可以編譯成功。它們分辨編譯成兩個不同的目標代碼文件(obj 或其他)

然後經過鏈接過程
這個例子的話,可以認為有這個式子:
前台.obj + 後台.obj + .... + 第三方函數庫 + Run-time 庫 = Exe

鏈接的時候,才會檢查這種相互依賴是否完整。
比如前台部分是否使用了有些函數,而這些函數在後台處理模塊中並不存在?或者忘記寫這個函數了?
或者是否調用了一個後台函數,而這個函數的參數與調用的時候根本不一致?
發生這些情況時,才會給出鏈接警告和錯誤。

㈧ 編譯原理 什麼是靜態鏈

1、路由器的工作原理
路由工作簡單原理圖
在這里插入圖片描述
1)主機1.1要發生數據包給主機4.1.因為IP地址不在同一網段,所以主機會將數據包發送給本網段的網關路由器。
2)路由器A 接收到數據包,先查看數據包IP首部中的目標IP地址。再查找自己的路由表。數據包的目標IP地址是4.1.屬於4.0網段,路由器A 在路由表中查到4.0網段轉發的介面是S0介面,於是路由器A將數據從S0介面轉發出去。
3)網路中的每個路由器都是按照這樣的步驟轉發數據的,直到到達路由器B,再用同樣的方法從E0介面轉發出去,最後主機4.1接收到這個數據包。
2、路由表
(1)概念
路由器中維護的路由條目的集合。
路由器根據路由表做的路徑選擇。
(2)路由表的形成
1)直連網段
配置IP地址,埠UP 狀態,形成直連路由。
2)非直連網段
需要靜態路由或動態路由,將網段添加到路由表中。
3、靜態路由
由管理員手工配置的,是單向的。缺乏靈活性。
管理員可以通過靜態路由來控制數據包在網路中的流動。
4、默認路由
一種特殊的靜態路由,當路由器在路由表中找不到目標網路的路由條目時,路由器把請求轉發到默認路由介面。
當默認路由存在末梢網路時,默認路由會大大簡化路由器的配置。
5、路由器轉發數據包的分裝過程
HostA向HostB發送數據
在這里插入圖片描述
1)HostA在網路層將上層的報文封裝成IP數據包,其首部包含源地址和目的地址。源地址即本機IP地址192.168.1.2,目的地在為HostB的IP地址192.168.2.2,HostA使用本機配置的24位掩碼於目的地址進行「與」運算,得出目的地在與本機地址不在同一網段,因此發往HostB的數據包需要經過網關路由器A轉發。
2)HostA通過ARP請求獲得默認網關路由器A 的E0介面MAC 地址00-11-12-21-22-22.在數據鏈路層HostA將IP數據包封裝成乙太網數據幀,在乙太網首部的源MAC地址為00-11-12-21-11-11,目的MAC地址為網關E0介面的MAC地址00-11-12-21-22-22
3)路由器A從E0介面接收到數據幀,把數據鏈路層的封裝去掉。路由器A認為這個IP數據包是要通過自己進行路由轉發,所以路由器A會自己查找自己的路由表,尋找與目標IP地址192.168.2.2相匹配的路由表項,然後根據路由表的下一跳地址將數據包轉發到E1介面。
4)在E1介面路由器A 重新封裝乙太網幀,此時源MAC地址為路由器A的E1介面MAC地址00-11-12-21-33-33,目的MAC地址為與之相連的路由器B的E1介面MAC地址00-11-12-21-44-44
5)路由器B從E1介面接收到數據幀,同樣會吧數據鏈路層的封裝去掉。對目的IP地址進行檢查,並與路由表進行匹配,然後根據路由表的下一跳信息將數據包轉發到E0介面。路由器B發現目的網段與自己的E0介面相連,通過ARP廣播,路由器B獲得HostB以太口的MAC地址00-11-12-21-66-66.路由器B在將IP數據包封裝成乙太網幀,源MAC地址為路由器B的E0介面的MAC地址00-11-12-21-55-55,目的MAC地址為HostB的MAC地址00-11-12-21-66-66.封裝完畢,將乙太網幀從E0介面發往HostB.

㈨ 編譯原理

C語言編譯過程詳解
C語言的編譯鏈接過程是要把我們編寫的一個C程序(源代碼)轉換成可以在硬體上運行的程序(可執行代碼),需要進行編譯和鏈接。編譯就是把文本形式源代碼翻譯為機器語言形式的目標文件的過程。鏈接是把目標文件、操作系統的啟動代碼和用到的庫文件進行組織形成最終生成可執行代碼的過程。過程圖解如下:

從圖上可以看到,整個代碼的編譯過程分為編譯和鏈接兩個過程,編譯對應圖中的大括弧括起的部分,其餘則為鏈接過程。
一、編譯過程
編譯過程又可以分成兩個階段:編譯和匯編。
1、編譯
編譯是讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,源文件的編譯過程包含兩個主要階段:
第一個階段是預處理階段,在正式的編譯階段之前進行。預處理階段將根據已放置在文件中的預處理指令來修改源文件的內容。如#include指令就是一個預處理指令,它把頭文件的內容添加到.cpp文件中。這個在編譯之前修改源文件的方式提供了很大的靈活性,以適應不同的計算機和操作系統環境的限制。一個環境需要的代碼跟另一個環境所需的代碼可能有所不同,因為可用的硬體或操作系統是不同的。在許多情況下,可以把用於不同環境的代碼放在同一個文件中,再在預處理階段修改代碼,使之適應當前的環境。
主要是以下幾方面的處理:
(1)宏定義指令,如 #define a b。
對於這種偽指令,預編譯所要做的是將程序中的所有a用b替換,但作為字元串常量的 a則不被替換。還有 #undef,則將取消對某個宏的定義,使以後該串的出現不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif等。
這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉
(3) 頭文件包含指令,如#include "FileName"或者#include <FileName>等。
在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字元常量),同時包含有各種外部符號的聲明。採用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復一遍。預編譯程序將把頭文件中的定義統統都加入到它所產生的輸出文件中,以供編譯程序對之進行處理。包含到C源程序中的頭文件可以是系統提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括弧(<>)。另外開發人員也可以定義自己的頭文件,這些文件一般與C源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預編譯程序可以識別一些特殊的符號。
例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對於在源程序中出現的這些串將用合適的值進行替換。
預編譯程序所完成的基本上是對源程序的「替代」工作。經過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經過預處理的源文件是相同的,但內容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。
第二個階段編譯、優化階段。經過預編譯得到的輸出文件中,只有常量;如數字、字元串、變數的定義,以及C語言的關鍵字,如main,if,else,for,while,{,}, +,-,*,\等等。
編譯程序所要作得工作就是通過詞法分析和語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中間代碼表示或匯編代碼。
優化處理是編譯系統中一項比較艱深的技術。它涉及到的問題不僅同編譯技術本身有關,而且同機器的硬體環境也有很大的關系。優化一部分是對中間代碼的優化。這種優化不依賴於具體的計算機。另一種優化則主要針對目標代碼的生成而進行的。
對於前一種優化,主要的工作是刪除公共表達式、循環優化(代碼外提、強度削弱、變換循環控制條件、已知量的合並等)、復寫傳播,以及無用賦值的刪除,等等。
後一種類型的優化同機器的硬體結構密切相關,最主要的是考慮是如何充分利用機器的各個硬體寄存器存放的有關變數的值,以減少對於內存的訪問次數。另外,如何根據機器硬體執行指令的特點(如流水線、RISC、CISC、VLIW等)而對指令進行一些調整使目標代碼比較短,執行的效率比較高,也是一個重要的研究課題。
2、匯編
匯編實際上指把匯編語言代碼翻譯成目標機器指令的過程。對於被翻譯系統處理的每一個C語言源程序,都將最終經過這一處理而得到相應的目標文件。目標文件中所存放的也就是與源程序等效的目標的機器語言代碼。目標文件由段組成。通常一個目標文件中至少有兩個段:
代碼段:該段中所包含的主要是程序的指令。該段一般是可讀和可執行的,但一般卻不可寫。
數據段:主要存放程序中要用到的各種全局變數或靜態的數據。一般數據段都是可讀,可寫,可執行的。
UNIX環境下主要有三種類型的目標文件:
(1)可重定位文件
其中包含有適合於其它目標文件鏈接來創建一個可執行的或者共享的目標文件的代碼和數據。
(2)共享的目標文件
這種文件存放了適合於在兩種上下文里鏈接的代碼和數據。
第一種是鏈接程序可把它與其它可重定位文件及共享的目標文件一起處理來創建另一個 目標文件;
第二種是動態鏈接程序將它與另一個可執行文件及其它的共享目標文件結合到一起,創建一個進程映象。
(3)可執行文件
它包含了一個可以被操作系統創建一個進程來執行之的文件。匯編程序生成的實際上是第一種類型的目標文件。對於後兩種還需要其他的一些處理方能得到,這個就是鏈接程序的工作了。
二、鏈接過程
由匯編程序生成的目標文件並不能立即就被執行,其中可能還有許多沒有解決的問題。
例如,某個源文件中的函數可能引用了另一個源文件中定義的某個符號(如變數或者函數調用等);在程序中可能調用了某個庫文件中的函數,等等。所有的這些問題,都需要經鏈接程序的處理方能得以解決。
鏈接程序的主要工作就是將有關的目標文件彼此相連接,也即將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠被操作系統裝入執行的統一整體。
根據開發人員指定的同庫函數的鏈接方式的不同,鏈接處理可分為兩種:
(1)靜態鏈接
在這種鏈接方式下,函數的代碼將從其所在地靜態鏈接庫中被拷貝到最終的可執行程序中。這樣該程序在被執行時這些代碼將被裝入到該進程的虛擬地址空間中。靜態鏈接庫實際上是一個目標文件的集合,其中的每個文件含有庫中的一個或者一組相關函數的代碼。
(2) 動態鏈接
在此種方式下,函數的代碼被放到稱作是動態鏈接庫或共享對象的某個目標文件中。鏈接程序此時所作的只是在最終的可執行程序中記錄下共享對象的名字以及其它少量的登記信息。在此可執行文件被執行時,動態鏈接庫的全部內容將被映射到運行時相應進程的虛地址空間。動態鏈接程序將根據可執行程序中記錄的信息找到相應的函數代碼。
對於可執行文件中的函數調用,可分別採用動態鏈接或靜態鏈接的方法。使用動態鏈接能夠使最終的可執行文件比較短小,並且當共享對象被多個進程使用時能節約一些內存,因為在內存中只需要保存一份此共享對象的代碼。但並不是使用動態鏈接就一定比使用靜態鏈接要優越。在某些情況下動態鏈接可能帶來一些性能上損害。
我們在linux使用的gcc編譯器便是把以上的幾個過程進行捆綁,使用戶只使用一次命令就把編譯工作完成,這的確方便了編譯工作,但對於初學者了解編譯過程就很不利了,下圖便是gcc代理的編譯過程:

從上圖可以看到:
預編譯
將.c 文件轉化成 .i文件
使用的gcc命令是:gcc –E
對應於預處理命令cpp
編譯
將.c/.h文件轉換成.s文件
使用的gcc命令是:gcc –S
對應於編譯命令 cc –S
匯編
將.s 文件轉化成 .o文件
使用的gcc 命令是:gcc –c
對應於匯編命令是 as
鏈接
將.o文件轉化成可執行程序
使用的gcc 命令是: gcc
對應於鏈接命令是 ld
總結起來編譯過程就上面的四個過程:預編譯、編譯、匯編、鏈接。了解這四個過程中所做的工作,對我們理解頭文件、庫等的工作過程是有幫助的,而且清楚的了解編譯鏈接過程還對我們在編程時定位錯誤,以及編程時盡量調動編譯器的檢測錯誤會有很大的幫助的。

閱讀全文

與編譯原理講不講鏈接相關的資料

熱點內容
ipad怎麼把app資源庫關了 瀏覽:301
量柱比前一天多源碼 瀏覽:416
電子書app怎麼上傳 瀏覽:66
國家反詐中心app注冊怎麼開啟 瀏覽:804
全波差分傅里葉演算法窗長 瀏覽:41
程序員如何講自己做過的項目 瀏覽:7
程序員要看的書頸椎 瀏覽:946
php文章cms 瀏覽:553
CSS權威指南第三版PDF 瀏覽:496
android怎麼搭建框架 瀏覽:184
正宗溯源碼大燕條一克一般多少錢 瀏覽:917
電腦感染exe文件夾 瀏覽:916
wpsppt怎麼轉pdf格式 瀏覽:88
騰訊文檔在線編輯怎麼添加密碼 瀏覽:880
本地不能訪問伺服器地址 瀏覽:865
訪問伺服器命令 瀏覽:835
華為雲伺服器分銷商 瀏覽:954
Linux定位內存泄露 瀏覽:198
工程加密狗視頻 瀏覽:720
不在內網怎麼連接伺服器 瀏覽:664