『Linux升級路』基礎開發工具——gcc/g++篇

🔥博客主頁:小王又困了

📚系列專欄:Linux

🌟人之為學,不日近則日退?

??感謝大家點贊👍收藏?評論??


目錄

一、快速認識gcc/g++

?二、預處理

📒1.1頭文件展開?

📒1.2條件編譯

二、編譯

三、匯編

四、鏈接

📒4.1庫的概念

📒4.2庫的特點

📒4.3庫的分類

📒4.4動態鏈接

📒4.5靜態鏈接


🗒?前言:

? ? 在前面的文章中我們學會了vim的用法,可以寫一些代碼,要想讓我們的代碼運行起來,還需要我們學會編譯工具gcc、g++的使用。C語言既可以使用gcc,也可以使用g++;C++只能使用g++,它們的使用形式是相同的,今天以gcc為主,介紹它們的使用方法,帶大家快速上手。

一、快速認識gcc/g++

? ? ?當我們寫完一段代碼,想要編譯時可以在命令行輸入:gcc code.c,會默認形成a.out的可執行程序。

在輸入./a.out,程序就可以執行起來了。

? ? ?當我們不想形成默認的可執行,想讓它形成指定名稱的可執行,可以輸入:gcc code.c -o mycode gcc -o mycode code.c

編譯主要分為預處理、編譯、匯編、鏈接四個過程,我們將詳細講解這四個過程,帶大家學會gcc的使用。

?二、預處理

? ? ?此階段處理以 .c .cpp 為擴展名的源文件,并執行預處理指令。預處理器的主要任務是頭文件展開條件編譯、展開宏定義、移除注釋等。預處理指令都是以#開頭的代碼行。

  • 指令:gcc -E code.c -o code.i
  • -E:從現在開始進行程序的翻譯過程,當預處理做完的時候就停止
  • -o:指目標文件,將當前編譯結果寫入到code.i文件中?
  • ?.i?文件為經過預處理的C語言程序(還是C語言)

📒1.1頭文件展開?

? ? ?頭文件展開,就是在預處理的時候,將頭文件拷貝到引用它的源文件中。通過上圖我們可以看到,原本14行的代碼經過預編譯變成了850行。多出的這么多代碼,就是把stdio.h文件中的內容插入到當前源文件中。/usr/include/目錄是Linux下gcc/g++頭文件的默認搜索路徑,該路徑下有許多和開發相關的頭文件。

頭文件的展開過程涉及到#include預處理指令。當預處理器遇到#include指令時,它會打開指定的頭文件并將其內容插入到當前源文件的位置。這個過程可以分為兩種類型的包含:

  • 系統頭文件的包含:

使用尖括號<>包含系統頭文件,例如:

#include <stdio.h>

預處理器會在系統頭文件目錄中查找并打開stdio.h文件,并將其內容插入到當前源文件中。

  • ?用戶頭文件的包含:

?使用雙引號?“ ”?包含用戶定義的頭文件,例如:

#include “test.h”

預處理器會在當前源文件所在目錄以及指定的包含路徑中查找并打開test.h文件,并將其內容插入到當前源文件中。

📒1.2條件編譯

? ? ?條件編譯就是處理條件編譯指令,如#if#ifdef#ifndef#else#elif#endif等。根據條件判斷是否編譯特定代碼塊。例如:

#ifdef identifier// 代碼塊 A
#else// 代碼塊 B
#endif

如果已經定義了標識符identifier,則編譯?// 代碼塊 A?部分,否則編譯?// 代碼塊 B?部分。

? ? ?條件編譯最重要的意義就是對頭文件的保護,防止頭文件被重復包含。

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

在展開頭文件時,預處理器會繼續遞歸地處理被包含的頭文件。這意味著如果一個頭文件包含了另一個頭文件,那么這個被包含的頭文件也會被展開,以此類推,直到所有的頭文件都被插入到源文件中。我們使用上面這段條件編譯的代碼就可以避免這種情況,如果沒有定義HEADER_FILE,就執行下面的代碼;如果定義了,就不會執行了。

📝條件編譯的主要用途包括:?

  • 平臺特定代碼: 通過條件編譯,可以根據不同的操作系統或硬件平臺編寫特定的代碼。

  • 調試和發布版本: 可以使用條件編譯來在調試版本和發布版本之間切換代碼。

  • 特定功能的開關: 通過條件編譯,可以選擇性地包含或排除某些功能,以滿足特定的編譯需求。

  • 配置選項: 根據不同的配置選項選擇性地包含或排除代碼,以適應不同的編譯環境

二、編譯

? ? ?在這個階段,預處理后的源代碼(通常是.i文件)被翻譯成匯編語言。gcc 首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤后,gcc 把代碼翻譯成匯編語言。生成的匯編代碼描述了程序的控制流、數據等信息。

  • 指令:gcc -S?code.i?-o code.s
  • -S:從現在開始進行程序的翻譯過程,當編譯工作做完的時候就停止

三、匯編

? ? ?在這個階段,匯編器將匯編代碼(通常是.s文件)翻譯成機器碼或可重定位的機器碼。它將匯編代碼轉換成二進制目標文件,其中包含特定于處理器體系結構的指令。這個二進制文件也被叫做可重定位目標二進制文件,簡稱目標文件。但是它不能被執行。

  • ?指令:gcc -c?code.s?-o code.o
  • -c:從現在開始進行程序的翻譯過程,當匯編工作做完的時候就停止

📝目標文件為什么不能執行?

? ? ?目標文件通常沒有定義程序的入口點,即程序的起始地址。可執行文件需要一個明確定義的入口點,從這個點開始執行程序。單獨的目標文件可能包含了未解決的符號引用,無法獨立執行。可執行文件需要在操作系統上運行,而操作系統提供了運行時支持,包括內存管理、文件操作、進程調度等。沒有這些支持,程序很難在操作系統上正確運行。所以,我們還要通過鏈接來解決這些問題,讓目標文件與其他目標文件或庫文件進行鏈接,形成最終的可執行文件。

四、鏈接

? ? ?在這個階段,鏈接器將一個或多個目標文件(通常是.o文件)與所需的庫文件結合,創建可執行文件。鏈接的主要任務包括符號解析、地址解析、重定位等,以確保所有部分正確地組合在一起。

  • 指令:gcc? code.o?-o mycode

📒4.1庫的概念

? ? ?庫通常指的是包含可重用代碼和資源的集合,目的是為了幫助開發者完成特定任務。庫可以包含函數、類、變量、子例程等,提供了一組API(應用程序接口)或者工具,使得開發者能夠更輕松地完成常見的編程任務,而無需從頭開始編寫所有的代碼。

? ? ?我們的C程序中,并沒有定義printf的函數實現,且在預編譯中包含的“stdio.h”中也只有該函數的聲明,而沒有定義函數的實現,那么,是在哪里實現printf函數的呢? 答案是:系統把這些函數實現都被做到名為?libc.so.6 的庫文件中去了,在沒有特別指定時,gcc會到系統默認的搜索路徑/usr/lib下進行查找,會默認找到C的標準庫,它會把我們寫的源代碼經過編譯得到的目標文件與庫文件進行鏈接,也就是鏈接到 libc.so.6 庫函數中去,這樣就能實現函數printf了,而這也就是鏈接的作用。

  • ?libc.so.6 就是C語言的標準庫。?

📒4.2庫的特點

  1. 可重用性: 庫中的代碼可以在不同的程序中被重復使用,從而減少了代碼的冗余,提高了開發效率。

  2. 封裝性: 庫提供了一個封裝的接口,隱藏了內部實現的細節,使得開發者可以專注于使用功能而不必關心底層的實現。

  3. 模塊化: 庫通常被組織成模塊,每個模塊負責一個特定的功能。這種模塊化的設計有助于提高代碼的可維護性和可擴展性。

  4. 標準化: 一些庫成為了編程的標準,被廣泛接受和使用。這樣的庫通常提供了一些通用的解決方案,被廣泛認可并得到社區的支持。

📒4.3庫的分類

? ? ?庫分為兩類:動態庫靜態庫。其中Linux環境下,動態庫的后綴是.so,靜態庫的后綴是.a。在Windows環境下,動態庫的后綴是.dll,靜態庫的后綴是.lib。所有的庫文件,都遵守相同的命名規則,即:libname.后綴.xxx

  • 靜態庫(Static Library): 在編譯時被鏈接到程序中,程序在運行前就包含了庫的代碼。這意味著庫的代碼被復制到了程序的可執行文件中。

  • 動態庫(Dynamic Library): 在運行時被加載到內存中,程序在運行時可以調用庫的函數。這樣可以減小程序的大小,因為多個程序可以共享同一個庫的實例。

?常見的庫包括標準庫(如C標準庫、C++標準庫)、圖形界面庫(如Qt、GTK+)、數學庫(如NumPy)、網絡庫(如libcurl)、以及許多其他領域的專用庫。

📒4.4動態鏈接

? ? ?動態鏈接是一種在程序運行時將代碼和數據庫鏈接到程序中的技術。把庫中要用到的庫函數的地址寫到在我們代碼中調用這個函數的地方,就是動態鏈接。

  • 指令ldd 可執行程序,可以查看一個可執行程序所依賴的動態庫。

gcc的默認行為是動態鏈接?

🎀動態鏈接的優點:

  • 節省內存:?多個程序可以共享同一份庫的實例,從而節省內存。
  • 易于更新:?更新庫時,不需要重新編譯所有依賴于該庫的程序。只需替換庫的新版本即可。
  • 靈活性:?可以在程序運行時動態加載和卸載庫,使得程序更加靈活。

🎀?動態鏈接的缺點:

  • 依賴性:對庫的依賴性強 一旦庫丟失,所有使用這個庫的程序都無法運行

📒4.5靜態鏈接

? ? ?靜態鏈接是一種在程序編譯時將所有代碼和庫鏈接到一個獨立的可執行文件的過程。這意味著在程序運行之前,所有的代碼和庫已經被合并成一個單獨的可執行文件。把庫中的代碼拷貝到我們的可執行程序中,就是靜態鏈接。

在Linux中默認是沒有靜態庫的,需要我們自己安裝。

  • sudo yum install -y glibc-static?
  • gcc code.c -o mycode-static -static
  • 其中 -static表示執行靜態鏈接

🎀靜態鏈接的優點:

  • 獨立性:?生成的可執行文件是完全獨立的,不需要外部的依賴。這使得程序更容易分發和部署,因為用戶只需要一個文件就可以運行程序。
  • 性能:?靜態鏈接的程序在運行時無需進行額外的庫加載,因此在一些情況下可能會稍微快于動態鏈接的程序。

🎀靜態鏈接的缺點:

  • 占用空間:?由于每個可執行文件包含了所需的所有代碼和庫,因此靜態鏈接的程序通常比動態鏈接的程序更大。
  • 更新困難:?如果庫被更新,需要重新編譯并重新分發整個可執行文件,而不僅僅是替換庫文件。

本次的內容到這里就結束啦。希望大家閱讀完可以有所收獲,同時也感謝各位讀者三連支持。文章有問題可以在評論區留言,博主一定認真認真修改,以后寫出更好的文章。你們的支持就是博主最大的動力。

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

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

相關文章

java字符串的常見用法

java字符串的常見用法 Java中的字符串是一個非常常用的對象&#xff0c;它屬于Java的內置類String類的實例。字符串在Java中是不可變的&#xff0c;即一旦創建了一個字符串對象&#xff0c;就不能修改它的值。 下面是一些關于Java字符串的詳細用法&#xff1a; 1&#xff09;創…

從零開始,用Docker-compose打造SkyWalking、Elasticsearch和Spring Cloud的完美融合

&#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交給時間 &#x1f3e0; &#xff1a;小破站 "從零開始&#xff0c;用Docker-compose打造SkyWalking、Elasticsearch和Spring Cloud的完美融合 前言準備工作編寫docker-compose.yml文件為什么使用本機ip為什么skywa…

代碼隨想錄-刷題第六天

242. 有效的字母異位詞 題目鏈接&#xff1a;242. 有效的字母異位詞 思路&#xff1a;哈希法。利用數組來記錄出現的字母個數&#xff0c;然后判斷是否為字母異位詞。 時間復雜度&#xff1a;O(n) class Solution {public boolean isAnagram(String s, String t) {int[] co…

【云備份】第三方庫的認識與使用

文章目錄 json庫粗略認識詳細認識writer 類reader類jsoncpp序列化實現jsoncpp反序列化實現 bundle文件壓縮庫簡單認識bundle庫實現文件壓縮bundle庫實現文件解壓縮 httplib庫Request類Response類Server類Client類 json庫 粗略認識 json是一種數據交換格式&#xff0c;采用完全…

激光切割設備中模組的作用有哪些?

激光切割設備是一種高精度的自動化加工設備&#xff0c;用于對金屬、非金屬等材料進行精確切割。直線模組作為激光切割設備的重要組成部分&#xff0c;在激光切割設備中起著重要的作用&#xff0c;為設備的運動系統提供了高精度、高穩定性和高效率的運動控制。 1、高精度的位置…

excel單元格加背景顏色不生效?

如果在 Excel 中設置單元格背景顏色而發現不生效&#xff0c;可能有幾個原因。以下是一些常見的解決方法&#xff1a; 1. **單元格鎖定&#xff1a;** 檢查所在單元格是否被鎖定。如果單元格被鎖定&#xff0c;并且工作表被保護&#xff0c;你可能無法更改其背景顏色。在工作表…

mysql 優化器的AST樹是啥

from ChatGPT: MySQL中的優化器&#xff08;optimizer&#xff09;使用AST&#xff08;Abstract Syntax Tree&#xff0c;抽象語法樹&#xff09;來表示查詢的語法結構。AST是一種樹狀結構&#xff0c;它反映了查詢語句的語法層次&#xff0c;是一個抽象表示&#xff0c;用于更…

Linux - 文件系統 - 理解目錄 - 理解 軟/硬鏈接

前言 在上篇博客當中&#xff0c;我們對 文件系統 和 inode 做了初步了解&#xff0c;本博客將在上篇博客的基礎之上&#xff0c;對于 文件系統當中的目錄進行進步一闡述。 Linux - 進一步理解 文件系統 - inode - 機械硬盤-CSDN博客 目錄 一個文件有一個 inode&#xff0c;…

Redis打包事務,分批提交

一、需求背景 接手一個老項目&#xff0c;在項目啟動的時候&#xff0c;需要將xxx省整個省的所有區域數據數據、以及系統字典配置逐條保存在Redis緩存里面&#xff0c;這樣查詢的時候會更快; 區域數據字典數據一共大概20000多條,&#xff0c;前同事直接使用 list.forEach…

Windows安裝MongoDB

1、下載MongoDB的zip&#xff0c;解壓 2、創建目錄 mkdir D:\JavaSoftware\Database\MongoDB\mongodb-win32-x86_64-windows-5.0.8\data\db mkdir D:\JavaSoftware\Database\MongoDB\mongodb-win32-x86_64-windows-5.0.8\data\log 3、創建一個配置文件mongod.cfg&#xff0c…

使用一個接口的結果作為第二個接口的參數并將兩者的數據放置成下拉框的格式

背景 我使用下拉框實現選擇id 但是只有兩個接口 一個是所有的id 另一個是id對應的具體信息 我想把id傳入另一個接口并且獲取其name然后寫成類似這樣的數組 [ { value: 1, label: ‘名稱1’ }&#xff0c; { value: 2, label: ‘名稱2’ } { value: 3, label: ‘名稱3’ } ] 然…

【PPspliT】ppt轉pdf-保留過渡動畫

網址 http://www.maxonthenet.altervista.org/ppsplit.php 下載安裝 使用 再次打開ppt&#xff0c;就能在上方的選項欄里頭看到了&#xff1a;

GEE生物量碳儲量——利用紅和近紅外波段和OTSU大津法提取純凈森林面積

簡介: 如何利用紅和近紅外波段和OTSU大津法提取純凈森林面積?本文的主要邏輯是利用特定時期的遙感影像的波段,提取指定范圍的內的DN值,然后分別統計發生閾值變化的峰值區域,從而作為篩選森林的臨界點,如果研究區較大的話則需要先進行影像分割,分割成為相同大小的區域,…

前端開發Java學習

注釋&#xff1a; 單行注釋 // 多行注釋 /* */ 文件注釋 /** */ 1 關鍵字 &#xff08;關鍵字一定是小寫&#xff09; 2 常量 字符串常量"HelloWord","你好世界"整數常量12&#xff0c;-33小數常量3.14&#xff0c;22.1字符常量A&#xff0c;a &…

不是默認進入Linux|總是自動進入windows系統

問題描述 不是默認進入Linux系統無法主動出現boot引導自動進入windows系統 嘗試無效 修復引導無效重裝Grub無效重裝系統無效 環境 Ubuntu 22.04 LST微星主板 解決方案 修改引導順序&#xff1a; 開機狂按Del鍵&#xff0c;進入BIOS系統&#xff0c;左側Settings 設置&…

src和href的區別

前言 持續學習總結輸出中&#xff0c;src和href都是HTML中特定元素的屬性&#xff0c;都可以用來引入外部的資源。兩者區別如下&#xff1a; 1、作用 href 用于在當前文檔和引用資源之間確立聯系。 src 用于替換當前內容。 2、范圍用途 src&#xff08;source&#xff09…

RabbitMQ基礎教程

1.什么是消息隊列 消息隊列&#xff08;Message Queue&#xff09;&#xff0c;我們一般簡稱為MQ。消息隊列中間件是分布式系統中重要的組件&#xff0c;具有異步性、松耦合、分布式、可靠性等特點。用于實現高性能、高可用、可伸縮和最終一致性架構。是大型分布式系統不可缺少…

Angular11 MSAL B2C登錄實例 (一)

前言 因為項目需求&#xff0c;需要把Angular 11項目中登錄方式改成B2C登錄&#xff0c;所以在參考了一系列文檔后&#xff0c;成功通過MSAL將項目的登錄方式改成B2C登錄。下面介紹了詳細步驟及一些注意事項。 步驟&#xff1a; 1. 安裝MSAL 在項目中安裝msal npm i azure/…

BUUCTF [WUSTCTF2020]find_me 1

BUUCTF:https://buuoj.cn/challenges 題目描述&#xff1a; 得到的 flag 請包上 flag{} 提交。 感謝 Iven Huang 師傅供題。 比賽平臺&#xff1a;https://ctfgame.w-ais.cn/ 密文&#xff1a; 下載附件&#xff0c;得到一個.jpg圖片。 解題思路&#xff1a; 1、得到一張圖…