Linux -- 認識gcc/g++、代碼的編譯過程

目錄

前言:

使用 gcc/g++:

代碼的編譯過程:?

預處理:

頭文件展開:

宏替換+去注釋:?

?編輯

條件編譯:?

編譯:

匯編:

鏈接:

動態庫(動態鏈接):

靜態庫(靜態鏈接):


前言:

我們寫完一段源代碼后,需要讓代碼跑起來,在Linux中,我們使用 gcc/g++來編譯C語言/C++代碼。

使用 gcc/g++:

我們現在新建了一個文件,且代碼如下:

?gcc? [ 源代碼文件名 ] 就可以對指定的代碼文件進行編譯,編譯時會生成一個可執行程序,如果沒有為可執行程序命名,默認文件名為 a.out,運行 a.out ,就會運行我們所寫的代碼!

我們也可以為可執行程序命名,gcc? [ 源代碼文件名 ] ?-o? ?[ 可執行程序文件名 ]

-o 后接目標文件

g++ 的使用方法和 gcc 相同,這里不再贅述。

需要區別的是,gcc只能編譯 C語言 ,g++可以編譯 C語言 和 C++!

代碼的編譯過程:?

預處理:

預處理時,會對代碼進行宏替換、去掉注釋、條件編譯、頭文件展開,如果想查看預處理后的代碼,以 gcc 為例:gcc? -E? test.c? -o? test.i ,就可以把預處理后的代碼存放到指定的文件中,注意,目標文件后綴為 .i 。

-E 表示從現在開始進行程序的預處理過程,當預處理工作結束后,就停下來,不再進行后續的工作!?

頭文件展開:

雖然我們原來的代碼只有15行,經過頭文件展開后,代碼行數已經達到851行!

宏替換+去注釋:?

如果代碼中有注釋和宏定義,預處理時,會進行宏替換和刪除注釋,通過下面的對比可以看出:?

條件編譯:?

由于宏定義時只定義了VERSION1,在條件編譯時,只有VERSION1的代碼保留下來,其余未定義的全部被動態裁剪了!若只定義了VERSION2,或者沒有宏定義,也同理!

可以看出,預處理時,可以對代碼進行編輯和裁剪。

我們也可以在預處理的指令中進行宏定義, 即使在源代碼中我們沒有定義 VERSION1,但我們在指令中定義了,效果和在源代碼中定義相同!

指令: gcc -E? test.c? -o? test.i? -D? VERSION1=1

條件編譯可以防止頭文件重復包含!頭文件重復包含,會導致頭文件展開時,代碼量太大,導致編譯效率低下!我們需要規避頭文件重復包含!這是個好的編程習慣。??

#ifndef _NAME_H
#define _NAME_H
//頭文件內容
#endif

這里的 _NAME_H 可以是自定義的宏,這里的宏應為獨一無二的,不可以與文件中的其他宏的名字相同!

# ifndef _NAME_H (if not define _NAME_H )

1、如果宏_NAME_H未定義,那么就會走 #define?_NAME_H 語句,定義宏 _NAME_H,并且引入頭文件

2、如果宏_NAME_H已經定義了,則不會走 #define?_NAME_H 語句,直接進入#endif,不引入頭文件

編譯:

編譯時,把代碼轉為匯編語言

-S:從現在開始進行程序的編譯,當編譯工作完成,就停下來!

形成匯編文件,可以直接在預處理的文件上進行編譯,也可以直接在源代碼上進行編譯,即兩種寫法:gcc? -S? test.c? -o? test.s? (在源代碼上)或?gcc? -S? test.i? -o? test.s(在預處理后的文件上)。

匯編:

匯編時,把編譯后生成的匯編語言轉為二進制語言

-c :從現在開始進行程序的匯編,匯編工作結束后,就停下來!

同樣可以在源代碼的基礎上進行匯編,也可以在編譯文件上進行匯編!?

?轉為二進制后,代碼還不可以運行起來,即使開放了可執行權限,也是運行不起來的!

還需要最后一步--鏈接!?

鏈接:

直接 gcc test.o? -o? test 就可以進行鏈接,所謂鏈接,就是把代碼和庫文件進行鏈接,默認與動態庫進行鏈接

?ldd 可以查看代碼和動態庫還是靜態庫產生鏈接

在 Linux 中,動態庫以 .so 結尾,靜態庫以 .a 結尾;

在Windows中,動態庫以 .dll 結尾,靜態庫以 .lib 結尾。?

動態庫(動態鏈接):

動態庫在程序編譯時并不會被鏈接到目標代碼中,而是在程序運行時才被載入

程序運行時,如果我們需要調用 printf 函數, printf 函數會被修改為庫函數中 printf 實現的地址,這時候動態鏈接就建立好了。

動態庫也叫共享庫。

優點:比較節省資源(內存資源、網絡資源等),不會出現太多的重復的代碼;

缺點:對庫的依賴性比較強,一旦庫丟失,所有依賴該庫的程序都無法運行。

?用 file 命令查看文件類型時,可以看出代碼是動態鏈接的:

靜態庫(靜態鏈接):

編譯鏈接時,把庫文件的代碼全部加入到可執行文件中

優點:可執行程序不依賴庫,同類型平臺中進行跨平臺使用;

缺點:生成的文件比較大,比較浪費資源(占用內存--內存資源、網絡傳輸時傳輸量大--網絡資源等)。

代碼默認與動態庫鏈接,我們也可以讓代碼與靜態庫鏈接:

gcc -o mybin-static? test.c? -static 就可以讓代碼與靜態庫鏈接,但是系統是默認沒有安裝靜態庫的,此時靜態鏈接會出錯,我們需要在系統中下載靜態庫!

在普通用戶下,sudo? yum? install? -y? glibc-static? libstdc++-static 就可以安裝靜態庫。?

?安裝完成后,用 ldd 和 file 命令可以看出,test-static 與靜態庫鏈接。

test 是動態鏈接的,test-static 是靜態鏈接的,通過對比可以看出, 同樣的源代碼,靜態鏈接的代碼占用的空間比動態鏈接的大很多。

?

本文到這里就結束了,歡迎各位大佬的指正!?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/43553.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/43553.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/43553.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Simulink基于模型設計(二):系統定義和布局

Simulink模型的頂層系統布局是許多工程團隊可以使用的公共環境,是基于模型的設計范式:分析、設計、檢驗和實現。您可以通過確定模型的結構和各個組件來定義頂層系統。然后,您可以將模型按照層次結構進行組織,分別與系統的各個組件…

【鴻蒙學習筆記】交互事件

官方文檔:交互事件 目錄標題 分類交互事件-觸屏交互事件-手勢事件單一手勢 分類 交互事件-觸屏 在組件上按下(Down) , 滑動(Move) , 抬起(up)時觸發的回調事件。包括點擊事件、觸摸事件和拖拽事件 交互事件-手勢事件 在手機上點擊打開應用 , 長按后拖動應用 , 這…

自動化數據集成的BI工具,為你提供決策洞察力

傳統的商業智能(BI)報表系統采用的是“業務提報表需求,IT進行開發”的模式。決策管理者和業務人員提出用報表等來展示經營管理數據的需求;接著IT響應需求,進行需求溝通、數據處理加工、報表開發等主體工作;…

使用java代碼取本月第一個工作日

根據參數或當前月,獲取本月第一個工作日 文章目錄 根據參數或當前月,獲取本月第一個工作日前言一、根據當前日期獲取當前月的第一個工作日二、根據參數日期,獲取參數月的第一個工作日。總結 前言 這里我們列舉兩個方法: 1、沒有參…

RFID資產管理系統 RFID固定資產管理系統

大多數企業都曾被固定資產管理“難”的問題困擾:賬物不符、查詢不便、盤點耗時……因此,越來越多的企業選擇用資產管理系統,來實現資產智能化管理。 RFID資產管理系統方案是針對大多數企業存在的資產管理痛點,采用RFID技術&#…

uni-app三部曲之三: 路由攔截

1.引言 路由攔截,個人理解就是在頁面跳轉的時候,增加一級攔截器,實現一些自定義的功能,其中最重要的就是判斷跳轉的頁面是否需要登錄后查看,如果需要登錄后查看且此時系統并未登錄,就需要跳轉到登錄頁&…

Python地震波逆問題解構算法復雜信號分析

🎯要點 🎯時域、時頻域以及時間和頻率相關聯偏振特性分析三種算法 | 🎯時域波參數估計算法 | 🎯機器學習模型波形指紋分析算法 | 🎯色散曲線和頻率相關波分析算法 | 🎯動態傾斜校正算法 | 🎯聲…

【JS|第21期】JavaScript模塊化:深入解析三種文件暴露方式

日期:2024年7月6日 作者:Commas 簽名:(? ?_?)? 積跬步以致千里,積小流以成江海…… 注釋:如果您覺得有所幫助,幫忙點個贊,也可以關注我,我們一起成長;如果有不對的地方,還望各位大佬不吝賜教,謝謝^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083…

前后端項目部署方案匯總

前端項目 1、本地打包部署 # 本地打包部署到線上服務器 npm run build && \ rsync -r ./dist/* root127.0.0.1:/www/www.demo.com/www2、服務器端打包部署 步驟 拉取代碼 -> 安裝依賴 -> 打包編譯 -> 拷貝到運行目錄 -> 發送成功消息shell命令 git pu…

新手小白報考學習PMP會遇到哪些“坑”?

PMP考試的陷阱實際上與其他大型證書考試差不多,主要是在選擇培訓機構和各種收費方面會遇到一些坑。 首先,并不是每個人都能經歷這些坑,因為PMP考試有一定的門檻。 作為引進國外的考試,報名都有中英文之分,所以先來看…

STM32的 DMA(直接存儲器訪問) 詳解

STM32的DMA(Direct Memory Access,直接存儲器存取)是一種在單片機中用于高效實現數據傳輸的技術。它允許外設設備直接訪問RAM,不需要CPU的干預,從而釋放CPU資源,提高CPU工作效率,本文基于STM32F…

[極客大挑戰 2019]RCE ME

[極客大挑戰 2019]RCE ME <?php error_reporting(0); if(isset($_GET[code])){$code$_GET[code];if(strlen($code)>40){die("This is too Long.");}if(preg_match("/[A-Za-z0-9]/",$code)){die("NO.");}eval($code); } else{highlight_f…

(附源碼)c#+winform實現遠程開機(廣域網可用)

實現邏輯 利用UDP協議發送特定格式的魔術包&#xff0c;以遠程喚醒具有特定MAC地址的目標計算機。目標計算機的BIOS和網絡配置需要支持Wake-on-LAN&#xff08;WOL&#xff09;功能&#xff0c;并且需要在目標計算機上配置正確的網絡喚醒設置。 源碼在最后 準備工作 進入Bio…

力學有限元的基石:虛功原理的推導

推導虛功方程的過程 彈性力學的平衡方程 在張量形式中&#xff0c;平衡方程為&#xff1a; ? ? σ b 0 \nabla \cdot \sigma b 0 ??σb0 用下標表示為&#xff1a; ? σ i j ? x j b i 0 \frac{\partial \sigma_{ij}}{\partial x_j} b_i 0 ?xj??σij??b…

知識圖譜入門筆記

自學參考&#xff1a; 視頻&#xff1a;斯坦福CS520 | 知識圖譜 最全知識圖譜綜述 詳解知識圖譜的構建全流程 知識圖譜構建&#xff08;概念&#xff0c;工具&#xff0c;實例調研&#xff09; 一、基本概念 知識圖譜&#xff08;Knowledge graph&#xff09;&#xff1a;由結…

Redis管理禁用命令

在redis數據量比較大時&#xff0c;執行 keys * &#xff0c;fluashdb 這些命令&#xff0c;會導致redis長時間阻塞&#xff0c;大量請求被阻塞&#xff0c;cpu飆升&#xff0c;嚴重可能導致redis宕機&#xff0c;數據庫雪崩。所以一些命令在生產環境禁止使用。 Redis 禁用命令…

【C語言】指針(3):探索-不同類型指針變量

目錄 一、字符指針變量 二、數組指針變量 三、二維數組傳參的本質 四、函數指針變量 4.1 函數指針變量 4.2 函數指針變量的使用 4.3 函數指針變量的拓展 五、函數指針數組 六、轉移表的應用 通過深入理解指針&#xff08;1&#xff09;和深入理解指針&#xff08;2&am…

67.SAP FICO-憑證類型學習

目錄 SAP憑證類型 憑證類型的作用 - OBA7 SAP默認的憑證類型更改 FI相應事務代碼默認憑證類型 - OBU1 對FB50、60、70默認憑證類型的更改 - OBZO 后勤貨物移動默認憑證類型 - OMBA 發貨憑證類型 收貨憑證類型 自動移動憑證類型 存貨盤點憑證類型 發票默認的憑證類…

深度學習Day-24:ResNeXt-50算法思考

&#x1f368; 本文為&#xff1a;[&#x1f517;365天深度學習訓練營] 中的學習記錄博客 &#x1f356; 原作者&#xff1a;[K同學啊 | 接輔導、項目定制] 要求&#xff1a; 閱讀給出代碼&#xff0c;判斷是否存在錯誤&#xff0c;正確與否都請給出你的思考&#xff1b;查找…

如何減少開發過程中的bug-數據庫篇

1.1慢查詢 1.1.1 是否命中索引 提起慢查詢&#xff0c;我們馬上就會想到加索引。如果一條SQL沒加索引&#xff0c;或者沒有命中索引的話&#xff0c;就會產生慢查詢。 索引哪些情況會失效&#xff1f; 查詢條件包含or&#xff0c;可能導致索引失效 如果字段類型是字符串&am…