国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

C語言進階:程序預處理

gxyz / 1813人閱讀

摘要:程序預處理本章節研究的是,源代碼文件是如何一步步得到一個可執行程序的。如的語句被稱為預處理指令,還有注釋文本的刪除,都在此階段完成替換。目的是能夠將所有文件中的代碼組合到一起成一個完整的程序。終止程序可以正常也可以意外終止程序。

程序預處理

本章節研究的是,源代碼文件test.c是如何一步步得到一個可執行程序test.exe的。在之前的學習中可知.c文件要先后經過編譯鏈接成.exe文件再執行。

程序的編譯鏈接運行如下圖所示。翻譯中編譯又包括預編譯、編譯、匯編。

編譯鏈接執行三個步驟,都需要為其配置不同的環境。編譯和鏈接在翻譯環境中,而執行在運行環境中發生。

  • 翻譯環境:在該環境中源代碼被轉換成可執行的機器指令。
  • 執行環境:用于實際執行代碼。

程序的翻譯環境

翻譯階段的大致流程如下圖所示。

組成一個程序的每個.c源文件都會被編譯器編譯,分別生成對應的.obj目標文件。多個目標文件以及引入的鏈接庫被鏈接器鏈接在一起,形成一個單一的.exe可執行程序。

編譯器即是一個用于編譯代碼的工具,在vs環境下為cl.exe的可執行程序。連接器則是用于鏈接所有目標文件的工具,在vs中為link.exe的可執行程序,鏈接庫是標準中任何被該程序用到的函數。如圖:

而若想觀察翻譯代碼過程中的每一個流程的具體細節,在集成開發環境vs中不便展示,當然我們可以使用Linux環境下的gcc編譯器。

此次演示就采用加法函數,分別存放在兩個文件test.cadd.c。

//1. add.cint Add(int x, int y){	int sum = x + y;	return sum;}//2. test.c#include  //聲明函數extern int Add(int x, int y);int main(){	int a = 10;	int b = 20;	int ret = 0;	ret = Add(a, b);	printf("ret = %d/n", ret);	return 0;}
預編譯

Linux環境下編寫完test.c文件的代碼后,輸入gcc test.c -E可以將代碼預編譯的結果輸出到屏幕上。還可以用gcc test.c -E -o test.i是將結果輸出到文件test.i。

#include,#define,#pragma的語句被稱為預處理指令,還有注釋文本的刪除,都在此階段完成替換。

所有可以看出預編譯階段的動作都是文本操作

  1. #include頭文件的包含
  2. #define預處理符號的替換
  3. 刪除注釋

預編譯,顧名思義,是在編譯前刪減代碼中的不必要的與機器識別代碼無關的內容。被稱為文本操作。

編譯

對預編譯產生的文件test.i再編譯gcc test.i -S,會自動生成匯編代碼test.s。

故編譯階段是將C語言代碼轉化為匯編代碼,這是整體現象。實際上會發生這四個動作:

  1. 詞法分析,語法分析,語義分析

詞法分析,語法分析,語義分析都是編譯器識別語句的操作。重點是接下接下來的符號匯總。

  1. 符號匯總

符號匯總,是只對全局符號進行匯總,局部符號是不進行匯總的。目的是能夠將所有文件中的代碼組合到一起成一個完整的程序。如add.c文件中的函數名Add,還有test.c文件中的Addmain。

匯編

gcc test.s -C將編譯結束產生的匯編代碼轉化成了二進制指令(機器指令)存入二進制文件test.o中。

匯編階段會形成符號表,因為機器在調用指令時需要知道其存放的位置,所謂符號表大概就是符號和其地址的集合。如圖,可以假設:

鏈接

鏈接將二進制指令目標文件test.o等,鏈接在一起形成可執行程序test.out。目標文件test.oelf格式文件,在Linux平臺下可以用readelf翻譯并查看其內容。

鏈接階段的動作是:

  1. 合并段表

所謂的鏈接,就是將對應的段合并起來。

  1. 符號表的合并和重定位

符號表的合并,是將各自的符號表合并到一起。如test.o中的Add的無效地址,需把add.oAdd的地址合并過去再重定位到變量的真實地址,才是有意義的。

從編譯期間的符號匯總,到匯編時的形成符號表,再到鏈接時的合并和重定位符號表,都是為了最后生成可執行程序時能夠找到并鏈接各個文件中的符號。

程序的執行環境

  1. 程序首先載入內存

    有的機器上有操作系統,這個動作就是由操作系統完成,沒有的由手工完成。

  2. 執行調用main函數

  3. 創建函數棧幀

    程序使用一個運行時堆棧,存儲函數的局部變量和返回地址。

  4. 終止程序

    可以正常也可以意外終止程序。

程序的執行并不是本章的要點,所以就大概介紹一下。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/122008.html

相關文章

  • 只看不敲,神也學不好C---------計算機經典書籍經驗分享

    摘要:學單片機多去官網上查資料,下載手冊,像我入門的單片機經常去官網,還有學的系列板子,公司的官網的官方例程給的很詳細,在英文視角閱讀對你大有益處。 目錄 1.C語言經典 2.單片機系列 3.Python方面 4.嵌入式LWip協議 5.Android 6.C++經典書籍 7.Linux開發 ...

    FleyX 評論0 收藏0
  • C語言進階第一問:數據在內存中是如何存儲的?(手把手帶你深度剖析數據在內卒中的存儲,超全解析,碼住不

    摘要:在符號位中,表示正,表示負。我們知道對于整型來說,內存中存放的是該數的補碼。在計算機系統中,數值一律用補碼來表示和存儲。表示有效數字,。規定對于位的浮點數,最高的位是 ...

    ghnor 評論0 收藏0
  • C語言進階程序處理

    摘要:如的語句被稱為預處理指令,還有注釋文本的刪除,都在此階段完成替換。故宏在程序規模和執行速度方面更勝一籌。宏替換發生在預編譯期間,故無法調試。宏可能由于運算符優先級的問題,會導致程序出錯。 ...

    binta 評論0 收藏0
  • C語言進階】??數據類型&&整型在內存中的存儲

    目錄 ? ?一、數據類型介紹 二、類型的意義 三、類型的基本歸類 整型家族 浮點數家族 構造類型(自定義類型) 指針類型 空類型 四、整形在內存中的存儲 原碼、反碼、補碼 大小端字節序 為什么有大端和小端? 一道經典筆試題 ?一、數據類型介紹 數據從大的方向分為兩類: 內置類型自定義類型內置類型我們前面已經學習過,如下: char? ? ? ? ? ? //字符數據類型 short? ? ? ...

    Xufc 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<