程序是如何生成的-以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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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、摘要 深度学习已彻底革新医学影…