《C语言》编译和链接

文章目录

    • 一、翻译环境
        • 1、预处理
        • 2、编译
        • 3、汇编
        • 4、链接
    • 二、运行环境

一、翻译环境

在使用编译器编写代码时,编写的代码是高级语言,机器无法直接识别和运行,在编译器内部会翻译成机器可执行的机器语言。
编译环境由编译和链接两大过程组成。
编译分为:预处理(预编译)、编译、汇编三个过程。

1、预处理

在预处理阶段,把源文件和头文件会被处理成为.i后缀的文件。
在gcc环境下,对test.c文件预处理后的.i文件,命令如下:

gcc -E test.c -o test.i

预处理阶段主要处理#开头的预编译指令。比如:#include,#define等,处理规则如下:

  • 将#define定义的常量名替换为常量值,将#define定义的宏替换为表达式。
  • 将#if后不满足条件的删除,#if 和 #endif 组合使用,#if覆盖的代码块到#endif结束,还有#ifdef、#elif、#else等条件预处理指令代码
  • 处理#include预编译指令,将头文件的内容插入到该预处理指令的位置。这个过程是递归进行的,也就是说被包含的头文件也可能包含其他头文件。
  • 删除所有注释: /* */代码块注释,//行注释
  • 添加行号和文件名标识,方便后续编译器生成调试信息等。
  • 或保留所有的#pragma的编译指令,编译器后续会使用。

经过预处理后的.i文件中不再包含宏定义,因为宏已经被展开。并且包含的头文件都被插入到.i文件中。所以当我们无法知道宏定义或者头文件是否包含正确的时候,可以查看预处理后的.i文件来确定。

2、编译

编译过程是对预处理后的文件进行的处理:词法分析语法分析语义分析及优化,生成相应的汇编代码文件。
变异过程的命令如下:

gcc -S test.i -o test.s

(1)词法分析

将源代码程序输入扫描器,扫描器的任务就是简单的进行词法分析,把代码中的字符分割成一系列的记号(关键字、标记符、字面量、特殊字符等)。

(2)语法分析

词法分析结束,就是语法分析,将对扫描产生的记号进行语法分析,从而产生语法树。这些语法树是以表达式为节点的树。

(3)语义分析

由语义分线器来完成语义分析,即对表达式的语法层面分析。编译器所能做的分析是语义的静态分析。静态语义分析通常包括声明和类型的匹配,类型的转换等。这个阶段会报告错误的语法信息。

3、汇编

汇编是将汇编代码转换变成机器可执行的指令,每一个汇编语句几乎都对应一条机器指令。就是根据汇编指令和机器指令的对照表一一的进行翻译,也不做指令优化。
汇编的命令如下:

gcc -c test.s -o test.o
4、链接

链接是一个复杂的过程,链接的时候需要把一堆的文件链接在一起才生成可执行程序。
链接过程主要:地址和空间分配,符号决议和重定位等这些步骤。
链接解决的是一个项目中多个文件、多个模块之间互相调用的问题。
链接会生成一个表记录函数名有没有被声明,变量名赋值等等,一个文件定义了一个函数,另一个文件中没有声明这个函数也可以使用的原因就是因为链接产生的效果。

在这里插入图片描述
在study.c文件中没有声明和定义Fibonacci这个函数

在这里插入图片描述
在test.c中声明和定义了这个函数

在运行时,仍然可以成功且没有报错。
在这里插入图片描述
标准写法应用extern来声明外部符号
在这里插入图片描述

二、运行环境

1、程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2、程序的执行便开始。接着便调用main函数。
3、开始执行程序代码。这个时候程序使用一个运行栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留它们的值。
4、终止程序。正常终止main函数;也可能是意外终止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/360383.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CT】LeetCode手撕—23. 合并 K 个升序链表

目录 题目1- 思路2- 实现⭐23. 合并 K 个升序链表——题解思路 3- ACM 实现 题目 原题连接:23. 合并 K 个升序链表 1- 思路 模式识别:合并 K 个链表 ——> 优先队列 思路 借助优先队列,每次从 k 个链表中,各取一个元素&…

【Docker】存储数据卷

目录 1、挂载数据卷到容器里 2、查询挂载文件 3、容器与主机之间映射共享卷 4、三个容器之间使用共享卷 5、卷数据的备份与恢复 5.1 备份 5.2 恢复 1、挂载数据卷到容器里 docker run -itd --name test02 -v /data nginx docker exec -it test02 bashls / docker inspe…

MySQL MVCC详解

目录 前言 MVCC实现原理 UndoLog版本链 ReadView MVCC是否可以解决不可重复读与幻读 隔离级别 READ UNCOMMITTED - 读未提交与脏读 READ COMMITTED - 读已提交与不可重复读 REPEATABLE READ - 可重复读与幻读 SERIALIZABLE - 串行化 小结 前言 为了提高数据库并发能力…

JVM虚拟机的组成

一、为什么要学习 JVM ? 1. “ ⾯试造⽕箭,⼯作拧螺丝” , JVM 属于⾯试官特别喜欢提问的知识点; 2. 未来在⼯作场景中,也许你会遇到以下场景: 线上系统突然宕机,系统⽆法访问,甚⾄直…

前后端交互的弯弯绕绕

前后端交互: 🆗,收拾一下心情让我们来聊一聊AJax吧,随着前端的飞速发展,前后的交互也发生了天翻地覆的变化: 前后端交互的方式有很多: AJAX、表单提交、WebSocket、RESTful API、... 这对新入…

查看es p12证书文件过期方法

查看证书过期时间: openssl pkcs12 -in elastic-certificates.p12 -nokeys -out elastic-certificates.crt (需要输入证书生成时配置密码) openssl x509 -enddate -noout -in elastic-certificates.crt

使用 GitOps 进行防灾 MinIO

想象一下,您已经花费了无数小时来完善 Docker Swarm 设置,精心设计每项服务,并调整 CI/CD 管道以实现无缝自动化。现在,想象一下这个经过微调的系统被重置为原点,不是因为严重的故障或安全漏洞,而是因为数据…

了解SD-WAN与传统WAN的区别

近年来,许多企业选择了SD-WAN作为他们的网络解决方案。云基础架构的SD-WAN不仅具备成本效益,而且提供更安全、更可靠的WAN连接,有助于实现持续盈利。客户能够更好地控制他们的网络,个性化定制且无需额外成本。 那么,为…

基于JSP的列车票务信息管理系统

开头语: 你好,我是专注于计算机科学与技术研究的学长。如果你对列车票务信息管理系统感兴趣或有相关需求,欢迎联系我。 开发语言:Java 数据库:MySQL 技术:JSP技术 工具:IDE、数据库管理工具…

基于SpringBoot小区物业智能卡管理设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟感兴趣的可以先收藏起来,还…

【SQL Server数据库】带函数查询和综合查询(1)

目录 1.统计年龄大于30岁的学生的人数。 2.统计数据结构有多少人80分或以上。 3.查询“0203”课程的最高分的学生的学号。 4.统计各系开设班级的数目(系名称、班级数目),并创建结果表。 5.选修了以“01”开头的课…

Spark SQL 血缘解析方案

背景 项目背景建设数据中台,往往数据开发人员首先需要能够通过有效的途径检索到所需要的数据,然后根据检索的数据模型进行业务加工然后得到一些中间模型,最后再通过数据抽取工具或者OLAP分析工具直接将数据仓库中加工好的公共模型输出到应用层。这里我不在去介绍数据仓库为…

Python 围棋

效果图 完整代码 源码地址:Python 围棋 # 使用Python内置GUI模块tkinter from tkinter import * # ttk覆盖tkinter部分对象,ttk对tkinter进行了优化 from tkinter.ttk import * # 深拷贝时需要用到copy模块 import copy import tkinter.me…

性能测试(五)—— 数据库性能测试-mysql

1 mysql性能测试的主要内容 MySQL数据库介绍MySQL数据库监控指标MySQL慢查询工作原理及操作SQL的分析与调优方法MySQL索引的概念及作用MySQL索引的工作原理与设计规范MySQL存储引擎MySQL实时监控MySQL集群监控方案MySQL性能测试的用例准备使用Jmeter开发MySQL性能测试脚本执行…

鸿蒙NEXT实战开发: 依据前端对http请求进行二次简单封装

一、为什么要对http请求进行封装? 在我看来二次封装有一下几点好处 代码封装之后,开发人员只用关注业务层面的东西,不用去过多浪费时间在接口请求数据处理上。封装之后代码更加简洁,通俗易懂,方便后期维护&#xff0…

微服务中的相关概念

Eureka Eureka 是由 Netflix 开发的一个服务发现和注册中心,广泛应用于微服务架构中。Eureka 主要用于管理和协调分布式服务的注册和发现,确保各个服务之间能够方便地找到并通信。它是 Netflix OSS(Netflix Open Source Software&#xff09…

OpenAI突然宣布停止向中国提供API服务!

标题 🌟 OpenAI突然宣布停止向中国提供API服务! 🌟摘要 📜引言 📢正文 📝1. OpenAI API的重要性2. 停止服务的原因分析3. 对中国市场的影响4. 应对措施代码案例 📂常见问题解答(QA)❓…

OpenAI禁止国区使用:免费国产大模型等你体验!

OpenAI中国停服 国产大模型免费使用 前言 OpenAI不支持中国区域访问 从6月25日开始,OpenAI 宣布了对中国停止提供 API 服务,毫无疑问的说这给国内的开发者带来了很大的不便,之后他们怎么去使用GPT 这类先进大模型方面遇到了难题。不过近期我们…

【ARMv8/ARMv9 硬件加速系列 3.4 -- SVE 复制指令CPY 使用介绍】

文章目录 SVE 复制指令CPYSVE 指令格式SVE 使用语法SVE CPY 使用示例SVE CPY 小结SVE 复制指令CPY CPY <Zd>.<T>, <Pg>/M, #<imm>{, <shift>}cpy 指令在 ARMv9 的

让我们聊聊网络安全中会涉及到的IP地址(IP协议)、MAC地址、路由、DNS协议(域名系统)、NAT技术(协议)、以太网帧、ARP协议

网络安全中会涉及到的IP地址&#xff08;IP协议&#xff09;、MAC地址、路由、DNS协议&#xff08;域名系统&#xff09;、NAT技术&#xff08;协议&#xff09;、以太网帧、ARP协议 一.IP地址&#xff08;IP协议&#xff09;1.IP地址&#xff08;IP协议&#xff09;的作用2.IP…