程序是如何生成的-以c語言為例

一,序言

從代碼到能跑的程序,整個過程就像 “把外文翻譯成母語,再組裝成能直接用的東西”,一步步來更清楚:

源代碼(程序員寫的代碼,如C語言文件)↓
預處理(處理#開頭的命令,如#include、#define)↓
編譯(把預處理后的代碼轉成匯編語言)↓
匯編(把匯編語言轉成二進制機器碼,生成目標文件,如main.o)↓
鏈接(合并多個目標文件和庫文件,解決函數/變量地址問題)↓
可執行文件(生成能直接運行的文件,如.exe、ELF格式)↓
加載運行(操作系統把文件加載到內存,開始執行代碼)

二,相關步驟簡介

一、源代碼:程序員寫的 “原始稿”

就是我們用編程語言(比如 C 語言)寫的代碼,比如這個打印 “你好世界” 的小程序:

#include <stdio.h>
int main() {printf("Hello, World!\n");return 0;
}

二、預處理:先 “整理” 代碼

用預處理器(比如 GCC 里的 cpp)處理代碼里帶#的命令,讓代碼更 “干凈”:
1,比如#include <stdio.h>,會直接把 stdio.h 文件里的內容 “復制粘貼” 到代碼里(因為 printf 函數的定義就在這個文件里);
2,要是有#define PI 3.14,會把代碼里所有 “PI” 換成 “3.14”;
3,還能根據#ifdef這類命令,選擇性保留代碼(比如調試時用一段,發布時用另一段)。

處理完后,代碼里就沒有#命令了,只剩純代碼。

三、編譯:翻譯成 “匯編語言”

用編譯器(比如 GCC 里的 cc1)把預處理后的代碼,轉成電腦硬件能理解的 “匯編語言”(相當于 “二進制的半成品”)。

過程中會檢查代碼對不對:比如語法錯了(少個括號)、類型不匹配(整數函數返回空值)都會報錯。

舉個例子,前面的代碼會變成類似這樣的匯編:

main:推棧操作準備"Hello, World!"這個字符串調用printf函數返回0出棧操作

四、匯編:轉成 “二進制指令”

用匯編器(比如 GCC 里的 as)把匯編語言轉成電腦能直接執行的 “二進制機器碼”,生成 “目標文件”(比如 main.o)。

這個文件里存著:
1,代碼段:二進制的指令(比如調用 printf 的操作);
2,數據段:已經初始化的變量(比如int a=10);
3,符號表:記著變量、函數的位置(比如 printf 在哪兒)。

五、鏈接:拼出 “能跑的程序”

用鏈接器(比如 GCC 里的 ld)把多個目標文件(比如自己寫的 main.o,還有系統提供的庫文件)合并成一個 “可執行文件”。

核心是解決 “找不到東西” 的問題:比如代碼里用了 printf,但目標文件里只知道有這個函數,不知道它在哪兒 —— 鏈接器會找到它在標準庫(比如 libc)里的實際位置,把地址填對。

鏈接分兩種:
1,靜態鏈接:直接把庫代碼(比如 printf 的實現)復制到可執行文件里,文件會變大,但能獨立運行;
2,動態鏈接:只記著依賴哪個庫(比如 libc.so),運行時再加載,文件小,但需要系統里有這個庫。

六、可執行文件:最終的 “成品”

生成的文件(比如 Windows 的.exe、Linux 的 ELF 文件)里有:
1,文件頭:告訴系統怎么加載它、從哪兒開始執行;
2,代碼和數據:合并后的二進制指令、變量;
3,動態鏈接信息(如果用了動態鏈接):記著需要哪些庫。

七、運行:雙擊就能跑

雙擊可執行文件后,操作系統會:
1,給它分配內存,建個 “進程”;
2,把文件里的代碼、數據從硬盤讀到內存;
3,如果是動態鏈接,會加載需要的庫;
4,最后跳到入口點(比如 main 函數),開始執行代碼 —— 屏幕上就會顯示 “Hello, World!” 啦。

編譯型 vs 解釋型語言,簡單說:

類型編譯型(比如 C/C++)解釋型(比如 Python)
執行前先編譯 + 鏈接,生成單獨的可執行文件不用編譯,直接用解釋器一行行讀代碼跑
速度快(直接跑機器碼)稍慢(每次都要解釋)
跨平臺不同系統可能要重新編譯(比如 Windows 和 Linux)一次寫完,有解釋器就能跑

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

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

相關文章

風險識別清單:構建動態化的風險管理體系

在項目管理實踐中&#xff0c;風險識別是確保項目成功的關鍵環節。PMBOK提出的風險提示清單&#xff08;Prompt List&#xff09;為項目團隊提供了一個系統化的思考框架&#xff0c;幫助突破個人經驗局限&#xff0c;實現更全面的風險覆蓋。這一工具的價值不僅在于其提供的標準…

從“點狀用例”到“質量生態”:現代軟件測試的演進、困局與破局

測試的三次范式躍遷業務高速迭代下的四大困局質量工程化&#xff1a;流程、平臺、度量三位一體左移與右移&#xff1a;把缺陷扼殺在搖籃&#xff0c;也把監控鋪到墳墓自動化金字塔的再平衡&#xff1a;UI、API、單元、契約、e2e數據驅動測試&#xff1a;從“拍腦袋”到“科學實…

【C++】繼承和多態擴展學習

目錄 1. 菱形虛擬繼承原理剖析 1.1.虛基表 2. 單繼承和多繼承的虛函數表深入探索 2.1 單繼承虛函數表深入探索 2.2 多繼承虛函數表深入探索 ?編輯 2.3 菱形繼承、菱形虛擬繼承 3. 繼承和多態考察的一些常見問題 1. 菱形虛擬繼承原理剖析 繼承的文章中我們講到C的多繼承…

Visual Studio Code 遠端云服務器開發使用指南

目錄 一、下載安裝 1、官方下載 2、下載加速方案 二、基于Ubuntu系統的開發環境搭建方案 1、開發環境配置 2、云服務器架構 3、工作流程關系 4、總結 三、推薦插件 1、免配置插件 1. Remote-SSH - 遠程登錄Linux服務器 2. C/C - 必備的C/C開發插件 3. C/C Extensi…

技術演進中的開發沉思-41 MFC系列:定制 AppWizard

MFC開發&#xff0c;最為重要的無非就是用“MFC AppWizard” 對話框做開發了&#xff0c;第一次使用感覺像拆收音機的孩子 —— 左邊是項目類型選擇&#xff0c;右邊是一堆打勾的選項&#xff0c;點完 “完成”&#xff0c;屏幕上就冒出了能直接編譯運行的窗口程序。那時還不知…

Libevent(3)之使用教程(2)創建事件

Libevent(3)之使用教程(2)創建事件 Author: Once Day Date: 2025年6月29日 一位熱衷于Linux學習和開發的菜鳥&#xff0c;試圖譜寫一場冒險之旅&#xff0c;也許終點只是一場白日夢… 漫漫長路&#xff0c;有人對你微笑過嘛… 本文檔翻譯于&#xff1a;Fast portable non-bl…

Kotlin 作用域函數 let 的實現原理

Kotlin 中的 let 是一個 標準庫擴展函數&#xff0c;它廣泛用于作用域函數&#xff08;Scope Functions&#xff09;中&#xff0c;尤其適用于對可空對象&#xff08;nullable&#xff09;做非空判斷并執行代碼塊的場景。 示例代碼 val name: String? "123" name?…

從FDTD仿真到光學神經網絡:機器學習在光子器件設計中的前沿應用工坊

FDTD仿真與光學神經網絡的基礎概念 FDTD&#xff08;時域有限差分&#xff09;是一種數值方法&#xff0c;用于求解麥克斯韋方程組&#xff0c;廣泛應用于光子器件設計。光學神經網絡通過光波導、衍射元件等物理結構實現矩陣運算&#xff0c;具有低能耗、高并行的優勢。 機器學…

在Ubutu22系統上面離線安裝Go語言環境【教程】

0.引言 Go語言&#xff08;又稱Golang&#xff09;是Google開發的一種靜態強類型、編譯型、并發型編程語言&#xff0c;由Robert Griesemer、Rob Pike和Ken Thompson于2007年開始設計&#xff0c;2009年正式發布。 1.到官網下載壓縮包 2.從win10系統離線上傳壓縮包給ubuntu22…

CMake實踐:CMake3.30版本之前和之后鏈接boost的方式差異

目錄 1.背景 2.boost引入CMake時機 3.CMake 3.30 之前&#xff08;含 3.29&#xff09;鏈接 Boost 的方式 4.CMake 3.30 及之后鏈接 Boost 的方式 5.CMake3.30后引入Boost的步驟 6.遷移建議&#xff08;3.30 之前 → 3.30 之后&#xff09; 7.CMake 3.30 移除FindBoost的…

告別掛馬風險!PBootCMS完美替代方案BadouCMS

開發企業網站時一直比較喜歡用pbootcms,標簽套用很簡單&#xff0c;使用也方便。 但是pbootcms一直有被掛馬的問題&#xff0c;官方好像也不怎么更新了&#xff01;換過好幾個cms&#xff0c;比如eyoucms、dedecms、帝國等等&#xff0c;感覺都不怎么能用得習慣&#xff0c;還…

開發者如何集成AI繪畫?智創聚合API簡化Midjourney接入

在 AI 繪畫領域&#xff0c;Midjourney 的大名如雷貫耳&#xff0c;其強大的圖像生成能力&#xff0c;能將我們腦海中的奇思妙想&#xff0c;迅速轉化為精美的視覺畫面&#xff0c;深受設計師、藝術家以及廣大創意愛好者的青睞。然而&#xff0c;使用 Midjourney 的過程中&…

pycharm回車、刪除、方向鍵和快捷鍵等不能使用原因

解決方法 &#xff1a;菜單欄中的Tools取消勾選Vim Emulator 原因 &#xff1a;新版的pycharm安裝中&#xff0c;默認安裝了vim擴展&#xff0c;一旦安裝了pycharm在編寫代碼時會默認使用Vim編輯器

修復ffmpeg.dll丟失錯誤|6種解決ffmpeg.dll方法詳細教程

看到電腦提示“ffmpeg.dll丟失”&#xff0c;很多人會懵。ffmpeg.dll 是個處理視頻、音頻的關鍵文件。它要是沒了或壞了&#xff0c;軟件就打不開或直接閃退。常見原因是軟件安裝不全、文件被刪、或者中病毒。下面說說它是干嘛的&#xff0c;再給解決辦法。一.ffmpeg.dll 到底是…

OkHttp 與 Stetho 結合使用:打造強大的 Android 網絡調試工具鏈

前言在 Android 應用開發過程中&#xff0c;網絡請求的調試一直是一個重要但具有挑戰性的環節。Facebook 開發的 Stetho 是一個強大的調試工具&#xff0c;當它與 OkHttp 結合使用時&#xff0c;可以為我們提供前所未有的網絡請求洞察能力。本文將詳細介紹如何將這兩者結合使用…

LangGraph教程10:LangGraph ReAct應用

文章目錄 ReAct 預構建的代理 向 ReAct 代理添加記憶 向 ReAct 代理添加系統提示 向 ReAct 代理添加人機交互 ReAct 官方文檔地址:https://langchain-ai.github.io/langgraph/how-tos/#prebuilt-react-agent 中文文檔地址:https://www.aidoczh.com/langgraph/how-tos/#react…

安卓第一個項目

測試所有攝像頭 安卓CameraX&#xff1a;https://developer.android.com/media/grow/spatial-audio?hlzh-cn 1、MainActivity.java // 定義包名 package com.mms.densenapplication;// 引入 AppCompatActivity&#xff0c;支持兼容性更強的 Activity import androidx.appcompa…

Google Gemini 體驗

文章中代碼倉庫 gemini 谷歌推出的 AI 只能模型 Gemini官網Gemini ChatGemini開發者文檔Gemini SDK 所有模型 模型變體輸入輸出優化目標Gemini 2.5 Pro gemini-2.5-pro音頻、圖片、視頻、文本和 PDF文本增強的思考和推理能力、多模態理解能力、高級編碼能力等Gemini 2.5 Fla…

Trae安裝指定版本的插件

前情 Trae是屬于國產的跟 Cursor類似的AI編程IDE&#xff0c;我也是第一時間體驗Trae的&#xff0c;雖然相比Cursor弱了一些&#xff0c;但是也絕對勝任了&#xff0c;前端因為排隊問題我轉戰了Cursor&#xff0c;等到Trae出收費模式前&#xff0c;我已經辦了Cursor會員了&…

【技術追蹤】用于醫學圖像合成和分割的噪聲一致孿生擴散模型(CVPR-2025)

孿生擴散模型&#xff0c;生成息肉圖像用于提升分割性能&#xff01; 論文&#xff1a;Noise-Consistent Siamese-Diffusion for Medical Image Synthesis and Segmentation 代碼&#xff1a;https://github.com/Qiukunpeng/Siamese-Diffusion 0、摘要 深度學習已徹底革新醫學影…