【Linux】編譯器gcc/g++及其庫的詳細介紹

前言:

? ? ? ? 上文我們學到了,LInux中的的編輯器vim【Linux】vim編輯器-CSDN博客

? ? ? ? 本文來學習LInux中的編譯器:gcc/g++

? ? ? ? gcc是C語言編譯器,g++是C++編譯器,這兩個的使用一模一樣。這里我們主要使用gcc給大家介紹

?1.格式

gcc? 被編譯的源文件? ?選項? ?編譯的目標文件

選項:-o,生成指定文件

若不指定文件則默認生成a.out,若自定則生成指定的可執行文件

hyc@hcss-ecs-4ce7:~$ ls
new  new.c#未指定
hyc@hcss-ecs-4ce7:~$ gcc new.c
hyc@hcss-ecs-4ce7:~$ ls
a.out  new  new.c
hyc@hcss-ecs-4ce7:~$ ./a.out
存在
存在
存在
存在
存在#指定
hyc@hcss-ecs-4ce7:~$ gcc new.c -o new.exe
hyc@hcss-ecs-4ce7:~$ ls
new  new.c  new.exe
hyc@hcss-ecs-4ce7:~$ ./new.exe
存在
存在
存在
存在
存在

2.編譯的過程?

2.1預處理

預處理的功能包括:替換宏定義、頭文件展開、條件編譯、去注釋等

預處理的指令是從#開始的代碼行

.c文件經過預處理會形成.i文件

-E選項:使編譯器處理完預處理就停下

hyc@hcss-ecs-4ce7:~$ ls
new  new.chyc@hcss-ecs-4ce7:~$ gcc -E new.c -o new.i
hyc@hcss-ecs-4ce7:~$ ls
new  new.c   new.i

2.2編譯

編譯主要功能:檢查.i文件代碼是否規范,是否有語法錯誤。檢查無誤后gcc將代碼翻譯為匯編語言,生成.s文件

-S選項:使編譯器處理完編譯就停下

hyc@hcss-ecs-4ce7:~$ ls -l
total 28
drw-rwxr-x 2 hyc hyc  4096 May 26 15:41 new
-rw-rw-r-- 1 hyc hyc   219 May 29 21:58 new.c
-rw-rw-r-- 1 hyc hyc 18047 Jun  3 13:31 new.ihyc@hcss-ecs-4ce7:~$ gcc -S new.i -o new.s
hyc@hcss-ecs-4ce7:~$ ls -l
total 32
drw-rwxr-x 2 hyc hyc  4096 May 26 15:41 new
-rw-rw-r-- 1 hyc hyc   219 May 29 21:58 new.c
-rw-rw-r-- 1 hyc hyc 18047 Jun  3 13:31 new.i
-rw-rw-r-- 1 hyc hyc   895 Jun  3 13:38 new.s

補充:為什么要將代碼翻譯成匯編?

????????在計算機剛剛誕生的時代,沒有任何編程語言,科學家是通過計算機上的元器件開關來控制計算機的。后來科學家發明了”打孔編程“,通過紙袋傳遞二進制信息

? ? ? ? 再后來又發明了匯編語言,但匯編語言無法直接傳遞二進制信息。于是對于匯編語言的編譯器誕生了。通過編譯器將匯編語言映射為二進制,來操控計算機

? ? ? ? 再后來就出現了各種各樣的編譯性語言:例如C/C++,java,python等等等等。對于這些語言我們也需要將其翻譯為二進制,計算機才能明白我們的意圖。

? ? ? ? 但是這里有兩條路:C -> 二進制,C ->匯編?選著哪條?

? ? ? ? 顯然我們選著了第二條路,因為C語言到二進制這無疑就困難的。而C到匯編語言仍是文本上的翻譯,相對簡單。我們可以直接站在巨人的肩膀上不用做二進制的翻譯。

補充:編譯器的誕生

? ? ? ? 匯編語言被發明了,想要匯編語言被翻譯成二進制,那么需要一個編譯器來編譯匯編語言。那匯編語言的編譯器是怎么來的?答案是:先通過二進制編寫一個編譯器,得到匯編語言的編譯器后,再通過使用匯編語言寫一個匯編編譯器。最終得到一個匯編版的匯編編譯器。

? ? ? ? 同理C語言被發明了,想要有一個C語言的編譯器,只能先使用匯編語言編寫一個C語言編譯器,在通過C語言編譯器寫一個C語言的編譯器。最終得到一個C語言版的C語言編譯器。

? ? ? ? 這就是編譯器的自舉

2.3匯編

匯編主要功能:將.s文件轉化為機器可識別的二進制文件(.o)

-c選項:使編譯器處理完匯編就停下

hyc@hcss-ecs-4ce7:~$ ls
new  new.c  new.i  new.shyc@hcss-ecs-4ce7:~$ gcc -c new.s -o new.o
hyc@hcss-ecs-4ce7:~$ ls -l 
total 36
drw-rwxr-x 2 hyc hyc  4096 May 26 15:41 new
-rw-rw-r-- 1 hyc hyc   219 May 29 21:58 new.c
-rw-rw-r-- 1 hyc hyc 18047 Jun  3 13:31 new.i
-rw-rw-r-- 1 hyc hyc  1744 Jun  3 13:42 new.o
-rw-rw-r-- 1 hyc hyc   895 Jun  3 13:38 new.s

2.4連接

將庫方法與我們自己寫的目標文件連接起來,形成可執行文件

hyc@hcss-ecs-4ce7:~$ gcc new.o -o new.exe
hyc@hcss-ecs-4ce7:~$ ls -l
total 52
drw-rwxr-x 2 hyc hyc  4096 May 26 15:41 new
-rw-rw-r-- 1 hyc hyc   219 May 29 21:58 new.c
-rwxrwxr-x 1 hyc hyc 15960 Jun  3 13:51 new.exe
-rw-rw-r-- 1 hyc hyc 18047 Jun  3 13:31 new.i
-rw-rw-r-- 1 hyc hyc  1744 Jun  3 13:42 new.o
-rw-rw-r-- 1 hyc hyc   895 Jun  3 13:38 new.s
hyc@hcss-ecs-4ce7:~$ ./new.exe
存在
存在
存在
存在
存在

補充:

記憶選項:ESc

記憶文件后綴:.iso

對于編譯器來說一般都是先將所有的文件編譯為 .o文件,再將全部 .o文件一起連接

3.理解條件編譯

條件編譯是在預處理階段執行的,其具體操作是將不滿足條件的代碼直接抹去,只保留滿足條件的

演示:

新建一個代碼

保存并退出,我們讓其進行預處理,然后再查看代碼

hyc@hcss-ecs-4ce7:~$ gcc -E test.c -o test.i
hyc@hcss-ecs-4ce7:~$ vim test.i

我們可以看到代碼就只剩第一個printf函數了。

同時編譯器還支持在命令行中動態的定義宏

#使用-D選項,可以實現在命令行中動態的定義宏hyc@hcss-ecs-4ce7:~$ gcc test.c -o test
hyc@hcss-ecs-4ce7:~$ ./test
收費->專業版
hyc@hcss-ecs-4ce7:~$ gcc test.c -o test -DM=10
hyc@hcss-ecs-4ce7:~$ ./test
免費->社區版

預處理的本質就是編輯我們的代碼。像我們用到的vs、xshell等等工具都有社區版和專業版的區別,但不論是那個版本其本質都是同一個項目,只是使用了條件編譯將專業版進行閹割作為社區版供給普通人免費使用。

4.動態庫靜態庫

什么的庫?

????????庫是編程中的 “工具箱”,通過復用成熟代碼,讓開發者聚焦業務邏輯,大幅提升開發效率和代碼質量。從基礎的標準庫到專業的第三方庫,它們構成了現代軟件開發的核心生態,是實現快速迭代和復雜功能的關鍵支撐。

補充:ldd指令

ldd指令可以讓我們查看可執行程序依賴了那些庫

這里我們可以看到這個可執行程序依賴了C語言的動態庫。

庫的命名方式

動態庫 :

在代碼加載到內存時,會進行動態連接:將程序中要使用的庫實現函數,在庫中找到相應位置,并對函數地址進行替換。這樣在調用對應函數時,就會直接跳轉到庫中相應位置進行執行。執行完畢跳轉回來繼續向下執行

靜態庫:

靜態庫與動態庫相反,在編譯階段就會將所需要部分的代碼,直接拷貝到我們自己的代碼中

補充:

1.Linux下動態庫為:xxx.so? ? 靜態庫為:xxx.a

? ?windows下動態庫為:xxx.dll? ? 靜態庫為:xxx.lib

2.靜態庫只在連接時有用,一旦形成可執行文件后, 就不再需要了

動靜態庫對比

1.動態庫所形成的可執行文件,體積小

2.可執行文件對靜態庫依賴小,動態庫依賴大不可缺失

3.運行程序需要加載至內存中,靜態庫的連接方式會導致內存中出現大量重復代碼

4.動態庫的連接方式比較節省內存空間和磁盤資源

(一般的可執行程序都是默認動態連接的)

簡單理解庫的本質

庫分為兩部分:一個是開放的.h頭文件包含各個函數的聲明,另一個是的各個函數的實現,是編譯后的.o文件組成的集合

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

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

相關文章

用“紅燒魚”類比說明卷積神經網絡CNN的概念

我們用一個生活中的例子——「廚房做紅燒魚」 的場景,來類比卷積神經網絡中多層卷積核的工作過程。你會發現,卷積層就像廚房里分工明確的廚師團隊,逐步處理食材,最終完成一道復雜的菜品。 🐟 生活案例:廚房…

uniapp與微信小程序開發平臺聯調無法打開IDE

經測試屬于網絡問題。本機需要聯網。否則會出現Hbuilder運行微信小程序到模擬器時無法打開 微信開發者工具 這個頁面出不來會一直顯示異常。這期間微信小程序開發工具的端口是通的 需要先聯網

內網穿透之Linux版客戶端安裝(神卓互聯)

選擇Linux系統版本 獲取安裝包 :https://www.shenzhuohl.com/download.html 這里以Ubuntu 18.04為例,其它版本方法類似 登錄Ubuntu操作系統: 打開Ubuntu系統終端,更新版本 apt-get update 安裝運行環境: 安裝C 運…

硬件學習筆記--66 MCU的DMA簡介

DMA(Direct Memory Access,直接存儲器訪問)是MCU中一種重要的數據傳輸機制,它允許外設與存儲器之間或存儲器與存儲器之間直接傳輸數據,而無需CPU的持續干預。 1、DMA的基本原理 1.1 核心概念: 1&#xf…

DeepSeek本地部署及WebUI可視化教程

前言 DeepSeek是近年來備受關注的大模型之一,支持多種推理和微調場景。很多開發者希望在本地部署DeepSeek模型,并通過WebUI進行可視化交互。本文將詳細介紹如何在本地環境下部署DeepSeek,并實現WebUI可視化,包括Ollama和CherryStudio的使用方法。 一、環境準備 1. 硬件要…

RK3588和FPGA橋片之間IO電平信號概率性不能通信原因

1.GPIO管腳配置問題 RK3588對IO進行配置的時候,如果配置為多功能復用,沒有明確IO功能,可能引起信號接收不穩定, 需要在驅動中設備樹中配置管腳為GPIO功能,確保沒有功能復用的干擾。 2.上下拉電阻阻值設置不當 GPIO引腳…

相機--相機標定實操

教程 camera_calibration移動畫面示例 usb_cam使用介紹和下載 我使用的是USB相機,所以直接使用ros的usb_cam功能包驅動相機閉關獲取實時圖像,然后用ros的camera_calibration標定相機。 查詢攝像機的信息 v4l2-ctl -d 0 --all的作用 命令詳解&#xf…

【Kotlin】高階函數Lambda內聯函數

【Kotlin】簡介&變量&類&接口 【Kotlin】數字&字符串&數組&集合 【Kotlin】高階函數&Lambda&內聯函數 【Kotlin】表達式&關鍵字 文章目錄 函數還是屬性高階函數抽象和高階函數實例: 函數作為參數的需求方法引用表達式更多使用場…

飛算JavaAI 炫技賽重磅回歸!用智能編碼攻克老項目重構難題

深夜還在排查十年前Hibernate框架埋下的N1查詢隱患?跨語言遷移時發現SpringMVC控制器里的業務邏輯像一團亂麻?當企業數字化進入深水區,百萬行代碼的老系統就像一座隨時可能崩塌的"技術債冰山"。近日,飛算科技發布JavaAI…

Linux I2C 子系統全解:結構、機制與工程實戰

Linux I2C 子系統全解:結構、機制與工程實戰 前言 I2C(Inter-Integrated Circuit)作為嵌入式系統和各種電子產品中最常用的串行通信總線之一,在 Linux 內核中的地位極其重要。然而,Linux I2C 子系統的分層結構、對象模…

多線程編程技術解析及示例:pthread_cond_timedwait、pthread_mutex_lock 和 pthread_mutex_trylock

多線程編程技術解析及示例:pthread_cond_timedwait、pthread_mutex_lock 和 pthread_mutex_trylock 摘要 本文深入解析了多線程編程中 pthread_cond_timedwait、pthread_mutex_lock 和 pthread_mutex_trylock 三個函數的功能、使用場景及注意事項,并通…

元胞自動機(Cellular Automata, CA)

一、什么是元胞自動機(Cellular Automata, CA) 元胞自動機(CA) 是一種基于離散時間、離散空間與規則驅動演化的動力系統,由 馮諾依曼(John von Neumann) 于1940年代首次提出,用于模…

Flutter面試題

Flutter架構解析 1. Flutter 是什么?它與其他移動開發框架有什么不同? Flutter 是 Google 開發的開源移動應用開發框架,可用于快速構建高性能、高保真的移動應用(iOS 和 Android),也支持 Web、桌面和嵌入式設備。。它與其他移動開發框架(如 React Native、Xamarin、原…

MySQL 如何判斷某個表中是否存在某個字段

在MySQL中,判斷某個表中是否存在某個字段,可以通過查詢系統數據庫 INFORMATION_SCHEMA.COLUMNS 實現。以下是詳細步驟和示例: 方法:使用 INFORMATION_SCHEMA.COLUMNS 通過查詢系統元數據表 COLUMNS,檢查目標字段是否存…

golang 實現基于redis的并行流量控制(計數鎖)

在業務開發中,有時需要對某個操作在整個集群中限制并發度,例如限制大模型對話的并行數。基于redis zset實現計數鎖,做個筆記。 關鍵詞:并行流量控制、計數鎖 package redisutilimport ("context""fmt""…

從線性方程組角度理解公式 s=n?r(3E?A)

從線性方程組角度理解公式 sn?r(3E?A) 這個公式本質上是 ?齊次線性方程組解空間維度 的直接體現。下面通過三個關鍵步驟解釋其在線性方程組中的含義: 1. ?公式對應的線性方程組 考慮矩陣方程: (3E?A)x0 其中: x 是 n 維未知向量3E?…

Docker 在 AI 開發中的實踐:GPU 支持與深度學習環境的容器化

人工智能(AI)和機器學習(ML),特別是深度學習,正以前所未有的速度發展。然而,AI 模型的開發和部署并非易事。開發者常常面臨復雜的依賴管理(如 Python 版本、TensorFlow/PyTorch 版本、CUDA、cuDNN)、異構硬件(CPU 和 GPU)支持以及環境復現困難等痛點。這些挑戰嚴重阻…

解決CSDN等網站訪問不了的問題

原文網址:解決CSDN等網站訪問不了的問題-CSDN博客 簡介 本文介紹解決CSDN等網站訪問不了的方法。 問題描述 CSDN訪問不了了,頁面是空的。 問題解決 方案1:修改DNS 可能是dns的問題,需要重新配置。 國內常用的dns是&#x…

使用tortoisegit連接遠程倉庫進行克隆、拉取、獲取、提交、推送、新建/切換分支、重命名、刪除的一套流程(附帶巨全面的git命令)

1.整備好tortoisegit工具。 2.新建一個文件夾,并進入這個文件夾后鼠標右擊(選擇克隆): 3.先去項目中拿到https地址,再填入: 4.新建分支,右擊克隆到本地的項目文件: 5.推送到遠程&am…

ArcGIS Pro 3.4 二次開發 - 地圖創作 1

環境:ArcGIS Pro SDK 3.4 + .NET 8 文章目錄 ArcGIS Pro 3.4 二次開發 - 地圖創作 11 樣式管理1.1 如何通過名稱獲取項目中的樣式1.2 如何創建新樣式1.3 如何向項目添加樣式1.4 如何從項目中移除樣式1.5 如何向樣式添加樣式項1.6 如何從樣式中移除樣式項1.7 如何判斷樣式是否可…