07 编译器

目录

  1. 编译过程
  2. 编译器查看
  3. 详解
  4. 函数库
  5. 自动化构建工具
  6. 进度条程序

1. 编译过程

预处理: a. 去注释 b.宏替换 c.头文件展开 d.条件编译
编译: 汇编
汇编: 可重定向二进制目标文件
链接: 链接多个.o, .obj合并形成一个可执行exe
gcc编译c程序, g++编译c++程序

2. 编译器查看

输入gcc -v , g++ -v ,查看编译器的版本,如果不存在g++,可以用命令安装

sudo yum install -y gcc-c++

在这里插入图片描述

3. 详解

如果要编译成可执行文件,首先编写一个.c文件,然后输入:

gcc [选项] 要编译的文件 [选项] [目标文件]

例如: gcc code.c -o myexe , -o后面带要生成的程序名
在这里插入图片描述

3.1 预处理

预处理功能主要包括宏定义、文件包含展开,条件编译,去注释等
预处理指令是以#号开头的代码行
实例: gcc -E hello.c -o hello.i
E的作用是让预处理后停止编译,选项-o是生成目标文件,不然会打印在屏幕上,.i为预处理后的文件

准备要一份这样的源代码:

  1 #include <stdio.h>
  2 #define M 100
  3 
  4 int main()
  5 {
  6     printf("hello %d\n ", M);
  7 
  8     //条件编译
  9 #ifdef DEBUG 
 10     printf("debug\n");
 11 #else
 12     printf("release\n");
 13 #endif                                                                                        
 14     return 0;
 15 }

执行预处理结果:

在这里插入图片描述
打开源代码和生成的.i文件对比
在这里插入图片描述

上面的840行才到main函数,前面的一大段部分是include头文件展开的结果,里面都是头文件函数的声明。define定义的宏M直接用100替换了输出的地方。条件编译这四个注释的字也去了,因为gcc默认编译为release模式,所以条件编译只保留条件成立的结果

3.2 编译

这个阶段首先检查代码的规范性,语法错误以及实际要做的工作,确保无误后翻译成汇编语言

实例:

gcc -S [.i文件] -o [文件名.s]

源文件翻译完成停止编译,将上面的.i 文件编译成.s文件查看
在这里插入图片描述在这里插入图片描述

3.3 汇编

生成机器识别的二进制代码,实例:

gcc -c hello.s -o hello.o

将上面的汇编文件转换为二进制目标文件查看

在这里插入图片描述在这里插入图片描述
由于是二进制文件,编辑器不能识别,所以显示为乱码

3.4 链接

生成可执行文件或库文件
实例:

gcc hello.o -o hello

4. 函数库

我们的程序中并没有printf函数的实现,而且预处理后也只有函数的声明,那是在哪里实现的printf函数

输入 file [程序名]
在这里插入图片描述
这里说动态链接分享的库,答案是这些函数的实现都在名为libc.so.6的库文件中,gcc会在路径/usr/bin目录下寻找,就能链接到库函数

/usr/include目录下有函数头文件,提供c语言函数的声明
在这里插入图片描述

ldd [程序]可以看到依赖的库,提供函数的实现
在这里插入图片描述

库分为动态库和静态库
静态库是编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,运行时也不需要库文件了
动态库是一个包含可由多个程序同时使用的代码和数据的库,动态链接提供了一种方法地址,程序执行时去找对应的函数实现
win:.dll 是动态库 .lib是静态库
linux: .so是动态库 .a是静态库

静态库需要拷贝函数实现所以文件更大,动态库生成的程序更小
gcc/g++默认动态链接的,输入命令使用静态链接

gcc [文件] -o [程序名] -static

在这里插入图片描述
静态链接的文件体积大很多

如果没有静态库,可以安装

sudo yum install -y glibc-static
sudo yum install -y libstdc+±static

gcc选项

-E 只激活预处理,不生成文件,需要重定向到输出文件
-S 编译到汇编语言不进行汇编和链接
-c 编译到目标代码
-o 文件输出到文件
-static 此选项仅对生成的文件采用静态链接
-g 生成调试信息,GNU调试器可利用该信息
-shared 尽量使用动态库,生成文件较小,需要有动态库
-O0
-O1
-O2
-O3 编译器优化的四个级别,0表示没有优化,1为缺省值,3最高
-w 不生成任何警告信息
-Wall 生成所有警告信息

可以记忆为编译选项Esc ,生成iso文件

5. 自动化构建

make和makefile

一个工程中的源文件不计其数,放在若干个目录中,makefile定义了一系列规则,哪些
文件需要先编译,哪些文件后编译,什么时候重新编译
带来的好处就是自动化编译,一旦写好,以后只需要调用,极大提高了开发效率。
make是一个命令工具,解释makefile指令的工具,一般来说大多数ide都有这个命令,如:Delphi的make,vc的nmake,linux下GNU的make
make是命令,makefile是文件,两个搭配使用

自动化构建的makefile需要明确两个东西,依赖关系和依赖方法,依赖关系自顶向下匹配,所以把首先把依赖关系根部的写最前面

准备三个文件,一个头文件和实现,一个main函数
头文件,add.h
在这里插入图片描述

实现 add.c
在这里插入图片描述

main文件 main.c
在这里插入图片描述

先用gcc编译一下程序有没有错误

在这里插入图片描述
创建一个makefile文件,用来自动化构建
在这里插入图片描述
mytest是要生成的程序名,依赖于add.o和main.o两个文件,这两个文件各自又依赖于源文件,gcc生成这两个源文件,最后加clean的依赖关系和依赖方法,删除所有临时文件和程序

输入make就会自动生成程序
在这里插入图片描述
输入make clean就会清楚项目
在这里插入图片描述

当多次make会显示程序已经是最新的了
在这里插入图片描述

这是因为程序如果已经是最新的,就没必要继续生成。makefile如何得知程序是最新的?。前面说过文件有acm时间,a是访问时间,因为是频繁操作所以达到一定量会刷新,c是内容修改时间,m是文件属性修改时间,一般内容修改,文件大小也会变化。一般情况下,生成的程序的修改时间应该是最晚的,make时会对比依赖的两个源文件是否有内容变化,如果这两个文件的修改时间晚于程序的时间,就说明内容有变化,这时可以make生成

我们修改一下main文件的参数重新make
在这里插入图片描述
修改后就可以构建了

.PHONY的依赖关系总是被执行的,这个如何理解
当我们构建时,如果程序是最新的将无法生成,但我们执行clean却不受时间限制,每次都可以执行,这就是总是可以执行

在写项目时,makefile先确保没问题再写项目

6. 进度条程序

\r和\n两个是不同的功能,在最初的计算机中,\n用来换行,而光标还在上一行的位置,\r回车用来重新回到本行开头,所以到下一行开头就是\r\n

#include <stdio.h>    
    
int main()    
{    
    printf("hello \r");    
    return  0;                                                                                     
}    

输入上面程序执行
发现什么都没有打印,这是因为\r让光标回到了最开头所以没有文本。在计算机里,输出并不是立即输出,有一个输出缓冲区的概念,有自己的刷新规则。碰到\n会把\n之前的内容刷新到目标设备。也可以用一些强制刷新缓冲区的函数,如:fflush(stdout)函数

制作进度条,每次打印增加的部分和百分比,都在同一行不断刷新,不换行。这个可以用\r打印

#include <stdio.h>    
#include <unistd.h>    
       
int main()    
{      
    int cnt = 1;    
    char str[100]= {0};    
    while(cnt <=50)    
    {    
    str[cnt - 1] = '#';    
    printf("[进度][%-50s](%d%%) \r", str,cnt*2);    
    fflush(stdout);    
    usleep(30000);    
    cnt++;    
    }     
       
    printf("\n");                                                                               
    return 0;                                                
}  

由于屏幕不够,每行打印50个扩大2倍作为百分百,usleep可以查询,是一个延时的函数,单位是微秒,上面是0.3秒一打印
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言-----动态内存管理(1)

1.引入 我们之前已经学习了几种开辟内存空间的方式&#xff1a; &#xff08;1&#xff09;int a10;开辟4个字节大小的空间 &#xff08;2&#xff09;int arr[10]{0}定义数组开辟了一串连续的空间 2.malloc和free (1)malloc开辟内存空间可能会失败&#xff0c;因此需要检查…

leetcode括号生成

题目描述 解题思路 首先看到题目&#xff0c;一开始是并没有思路的。这时候可以在纸上进行演算一下结果。当只有一对括号的时候&#xff0c;我们可以得知结果[“()”],当有两对括号的时候&#xff0c;我们可以发现&#xff0c;括号在第一个基础上&#xff0c;要么在括号内部出…

【EAI 026】RoboGen: 通过自动数据生成管线实现机器人技能学习

Paper Card 论文标题&#xff1a;RoboGen: Towards Unleashing Infinite Data for Automated Robot Learning via Generative Simulation 论文作者&#xff1a;Yufei Wang, Zhou Xian, Feng Chen, Tsun-Hsuan Wang, Yian Wang, Zackory Erickson, David Held, Chuang Gan 作者单…

瑞_Redis_Redis客户端

文章目录 1 Redis客户端1.1 Redis命令行客户端1.2 图形化桌面客户端1.2.1 资源准备1.2.2 安装1.2.3 建立连接附&#xff1a;解决Liunx防火墙和开放端口号 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《Redis》的基础篇的Redis客户端章节。由于博主是从B站黑马程序员的…

GraphPad Prism 10: 你的数据,我们的魔法 mac/win版

GraphPad Prism 10是GraphPad Software公司推出的一款功能强大的数据分析和可视化软件。它集数据整理、统计分析、图表制作和报告生成于一体&#xff0c;为科研工作者、学者和数据分析师提供了一个高效、便捷的工作平台。 GraphPad Prism 10软件获取 Prism 10拥有丰富的图表类…

接口测试(全)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 大多数人对于接口测试都觉得是一种高大上的测试&#xff0c;觉得…

《无线网络技术》考试版笔记

第一章 无线网络介绍 什么是多径效应&#xff0c;如何去克服&#xff1a; 在发射机和接收机之间没有明显的直线路径时&#xff0c;就会产生多径传播。如果两个信号彼此叠加&#xff0c;那么接收设备就无法正确解调信号&#xff0c;无法还原为它的原始数据形式。 可以稍微调整接…

NOC2023软件创意编程(学而思赛道)python小高组初赛真题

软件创意编程 一、参赛范围 1.参赛组别:小学低年级组(1-3 年级)、小学高年级组(4-6 年级)、初中组。 2.参赛人数:1 人。 3.指导教师:1 人(可空缺)。 4.每人限参加 1 个赛项。 组别确定:以地方教育行政主管部门(教委、教育厅、教育局) 认定的选手所属学段为准。 二、…

LeetCode 热题 100 | 图论(二)

目录 1 基础知识 1.1 什么是拓扑排序 1.2 如何进行拓扑排序 1.3 拓扑排序举例 2 207. 课程表 3 210. 课程表 II 菜鸟做题&#xff0c;语言是 C 1 基础知识 1.1 什么是拓扑排序 含义&#xff1a;根据节点之间的依赖关系来生成一个有序的序列。 应用&#xff1a…

【Java数据结构 -- 二叉树+树的深度优先遍历】

二叉树 1. 二叉树1.1 二叉树的介绍1.2 两种特殊的二叉树1.3 二叉树的性质1.4 二叉树的存储 2. 二叉树的基本操作2.1 二叉树的创建2.2 二叉树的优先遍历2.3 递归实现二叉树遍历2.4 用非递归实现二叉树遍历 1. 二叉树 1.1 二叉树的介绍 二叉树是一种数据结构&#xff0c;一颗二…

虚拟机数据恢复-虚拟机误还原快照后如何恢复还原前的数据?

虚拟机数据恢复环境&故障&#xff1a; 由一台物理服务器迁移到ESXI上的虚拟机&#xff0c;虚拟机迁移完成后做了一个快照&#xff0c;该ESXI上面一共运行了数十台虚拟机。某天工作人员不小心将快照进行了还原&#xff0c;虚拟机内的数据还原到了数年前刚迁移过来时的状态&a…

超详细的 pytest 钩子函数 之初始钩子和引导钩子来啦

前几篇文章介绍了 pytest 点的基本使用&#xff0c;学完前面几篇的内容基本上就可以满足工作中编写用例和进行自动化测试的需求。从这篇文章开始会陆续给大家介绍 pytest 中的钩子函数&#xff0c;插件开发等等。 仔细去看过 pytest 文档的小伙伴&#xff0c;应该都有发现 pyt…

利用小蜜蜂AI智能问答ChatGPT+AI高清绘图生成图文故事案例

利用小蜜蜂AI智能问答ChatGPTAI高清绘图生成图文故事案例 这段时间利用小蜜蜂AI网站做了一些编程、绘图以及数据分析方面的案例。再过几个月&#xff0c;我的大孙子就要出生了。我要用小蜜蜂AI智能问答和AI高清绘图为大孙子生成一个1-9的数字图文故事。 小蜜蜂AI网站可以扫如…

DangZero:通过直接页表访问的高效UAF检测(DangZero实现IMPLEMENTATION翻译)

We implement DangZero as a shared library that overlays the de- fault memory allocator via LD_PRELOAD. Additionally, DangZero requires a backend to be available for direct page table access, which we describe in detail in the following section. 我们将DangZ…

CTFHUB 命令执行

命令执行 原理&#xff1a; 在编写程序的时候&#xff0c;当碰到要执行系统命令来获取一些信息时&#xff0c;就要调用外部命令的函数&#xff0c;比如php中的exec()、system()等&#xff0c;如果这些函数的参数是由用户所提供的&#xff0c;那么恶意用户就可能通过构造命令拼…

Android编程环境搭建

一、下载软件&#xff1a; JDK、Android SDK、Android Studio 1.1 首先下载安装JDK 登录Java Downloads | Oracle网站下载javaJDK11&#xff0c;具体步骤如图1所示 图1 下载安装JDK 1.2 下载安装 Android Studio 到 Android Studio 的官网上下载对应安装包&#xff0c;链接…

20240301-2-ZooKeeper面试题(二)

11. Chroot 特性 3.2.0 版本后&#xff0c;添加了 Chroot 特性&#xff0c;该特性允许每个客户端为自己设置一个命名空间。如果一个客户端设置了 Chroot&#xff0c;那么该客户端对服务器的任何操作&#xff0c;都将会被限制在其自己的命名空间下。 通过设置 Chroot&#xff…

腾讯云-云+校园扶持-2核2G学生服务器套餐30元起

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…

【树莓派系统配置+python3.8+环境配置踩坑点汇总】raspberrypi

最近又开始搞树莓派的深度学习模型。很多windows端的环境需要在树莓派上重新部署&#xff0c;中间出现了非常多的问题。主要以各种库的下载安装为主要。 首先&#xff0c;第一个问题&#xff1a; 树莓派系统烧录之后&#xff0c;默认apt一般需要升级看&#xff0c;而默认下载…

YOLOv9:Learning What You Want to Learn Using Programmable Gradient Information

YOLOv9&#xff1a;Learning What You Want to Learn Using Programmable Gradient Information 摘要 今天的深度学习方法关注的是如何设计最合适的目标函数&#xff0c;使模型的预测结果最接近ground truth的真实情况。同时&#xff0c;必须设计一个适当的体系结构&#xff…