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 1003 4 int main()5 {6     printf("hello %d\n ", M);7 8     //条件编译9 #ifdef DEBUG 10     printf("debug\n");11 #else12     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秒一打印
在这里插入图片描述

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

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

相关文章

mac苹果电脑c盘满了如何清理内存?2024最新操作教程分享

苹果电脑用户经常会遇到麻烦:内置存储器(即C盘)空间不断缩小&#xff0c;电脑运行缓慢。在这种情况下&#xff0c;苹果电脑c盘满了怎么清理&#xff1f;如何有效清理和优化存储空间&#xff0c;提高计算机性能&#xff1f;成了一个重要的问题。今天&#xff0c;我想给大家详细介…

备战蓝桥杯---线段树基础2

今天我们把线段树的另一个模板看一下&#xff1a; 在这里&#xff0c;我们注意到乘的操作&#xff0c;因此我们用两个懒标记来分别表示加和乘&#xff0c;这时我们面临了一个问题&#xff0c;就是当我们把标记往下传时&#xff0c;它的儿子怎么知道是先乘还是先加&#xff1f; …

2025张宇考研数学,百度网盘视频课+36讲PDF讲义+真题

张宇老师的课属于幽默生动&#xff0c;会让一个文科生爱上数学&#xff0c;但是有的同学不知道在哪看&#xff0c;可以看一下&#xff1a;2025张宇考研数学全程网盘 docs.qq.com/doc/DTmtOa0Fzc0V3WElI 可以粘贴在浏览器 张宇30讲作为一本基础讲义&#xff1a;和教材…

java的线程池介绍

什么是线程池&#xff1f; 线程池是一种用于管理和复用线程的机制&#xff0c;旨在减少线程的创建和销毁次数&#xff0c;提高线程的可重用性和执行效率。通过线程池&#xff0c;可以控制线程的数量、数量大小以及线程的执行方式&#xff0c;从而更加有效地处理并发任务。 线…

如何使用公网地址远程访问内网Nacos UI界面查看注册服务

文章目录 1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Plik Nacos是阿里开放的一款中间件,也是一款服务注册中心&#xff0c;它主要提供三种功能&#xff1a;持久化…

6、wuzhicms代码审计

wuzhicms代码审计 前言 安装环境配置 服务器要求 Web服务器: apache/nginx/iis PHP环境要求:支持php5.2、php5.3、php5.4、php5.5、php5.6、php7.1 (推荐使用5.4或更高版本!) 数据库要求: Mysql5www/install文件夹即可进入安装页面 审计开始 首页文件index.php&#xff0c…

kubernetes+prometheus+grafana监控+alertmanager实现qq邮箱报警

prometheus基于kubernetes监控 prometheus对kubernetes的监控 对于Kubernetes而言&#xff0c;我们可以把当中所有的资源分为几类&#xff1a; 基础设施层&#xff08;Node&#xff09;&#xff1a;集群节点&#xff0c;为整个集群和应用提供运行时资源容器基础设施&#xff…

C/C++内存管理及内存泄漏详解

目录 C/C内存分布 C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free C内存管理方式 new/delete操作内置类型 new和delete操作自定义类型 operator new与operator delete函数 new和delete的实现原理 内置类型 自定义类型 内存泄漏 概念 内存泄漏分类 ⭐…

180基于matlab的频率切片小波变换程序(FTWT)

基于matlab的频率切片小波变换程序&#xff08;FTWT&#xff09;。从一种新的角度出发&#xff0c;通过自由选择频率切片函数、引进新尺度参数&#xff0c;在频率域实现小波变换&#xff0c;该变换能够很好地刻画信号各成分之间的相对能量关系。此外&#xff0c;频率切片小波变…

【InternLM 实战营笔记】OpenCompass大模型评测

随着人工智能技术的快速发展&#xff0c; 大规模预训练自然语言模型成为了研究热点和关注焦点。OpenAI于2018年提出了第一代GPT模型&#xff0c;开辟了自然语言模型生成式预训练的路线。沿着这条路线&#xff0c;随后又陆续发布了GPT-2和GPT-3模型。与此同时&#xff0c;谷歌也…

探讨苹果 Vision Pro 的 AI 数字人形象问题

Personas 的设计模糊性&#xff1a; 部分人认为这种模糊设计可能是出于安全考虑&#x1f6e1;️。安全角度&#xff1a;Personas 代表着你的 AI 数字形象&#xff0c;在创建时&#xff0c;它相当于你的 AVP&#xff08;生物识别扫描器的存在增加了冒充的难度&#xff09;。如果…

40、网络编程/TCP和UDP通信模型练习20240229

一、使用TCP模型创建服务器和客户端完成简单通信。 服务器代码&#xff1a; #include<myhead.h> #define SER_IP "192.168.32.130" #define SER_PORT 8888 int main(int argc, const char *argv[]) {//1.创建监听的套接字int sfd-1;sfdsocket(AF_INET,SOCK_S…

解决 MySQL 未运行但锁文件存在的问题

查看mysql状态时&#xff0c;显示错误信息"ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists"。 解决步骤 1、检查 MySQL 进程是否正在运行 在继续之前&#xff0c;我们首先需要确定 MySQL 进程是否正在运行。我们可以使用以下命令检查…

港中文联合MIT提出超长上下文LongLoRA大模型微调算法

论文名称&#xff1a; LongLoRA: Efficient Fine-tuning of Long-Context Large Language Models 文章链接&#xff1a;https://arxiv.org/abs/2309.12307 代码仓库&#xff1a; https://github.com/dvlab-research/LongLoRA 现阶段&#xff0c;上下文窗口长度基本上成为了评估…

算法修炼-动态规划之路径问题(1)

62. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;选定一个网格为终点&#xff0c;走到这个网格的所有走法就是这个网格的上面一个网格的所有走法加上这个网格左边一个网格的所有走法&#xff0c;然后做好初始化工作就行。 class Solution { public:int…

MATLAB环境下基于偏置场校正的改进模糊c-均值聚类图像分割算法

基于聚类的分割方法是以统计学为基础提出的一种分割方法。其实质是通过计算像素与每一类聚类中心的欧氏距离来判定像素与每一类聚类中心的相似性&#xff0c;距离近就说明像素与聚类中心相似性大&#xff0c;反之相似性小。基于一定标准下的相似性自动划分成若干个子集(类)&…

【无标题】TMGM官网平台切尔西足球俱乐部合作

TMGM作为一家在三大洲均设有办事处的行业领导者&#xff0c;TMGM 被视为可靠的差价合约交易提供商&#xff0c;其重点是监管合规、技术创新与他联系➕&#x1f6f0;️TMGM818卓越的客户服务。 切尔西足球俱乐部在亚太地区拥有庞大的球迷群体&#xff0c;并在该地区建立了多种亚…

2024年腾讯云优惠政策_腾讯云TOP10优惠活动

腾讯云服务器多少钱一年&#xff1f;62元一年起&#xff0c;2核2G3M配置&#xff0c;腾讯云2核4G5M轻量应用服务器218元一年、756元3年&#xff0c;4核16G12M服务器32元1个月、312元一年&#xff0c;8核32G22M服务器115元1个月、345元3个月&#xff0c;腾讯云服务器网txyfwq.co…

AOP案例(黑马学习笔记)

需求 需求&#xff1a;将案例中增、删、改相关接口的操作日志记录到数据库表中 ● 就是当访问部门管理和员工管理当中的增、删、改相关功能接口时&#xff0c;需要详细的操作日志&#xff0c;并保存在数据表中&#xff0c;便于后期数据追踪。 操作日志信息包含&#xff1a; ●…

IO多路转接

1.select 初识select 系统提供 select 函数来实现多路复用输入 / 输出模型 . select 系统调用是用来让我们的程序监视多个文件描述符的状态变化的 ; 程序会停在 select 这里等待&#xff0c;直到被监视的文件描述符有一个或多个发生了状态改变 ; select函数模型 select的函…