當前位置:首頁 » 編程軟體 » 編譯程序框架圖

編譯程序框架圖

發布時間: 2025-05-24 15:30:05

編譯程序有哪些主要構成成分它們各自的主要功能是什麼

編譯過程分為分析和綜合兩個部分,並進一步劃分為詞法分析、語法分析、語義分析、代碼優化、存儲分配和代碼生成等六個相繼的邏輯步驟。這六個步驟只表示編譯程序各部分之間的邏輯聯系,而不是時間關系。

編譯過程既可以按照這六個邏輯步驟順序地執行,也可以按照平行互鎖方式去執行。在確定編譯程序的具體結構時,常常分若干遍實現。對於源程序或中間語言程序,從頭到尾掃視一次並實現所規定的工作稱作一遍。每一遍可以完成一個或相連幾個邏輯步驟的工作。

例如,可以把詞法分析作為第一遍;語法分析和語義分析作為第二遍;代碼優化和存儲分配作為第三遍;代碼生成作為第四遍。

反之,為了適應較小的存儲空間或提高目標程序質量,也可以把一個邏輯步驟的工作分為幾遍去執行。例如,代碼優化可劃分為代碼優化准備工作和實際代碼優化兩遍進行。

(1)編譯程序框架圖擴展閱讀

從左至右逐個字元地對源程序進行掃描,產生一個個的單詞符號,把作為字元串的源程序改造成為單詞符號串的中間程序。執行詞法分析的程序稱為詞法分析程序或掃描器。

源程序中的單詞符號經掃描器分析,一般產生二元式:單詞種別;單詞自身的值。單詞種別通常用整數編碼,如果一個種別只含一個單詞符號,那麼對這個單詞符號,種別編碼就完全代表它自身的值了。若一個種別含有許多個單詞符號,那麼,對於它的每個單詞符號,除了給出種別編碼以外,還應給出自身的值。

詞法分析器一般來說有兩種方法構造:手工構造和自動生成。手工構造可使用狀態圖進行工作,自動生成使用確定的有限自動機來實現。

編譯程序的語法分析器以單詞符號作為輸入,分析單詞符號串是否形成符合語法規則的語法單位,如表達式、賦值、循環等,最後看是否構成一個符合要求的程序,按該語言使用的語法規則分析檢查每條語句是否有正確的邏輯結構,程序是最終的一個語法單位。編譯程序的語法規則可用上下文無關文法來刻畫。

Ⅱ 高級語言程序有兩種工作方式編譯方式和解釋方式

具體如下。
編譯型工作過程圖,編譯程序功能就是把高級語言書寫的源代碼譯成與之等價的目標程序(匯編語言或機器語言)。解釋型,解釋程序實現高級語言的三種方式解釋型在詞法、語法和語義分析方面與編譯程序的工作原理基本相同,但在運行時直接執行源程序或源程序的內部形式,即解釋程序不產生源程序的目標程序,解釋程序通常可以分為兩部分:第一部分是分析部分,經語義分析後把源程序翻譯成中間代碼,中間代碼常用逆波蘭式表示。第二部分是解釋部分。
高級語言(High-levelprogramminglanguage)是一種獨立於機器,面向過程或對象的語言。高級語言是參照數學語言而設計的近似於日常會話的語言。例如,要將2個變數相加並賦值給第三個變數,用高級語言表達為var3=var1+var2。

Ⅲ tc 編譯、連接和生成程序分別叫什麼名字求助高手!!!!!

何編譯、調試和運行源程序。並給出Turbo C的常用編輯命令。最後介紹Turbo C編譯、連接和運行時的常見錯誤。

一、Turbo C程序設計基本步驟
程序設計方法包括三個基本步驟:
第一步: 分析問題。
第二步: 畫出程序的基本輪廓。
第三步: 實現該程序。
3a. 編寫程序
3b. 測試和調試程序
3c. 提供數據列印結果
下面, 我們來說明每一步的具體細節。
第一步: 分析問題
在這一步, 你必須:
a. 作為解決問題的一種方法, 確定要產生的數據(輸出)。作為這一子步的一部分, 你應定義表示輸出的變數。
b. 確定需產生輸出的數據(稱為輸入), 作為這一子步的一部分, 你應定義表示輸入的變數。
c. 研製一種演算法, 從有限步的輸入中獲取輸出。 這種演算法定義為結構化的順序操作, 以便在有限步內解決問題。就數字問題而言, 這種演算法包括獲取輸出的計算, 但對非數字問題來說, 這種演算法包括許多文本和圖象處理作。

第二步: 畫出程序的基本輪廓
在這一步, 你要用一些句子(偽代碼)來畫出程序的基本輪廓。每個句子對應一個簡單的程序操作。對一個簡單的程序來說, 通過列出程序順序執行的動作,便可直接產生偽代碼。然而, 對復雜一些的程序來說, 則需要將大致過程有條理地進行組織。對此, 應使用自上而下的設計方法。
當使用自上而下的設計方法時, 你要把程序分割成幾段來完成。列出每段要實現的任務, 程序的輪廓也就有了, 這稱之為主模塊。當一項任務列在主模塊時,僅用其名加以標識, 並未指出該任務將如何完成。這方面的內容留給程序設計的下一階段來討論。將程序分為幾項任務只是對程序的初步設計。整個程序設計歸結為下圖所示的流程圖1.。
┏━━━━━━━━━━━━━━━┓
┃ 主模塊 ┃
┏━━━━━━━┓ ┃ 輸入數據 ┃
┃ 主模塊 ┃ ┃ 計算購房所需的金額 ┃
┃ ┃ ┃ 計算裝修所需的金額 ┃
┃ 任務1 ┃ ┃ 計算總金額 ┃
┃ 任務2 ┃ ┃ 輸出計算結果 ┃
┃ 任務3 ┃ ┃ ┃
┃ 任務4 ┃ ┗━━━━━━━┳━━━━━━━┛
┃ ┃ ┏━━━━━┳━━━━━╋━━━━┳━━━━━┓
┃ ┃ ┏━━┻━┓┏━━┻━┓┏━━┻━┓┏━┻━┓┏━━┻━┓
┗━━━━━━━┛ ┃輸入數據┃┃購房額..┃┃裝修額..┃┃總額..┃┃輸出結果┃
┗━━━━┛┗━━━━┛┗━━━━┛┗━━━┛┗━━━━┛
圖1. 程序初步設計 圖2. 第二級程序設計

如果把主模塊的每項任務擴展成一個模塊, 並根據子任務進行定義的話, 那麼, 程序設計就更為詳細了(見圖2.)。這些模塊稱為主模塊的子模塊。程序中許多子模塊之間的關系可象圖2.中那樣歸結為一張圖。這種圖稱為結構圖。
要畫出模塊的輪廓, 你可不考慮細節。如果這樣的話, 你必須使用子模塊,將各個模塊求精, 達到第三級設計。繼續這一過程, 直至說明程序的全部細節。
這一級一級的設計過程稱為逐步求精法。在編寫程序之前, 對你的程序進行逐步求精, 對你來說, 是很好的程序設計實踐, 會使你養成良好的設計習慣。
我們則才描述了程序設計中自上而下的設計方法。實際上就是說, 我們設計程序是從程序的"頂部"開始一直考慮到程序的"底部"。

第三步: 實現該程序
程序設計的最後一步是編寫源碼程序。 在這一步, 把模塊的偽代碼翻譯成Turbo C語句。
對於源程序, 你應包含注釋方式的文件編制, 以描述程序各個部分做何種工作。此外, 源程序還應包含調試程序段, 以測試程序的運行情況, 並允許查找編程錯誤。一旦程序運行情況良好, 可去掉調試程序段, 然而, 文件編制應做為源程序的固定部分保留下來, 便於你或其他人維護和修改。
二、源程序的輸入、編譯和運行

C語言是一種中級語言, 用戶用C語言編寫的程序稱為源程序, 存放用C 語言所寫源程序文件名字最後的兩個字元一般必須為".c"。計算機硬體不能直接執行源程序, 必須將源程序翻譯成二進制目標程序。翻譯工作是由一個程序完成的,這個程序稱為編譯程序, 翻譯的過程稱為編譯, 編譯的結果稱為目標程序, 存放目標程序文件名字緊後的字元一般為".OBJ"或".O"。程序翻譯成目標程序後, 便可進行連接。"連接"的目的是使程序變成在計算機上可以執行的最終形式。在這一階段, 從系統程序庫來的程序要與目標程序連接, 連接的結果稱為執行程序,存放執行程序文件名字一般以".EXE"結尾。
在Turbo C集成開發環境中建立一個新程序通常有以下幾個步驟:
(1). 在編輯器中編寫源文件。
(2). 生成可執行文件。

在DOS提示符下鍵入TC, 即可進入Turbo C了。進入主TC屏後, 按F3鍵, 即可在隨之出現的框中輸入文件名, 文件名可以帶".C"也可以不帶( 此時系統會自動加上)。輸入文件名後, 按回車, 即可將文件調入, 如果文件不存在, 就建立一個新文件(也可用下面例子中的方法輸入文件名)。系統隨之進入編輯狀態。就可以輸入或修改源程序了, 源程序輸入或修改完畢以後, 按Ctrl+F9(同時按下Ctrl鍵和F9鍵), 則立即進行編譯、連接和執行, 這三項工作是連續完成的。
下面我們試著建立一個Turbo C名為"HELLO.C"的源程序(因程序很小, 這里就不畫出該程序的輪廓圖了):
1. 操作步驟:
(1). 將系統置於DOS提示符下:
(2). 鍵入命令:
tc hello.c
使系統進入Turbo C集成開發環境, 並建立一個名為HELLO.C的文件。這時, 系統進入Turbo C編輯環境。
(3). 通過鍵盤輸入程序, 例如:
main()
{
printf("Hello, world\n");
}
則程序進入計算機存貯器。
2. 程序存檔
為防止意外事故丟失程序, 最好將輸入的程序存貯到磁碟中。在編輯窗口下,可直接按F2鍵或按F10鍵, 再按F鍵進入File菜單項, 再按S或W鍵將文件存檔。存檔時屏幕最底行會顯示:
"saving edit file"
3. 編譯一個程序
對源程序進行編譯有兩種方法: (1). 直接按Alt+F9即可。(2). 按F10 鍵返回主菜單, 選擇Compile項, 屏幕顯示Compile 下拉菜單, 從下拉菜單中選擇Compile to .OBJ項, 按回車鍵。
進入編譯狀態後, 屏幕會出現一個編譯窗口, 幾秒鍾後, 屏幕顯示一閃爍信息:
Success: press any key
表示編譯成功。此時可按任意鍵, 編譯窗口消失, 游標返回主菜單。
如果編譯時產生警告Warning或出錯Error信息, 這些具體錯誤信息會顯示在屏幕下部的信息窗中, 必須糾正這些錯誤。對源程序進行修改, 重新進行編譯。
4. 運行程序
源程序經編譯無誤後, 可以投入運行。具體操作如下:
(1). 如果當前還在編輯狀態, 可按Alt+R, 再選擇RUN項即可。
(2). 按Ctrl+F9。
程序投入運行時, 屏幕會出現一個連接窗口, 顯示Turbo C 正在連接和程序所需的庫函數。連接完畢後, 會出現屏幕突然一閃, 後又回到TC主屏幕, 發生了什麼? 讓我們按Alt+F5看看, 此時屏幕被清除, 在頂部顯示"Hello, world"字樣。再按任意鍵, 即可又回到TC主屏幕。
5. 列磁碟文件目錄
現在請按Alt+X退出Turbo C, 返回DOS提示符, 鍵入dir hello.*, 回車, 則屏幕顯示:
HELLO C 42 1-09-93 10:18
HELLO OBJ 221 1-09-93 10:22
HELLO EXE 4486 1-09-93 10:25
...
第一個文件HELLO.C是源文件文本, 在DOS提示符下鍵入TYPE HELLO.C命令,可在屏幕上顯示該文件的內容。可看到該程序只有42個位元組。
第二個文件HELLO.OBJ是Turbo C編擇程序產生的二進制機器指令(目標碼),如果用DOS命令TYPE顯示該文件, 屏幕可能會出現混亂的信息。
第三個文件HELLO.EXE是Turbo C連接程序產生的實際可執行文件。在DOS 提示符下鍵入HELLO並按回車, 屏幕將顯示"Hello, world"。

Turbo C 常用的編輯命令
Turbo C編輯程序大約有50條命令, 用以移動游標, 按頁查看正文, 查找並替換字元串等。如下表所示。

表1. Turbo C編輯程序命令
━━━┳━━━━━━━━━┳━━━━━━━━━━━━━
類別 ┃ 功能 ┃ 默認鍵
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
┃ 字元左 ┃ Ctrl+S或Left
基 ┃ 字元右 ┃ Ctrl+D或Right
本 ┃ 字左 ┃ Ctrl+A
光 ┃ 字右 ┃ Ctrl+F
標 ┃ 上行 ┃ Ctrl+E或Up
移 ┃ 下行 ┃ Ctrl+X或Down
動 ┃ 上滾 ┃ Ctrl+W
命 ┃ 下滾 ┃ Ctrl+Z
令 ┃ 上一頁 ┃ Ctrl+R或PgUp
┃ 下一頁 ┃ Ctrl+C或PgDn
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
快 ┃ 行頭 ┃ Ctrl+QS或Home
速 ┃ 行尾 ┃ Ctrl+QD或End
光 ┃ 窗口頭 ┃ Ctrl+QE
標 ┃ 窗口底 ┃ Ctrl+QX
移 ┃ 文件頭 ┃ Ctrl+QR
動 ┃ 文件尾 ┃ Ctrl+QC
命 ┃ 塊頭 ┃ Ctrl+QB
令 ┃ 塊尾 ┃ Ctrl+QK
┃ 上次游標位置 ┃ Ctrl+QP
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
輸 ┃ 插入模式 ┃ Ctrl+V或Ins
入 ┃ 插入行 ┃ Ctrl+N
與 ┃ 刪除行 ┃ Ctrl+Y
刪 ┃ 刪除至行尾 ┃ Ctrl+QY
除 ┃ 刪除游標左邊字元┃ Ctrl+H或Backspace
命 ┃ 刪除游標處字元 ┃ Ctrl+G或Del
令 ┃ 刪除游標右邊字元┃ Ctrl+T
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
┃ 標記塊首 ┃ Ctrl+KB
┃ 標記塊尾 ┃ Ctrl+KK
┃ 標記單個字 ┃ Ctrl+KT
塊 ┃ 復制塊 ┃ Ctrl+KC
命 ┃ 刪除塊 ┃ Ctrl+KY
令 ┃ 塊取消 ┃ Ctrl+KH
┃ 塊移動 ┃ Ctrl+KV
┃ 讀塊 ┃ Ctrl+KR
┃ 寫塊 ┃ Ctrl+KW
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
┃ 異常結束操作 ┃ Ctrl+U或Ctrl+Break
┃ 製表 ┃ Ctrl+L或Tab
其 ┃ 自動縮進 ┃ Ctrl+OI
┃ 定界符配對 ┃ Ctrl+Q[或Ctrl+Q]
它 ┃ 查找 ┃ Ctrl+QF
┃ 查找並替換 ┃ Ctrl+QA
┃ 查找標記 ┃ Ctrl+QN
┃ 退出編輯 ┃ Ctrl+KQ
━━━┻━━━━━━━━━┻━━━━━━━━━━━━━

Turbo C 程序的調試

一個程序設計好了以後, 通常會有一些錯誤, 查找和修改程序中的錯誤是令人頭痛的事。Turbo C集成開發環境提供了一調試裝置, 使得這一個工作容易了許多, 程序調試達到了編譯和運行級。

一、TC消息窗口

使用TC最好的理由之一是它允許用戶修改語法錯誤(編譯時) 和評估編譯器給出的警告。TC將編譯器和連接器發出的消息收集到一緩沖區中, 然後在消息窗口中顯示, 這樣在訪問源代碼的同時, 還能一下看到這些消息。
現將上面的HELLO.C製造一點語法錯誤, 將第一行包含語句的#去掉, 再去掉第五行printf語句中的後引號。現在程序看上去是這樣的:
include <stdio.h>
main()
{
printf("Hello, world\n);
}
按CTRL+F9重新編譯之。編譯窗口將顯示有多少錯誤和警告: 應為兩個錯誤, 0個
警告。
當看見編譯窗口中的Press anykey提示時, 按空格鍵, 消息窗口立刻被激活,亮條出現在第一個錯誤或警告上, 這時編輯窗口中也會有一亮條--- 它標志著編譯器給出的錯誤或警告在源代碼中的相應位置。
這時可用游標鍵將消息窗口中的亮條上下移動, 注意到編輯窗口中的亮條也隨著跟蹤源代碼中錯誤發生的位置。如果將亮條置於"compile"上, 則編輯器顯示文件的最後位置。
如果消息窗口太長看不見, 可用左、右游標水平滾動消息, 為了一次能夠多看點信息, 可按F5放大消息窗口。放大後, 編輯窗口不可見了, 因此不進行錯誤跟蹤。現在, 保持分屏模式。
為了改正錯誤, 將消息窗口中的亮條置於第一個錯誤消息上, 回車, 游標移到編輯窗口中錯誤產生處, 注意, 編輯器狀態給出所選消息( 這在放大模式下是有用的)改正之。(將第一行拿走的#重新寫上)。
當不只一個錯誤時, 可用兩種方法來修改下一錯誤。
第一種方法和前面一樣, 按F6回到消息窗口選擇想修改的下一條消息。
第二種方法不用回到消息窗口, 只要按Alt+F8, 編譯器就會將游標移至消息窗口中列的下一個錯誤。按Alt+F7可移至前一個錯誤。
這兩種方法各有長短, 視情況而定。有時源代碼中一個愚蠢的錯誤把編譯弄糊塗了, 產生好多消息, 這時選擇修改第一條消息就使得其餘的一些錯誤消息沒有什麼意義了, 這種情況發生時, 使用方法一會方便些, 一修改完第一個錯誤之後回到消息窗口, 再滾動到下一個有意義的消息上, 選擇之。在別的情況下, 按Alt+F8會方便得多。
記住, Alt+F7和Alt+F8是熱鍵, TC中無論何時均起作用。因此在消息窗口中按Alt+F8得到的不是當前亮行消息, 而是下一個消息(按Enter選擇當前消息)。
但如果沒別的編譯消息, Alt+F8就不起作用了。
注: 可以如此法選擇連接消息, 但它們不跟蹤源文件。在修改語法錯誤的過程當中, 經常需要增加、刪除正文, 編輯器是記住的, 依然能正確定位錯誤位置。
沒有必要記住行號和增加、刪除的正文行。

二、Turbo C集成調試器

一旦修改好語法錯誤之後程序編譯就沒什麼問題了, 但還是可能不按要求運行, 因為可能有邏輯錯誤(運行錯誤)。這種錯誤跟蹤就無助於發現錯誤位置了。TC有一個集成調試器可以跟蹤運行錯誤。通過調試器可以運行, 在斷點處暫停,檢查變數的值, 甚至可以改變之, 以看程序會有什麼反應。
Turbo C集成調試器是源程序級的調試器, 即用同你編寫程序一樣的" 語言"來控制調試器。例如, 為了顯示數組中的一個元素的值, 可告訴調試器顯示這樣的表達式的值:
Ctrl+F4 Debug/Eavluate 計算表達式, 允許修改變數的值。
Debug/Find Function 查找函數定義, 顯示在編輯窗口中。 僅在調試時才有效。
Ctrl+F3 Debug/Call Stack 顯示調用棧, 可顯示任何函數的當前執行位置, 其方法是在調用棧中選擇相應的
函數名。僅在調試時有效。
Debug/Source Debugging 控制是否允許調試: 置為On時, 集成調
試器和單獨調試器均可用 ; 置為
Standalone時, 只能用單獨調試器
調試, 雖然還能在TC中運行; 置為
None時, 在.EXE文件不置調試信息,
兩種調試均不能調試。
Ctrl+F4 Break/Watch/Add Watch 增加一監視表達式。
Break/Watch/Delete Watch 刪除一監視表達式。
Break/Watch/Edit 編輯一監視表達式。
Break/Watch/Remove All 刪除所有監視表達式。
Watches
Ctrl+F8 Break/Watch/Toggle 設置或清除游標所在行的斷點。
Breakpoint
Break/Watch/Clear 刪除程序中所有斷點。
Breakpoint
Break/Watch/Next 顯示下一斷點
Breakpoint
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

表3. 調試器菜單命令及其熱鍵
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
熱鍵 菜單命令 功能
———————————————————————————————————
F5 在整屏和分屏之間放大縮小活動窗口。
Alt+F5 將顯示轉到用戶屏, 擊任意鍵返回。
F6 在編輯窗口與監視窗口或消息窗口間
切換。
Alt+F6 若編輯窗口是活動的, 轉到最近一次
裝入編輯器的文件; 若下面窗口是活
動的, 則在監視窗口和消息窗口間切換。
Ctrl+F9 Run/Run 調試運行或不調試運行程序, 必要時
編譯、連接源文件, 若編譯、 連接時
Debug/Source Debuging和O/C/C/OBJ
Debug Information為On, 則運行程序
到斷點或程序末尾。
Project/Remove Messages 刪除消息窗口中的內容。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

判斷程序是否出錯或者為什麼出錯是編程中最有挑戰意義的一方面。這里建義你進行預防性設計, 具體做法為:
(1). 將代碼寫清楚點, 應作適當縮進, 使用文字說明和描述性的變數名。
(2). 代碼應簡單, 把精力放在簡單語句中的復雜表達式, 而不是一些復雜語句。Turbo C的代碼優化機制將大大提高代碼的效率, 而且調試、閱讀、 修改
起來容易。
(3). 盡量用目的簡單、好定義的函數構建程序。 這會便於編制調試程序和分析結果, 而且閱讀、修改起來也要容易一些。
(4). 應盡量減少各個函數要求的數據和改變數據的元素個數。這也會便於編制測試程序和分析結果; 同樣便於閱讀、修改程序。並且還限制了出錯函數可能造成的巨大混亂的牽涉面, 便得能在一個調試節中多運行函數幾次。
(5). 要留心編寫程序中的公共函數, 或者說在其它程序中可再用的函數.編寫、調試一個一般性的函數通常要比編寫、調試兩個或更多的特殊函數要容易。

Turbo C編譯、連接和運行時的常見錯誤
一、編譯時的常見錯誤
1. 數據類型錯誤。此類錯誤是初學者編程時的常見現象, 下面是一些要引起注意的錯誤:
(1) 所有變數和常量必須要加以說明。
(2) 變數只能賦給相同類型的數據。
(3) 對scanf()語句, 用戶可能輸入錯誤類型的數據項, 這將導致運行時出錯, 並報出錯信息。為避免這樣的錯誤出現, 你就提示用戶輸入正確類型的數據。
(4) 在執行算術運算時要注意:
a. 根據語法規則書寫雙精度數字。要寫0.5, 而不是寫.5; 要寫1.0,
而不是1。盡管C語言會自動地把整型轉換成雙精度型, 但書寫雙精
度型是個好習慣。讓C語言為你做強行轉換這是一種效率不高的程序
設計風格。 這有可能導致轉換產生錯誤。
b. 不要用0除。這是一個災難性的錯誤, 它會導致程序失敗, 不管C
語言的什麼版本, 都是如此, 執行除法運算要特別小心。
c. 確保所有的雙精度數(包括那些程序輸入用的雙精度數) 是在實數
范圍之內。
d. 所有整數必須在整數允許的范圍內。這適用於所有計算結果,包括中間結果。

2. 將函數後面的";"忘掉。此時錯誤提示色棒將停在該語句下的一行, 並顯示:
Statement missing ; in function <函數名>

3. 給宏指令如#include, #define等語句尾加了";"號。

4. ""、"("和")"、"/*"和"*/"不匹配。 引時色棒將位於錯誤所在的行, 並提示出有關丟掉括弧的信息。

5. 沒有用#include指令說明頭文件, 錯誤信息提示有關該函數所使用的參數未定義。

6. 使用了Turbo C保留關鍵字作為標識符, 此時將提示定義了太多數據類型。

7. 將定義變數語句放在了執行語句後面。此時會提示語法錯誤。

8. 使用了未定義的變數, 此時屏幕顯示:
Undefined symbol '<變數名>' in function <函數名>

9. 警告錯誤太多。忽略這些警告錯誤並不影響程序的執行和結果。編譯時當警告錯誤數目大於某一規定值時(預設為100)便退出編譯器, 這時應改變集成開發環境Options/Compiler/Errors中的有關警告錯誤檢查開關為off。

10. 將關系符"=="誤用作賦值號"="。此時屏幕顯示:
Lvalue required in function <函數名>

二、連接時的常見錯誤

1. 將Turbo C庫函數名寫錯。這種情況下在連接時將會認為此函數是用戶自定義函數。此時屏幕顯示:
Undefined symbol '<函數名>' in <程序名>

2. 多個文件連接時, 沒有在"Project/Project name中指定項目文件 (.PRJ文件), 此時出現找不到函數的錯誤。

3. 子函數在說明和定義時類型不一致。
4. 程序調用的子函數沒有定義。

三、運行時的常見錯誤

1. 路徑名錯誤。在MS-DOS中, 斜杠(\)表示一個目錄名; 而在Turbo C 中斜杠是個某個字元串的一個轉義字元, 這樣, 在用Turbo C 字元串給出一個路徑名時應考慮"\"的轉義的作用。例如, 有這樣一條語句: file=fopen("c:\new\tbc.dat", "rb");
目的是打開C盤中NEW目錄中的TBC.DAT文件, 但做不到。這里"\"後面緊接的分別是"n"及"t", "\n"及"\t"將被分別編譯為換行及tab字元, DOS將認為它是不正確的文件名而拒絕接受, 因為文件名中不能和換行或tab字元。正確的寫法應為:
file=fopen("c:\\new\\tbc.dat", "rb");
2. 格式化輸入輸出時, 規定的類型與變數本身的類型不一致。例如:
float l;
printf("%c", l);
3. scanf()函數中將變數地址寫成變數。例如:
int l;
scanf("%d", l);
4. 循環語句中, 循環控制變數在每次循環未進行修改, 使循環成為無限循
環。
5. switch語句中沒有使用break語句。
6. 將賦值號"="誤用作關系符"=="。
7. 多層條件語句的if和else不配對。
8. 用動態內存分配函數malloc()或calloc()分配的內存區使用完之後, 未用free()函數釋放, 會導致函數前幾次調用正常, 而後面調用時發生死機現象,不能返回操作系統。其原因是因為沒用空間可供分配, 而佔用了操作系統在內存中的某些空間。
9. 使用了動態分配內存不成功的指針, 造成系統破壞。
10. 在對文件操作時, 沒有在使用完及時關閉打開的文件。

Ⅳ 編譯原理

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
總結起來編譯過程就上面的四個過程:預編譯、編譯、匯編、鏈接。了解這四個過程中所做的工作,對我們理解頭文件、庫等的工作過程是有幫助的,而且清楚的了解編譯鏈接過程還對我們在編程時定位錯誤,以及編程時盡量調動編譯器的檢測錯誤會有很大的幫助的。

Ⅳ 涓轟粈涔堢▼搴忚佸厛緙栬瘧錛屾墠鑳借繍琛屽晩錛

褰撶紪鍐欏畬涓涓紼嬪簭鍚庯紝闇瑕侀栧厛榪涜岀紪璇戱紝鐒跺悗鍐嶈繍琛屻

濡備笅鍥炬墍紺猴紝紼嬪簭緙栧啓瀹屾瘯鍚庯紝鐐瑰嚮宸ュ叿鏍忎腑鐨凟xecute,閫夋嫨compile(緙栬瘧錛

濡傛灉娌℃湁閿欒錛屽啀閫夋嫨Execute,閫夋嫨run錛堣繍琛)

鎵╁睍璧勬枡

緙栬瘧灝辨槸鎶婇珮綰ц璦鍙樻垚璁$畻鏈哄彲浠ヨ瘑鍒鐨2榪涘埗璇璦錛岃$畻鏈哄彧璁よ瘑1鍜0錛岀紪璇戠▼搴忔妸浜轟滑鐔熸倝鐨勮璦鎹㈡垚2榪涘埗鐨勩緙栬瘧紼嬪簭鎶婁竴涓婧愮▼搴忕炕璇戞垚鐩鏍囩▼搴忕殑宸ヤ綔榪囩▼鍒嗕負浜斾釜闃舵碉細璇嶆硶鍒嗘瀽錛涜娉曞垎鏋愶紱璇涔夋鏌ュ拰涓闂翠唬鐮佺敓鎴愶紱浠g爜浼樺寲錛涚洰鏍囦唬鐮佺敓鎴愩備富瑕佹槸榪涜岃瘝娉曞垎鏋愬拰璇娉曞垎鏋愶紝鍙堢О涓烘簮紼嬪簭鍒嗘瀽錛屽垎鏋愯繃紼嬩腑鍙戠幇鏈夎娉曢敊璇錛岀粰鍑烘彁紺轟俊鎮銆

緙栬瘧璇璦鏄涓縐嶄互緙栬瘧鍣ㄦ潵瀹炵幇鐨勭紪紼嬭璦銆傚畠涓嶅儚鐩磋瘧璇璦涓鏍鳳紝鐢辮В閲婂櫒灝嗕唬鐮佷竴鍙ヤ竴鍙ヨ繍琛岋紝鑰屾槸浠ョ紪璇戝櫒錛屽厛灝嗕唬鐮佺紪璇戜負鏈哄櫒鐮侊紝鍐嶅姞浠ヨ繍琛屻傜悊璁轟笂錛屼換浣曠紪紼嬭璦閮藉彲浠ユ槸緙栬瘧寮忥紝鎴栫洿璇戝紡鐨勩傚畠浠涔嬮棿鐨勫尯鍒錛屼粎涓庣▼搴忕殑搴旂敤鏈夊叧銆



熱點內容
c語言編譯壓縮解壓 發布:2025-05-24 22:38:17 瀏覽:577
網易版我的世界有哪些紅石伺服器 發布:2025-05-24 22:36:01 瀏覽:892
linux人 發布:2025-05-24 22:36:00 瀏覽:51
pdf的解壓碼有幾種 發布:2025-05-24 22:30:57 瀏覽:643
文件上傳加速 發布:2025-05-24 22:26:10 瀏覽:298
資料庫訪問頁 發布:2025-05-24 22:26:07 瀏覽:530
linux操作命令大全 發布:2025-05-24 22:26:05 瀏覽:351
排列5源碼 發布:2025-05-24 22:19:44 瀏覽:35
android字元串的截取字元串 發布:2025-05-24 22:17:37 瀏覽:82
我的世界伺服器op菜單怎麼做 發布:2025-05-24 22:07:38 瀏覽:852