Linux工具——gcc

news2024/11/18 23:41:47

目录

一,gcc简介

二,C语言源文件的编译过程

1.预处理

2.编译

3.汇编

 4.链接

5.动静态库 


一,gcc简介

相信有不少的小白和我一样在学习Linux之前只听说过visual  studio。其实这个gcc这个编译器实现的功能便是和visual studio一样的功能,但是gcc只能够支持c语言。如果要支持C++的话便要用到g++。

二,C语言源文件的编译过程

1.预处理

在C源文件运行时做的第一步便是预处理,在预处理的过程中要做的便是:

1.头文件展开。

2.去掉注释。

3.条件编译。

4.宏替换。

这上面的四步便是预处理时要做的四步。那我们在Linux中要如何的去观察这一个过程呢?这个时候便要使用到一个Linux的指令了。这个指令便是——gcc -E:代表的意思便是开始编译C源文件等到预处理结束以后便停止翻译。可以来段代码来看看效果。如以下代码:

#include<stdio.h> //头文件
 
  2 #define M 123 //宏定义
  3 #define v1 1  
  4 #define v2 0  
  5 #define v3 0  
 
  6 int main()  
  7 {  
  8   printf("hello Linux:%d \n",M);  
  9   printf("hello C++ :%d \n",M);  
 10   
 11 //  printf("hello Linux:%d \n",M);//注释  
 12 //  printf("hello C++ :%d \n",M);  
 13 //    
 14 //  printf("hello Linux:%d \n",M);  
 15 //  printf("hello C++ :%d \n",M);  
 16   
 17 #if(v1) //条件编译 
 18   printf("普通版本\n");  
 19 #elif(v2)  
 20     printf("会员版本\n");  
 21 #else  
 22     printf("超级会员版本\n");  
 23 #endif  
 24                                                                                                                                                                                        
 25     return 0 ;    
 26 }  

当我执行如下指令时:gcc -E texe2.c -o code.i。当我们输入这条指令时便会得到一个code.i文件。当用vim进到这个文件里面是便会看到头文件被展开了,宏被替换掉了,注释被删掉了,预处理指令只有条件成立的那一部分被留下来。

2.编译

这个编译便是代码翻译的第二步,在这个过程中我们要做的便是将英文代码变成汇编代码。在Linux 系统下输入gcc -S ,这条指令便可以生成一个经过编译后的汇编文件。比如对上述的code.i文件进行编译-gcc -S code.i -o code.s,便会得到这样一个汇编文件:

这样子便将c源文件给弄成了汇编文件了。

3.汇编

在这个过程中要做到的便是将汇编文件翻译为重定向的二进制文件。在Linux系统下输入指令:gcc -c便可。如对上述的code.s文件进行翻译便可以输入指令-code -c code.s -o code.o。在执行完这个指令以后便会形成一个code.o文件。用vim打开该文件便会是这样一个光景:

因为vim是文本编辑器,但是code.o文件却是二进制文件所以就会出现这样的错误。要打开二进制文件要调用另一个指令——od。打开后便是这样的:

我们自然是看不懂的,但是计算机就能看懂。在进行到这一步以后一个二进制文件也就是目标文件便生成了。但是此时我们还不能运行。

 4.链接

生成目标文件以后,如果要运行的话便要经过链接这一步。经过了链接这一步以后代码才可以变成一个可执行文件。在Linux环境下就是输入指令gcc 。对于上述的code.o文件也就是输入指令 ——gcc code.o -o mybin:

5.动静态库 

1.库的分类

其实可执行文件 = 头文件+代码+库。在这里头文件相当于一个功能函数声明的集合,代码就是我们调用功能函数的指令,库便是各种功能函数的定义。在这里的库便分为两种库,一种叫做动态库,一种叫做静态库。动态库的后缀是so,静态库的后缀是.a。在Linux环境下输入指令ls /usr/lib64/libc.so.6便可以查看这个动态库。

得到这个蓝色的路径便是动态库的路径。lib表示库,c表示动态库的名字,so表示是动态库,6表示版本。

2.链接方式

在Linux中有两种链接方式。一种是动态连接方式,一种是静态链接方式。这两种不同的链接方式各自有各自的优点。动态链接形成的可执行程序比较小,静态链接形成的可执行序比较大。这两种差别是因为这两种链接调用库中功能函数的方式的不同导致的。

1.动态链接是通过函数的地址来调用的,静态链接是通过将函数拷贝到可执行文件中来调用的。

2.动态库的函数调用会受到动态库的存在与否影响,但是静态库则不受这个影响。

 

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

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

相关文章

纷享销客入选中国信通院《高质量数字化转型产品及服务全景图》

近期&#xff0c;在中国信息通信研究院主办的“2023数字生态发展大会”暨中国信通院“铸基计划”年中上&#xff0c;重磅发布了《高质量数字化转型产品及服务全景图&#xff08;2023&#xff09;》&#xff0c;纷享销客凭借先进的技术能力和十余年客户业务场景应用理解&#xf…

Linux fcntl函数

/*#include <unistd.h>#include <fcntl.h>int fcntl(int fd, int cmd, ... ); 参数&#xff1a;- fd&#xff1a;需要操作的文件描述符- cmd&#xff1a;表示对文件描述符如何操作- F_DUPFD:复制文件描述符&#xff0c;复制的是参数fd&#xff0c;得到一个新的文件…

LeetCode:2. 两数相加

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

Java学习笔记------抽象类和抽象方法

抽象方法 抽象方法&#xff1a;将共性的行为&#xff08;方法&#xff09;抽取到父类之后&#xff0c;由于每一个子类执行的内容是不一样的&#xff0c;所以&#xff0c;在父类中不能确定具体的方法体&#xff0c;该方法就可以定义为抽象方法抽象类&#xff1a;如果一个类中存…

d3.js 的使用

这篇文章相当于之前 svg 的补充。 因为 svg 代码肯定不是人为去专门写的。 在这里推荐制作 svg 的第三方库 - D3.js 用于定制数据可视化的JavaScript库 - D3 官网地址&#xff1a; D3 by Observable | The JavaScript library for bespoke data visualization 简单使用 画…

嵌入式基础知识-信息安全与加密

本篇来介绍计算机领域的信息安全以及加密相关基础知识&#xff0c;这些在嵌入式软件开发中也同样会用到。 1 信息安全 1.1 信息安全的基本要素 保密性&#xff1a;确保信息不被泄露给未授权的实体。包括最小授权原则、防暴露、信息加密、物理加密。完整性&#xff1a;保证数…

nginx-日志处理

access.log #正常请求的日志 error.log #访问错误日志&#xff0c;404&#xff0c;500等请求在这里 buffer&#xff1a;设置缓冲区&#xff0c;访问日志不会直接打到磁盘上&#xff0c;而是先积攒到缓冲区&#xff0c;缓冲区满了后在统一往…

H5打包APP和IOS实现免签,超级签,mam签,h5分发

博主技术笔记 博主开源微服架构前后端分离技术博客项目源码地址&#xff0c;欢迎各位star 微信公众号&#xff0c;每天给大家提供技术干货 http://yun.viphssp.top/root 打包出来的模板&#xff1a;https://yun.viphssp.top/mq/3/html/index.html

解决a标签内容中img标签和p标签垂直方向间隔太大的问题

现象如下&#xff1a; 对应的html结构&#xff1a; 解决办法&#xff1a;给a标签设置&#xff1a;display: inline-block和line-height属性。 然后问题解决&#xff1a; 具体原理如下&#xff08;由chatgpt回答&#xff09;&#xff1a; display: inline-block 可以减少垂直方…

java可以跨平台的原因是什么?

因为不同平台可以安装对应的JVM&#xff08;Java Virtual Machine&#xff09;&#xff0c;它是C/ C写的&#xff0c;JVM可以屏蔽所有和平台相关的信息&#xff0c;并帮助把Java文件经过编译后生成的和平台无关的class类文件&#xff08;也就是字节码&#xff09;从硬盘读取到内…

Java面试题(持续更新中)

一、Java基础集合多线程JVM 1.Java基础 1.1面向对象和面向过程的区别 面向过程&#xff1a;面向过程的性能比面向对象高。因为类调用时需要实例化&#xff0c;消耗比较大&#xff0c;比较消耗资源&#xff0c;所以当性能是最重要的考量因素的时候&#xff0c;比如单片机、Li…

内存卡数据恢复软件推荐,简直是高效恢复好帮手!

“朋友们在使用内存卡时有没有好的内存卡数据恢复软件推荐呀&#xff1f;我的内存卡对我来说真的很重要&#xff0c;但是我不小心把里面的数据删除了&#xff0c;我应该怎么做才能恢复里面的数据呢&#xff1f;” 内存卡为我们的生活提供了很多的便利&#xff0c;我们可以在里面…

输入时并未按照格式,没注意汉字符号

&#x1f388;问题现象&#xff1a; 运行出来的代码没得到想要的结果&#xff1a; &#x1f388;原因分析&#xff1a; 程序运行起来了&#xff0c;计算的结果是错误的&#xff0c;这个最好的解决办法就是调试&#xff0c;一步步的看代码在每个阶段的值是不是我们期望的&…

Qt学习记录___9.10

1.QtSvg初体验 #include <QtSvg> QSvgWidget w1;w1.load(QString(":/iconfont-gongyichongwu.svg"));QSvgRenderer *renderw1.renderer();qDebug()<<render->defaultSize();w1.resize(render->defaultSize());w1.show(); 2. 对话框实验。 QT之隐藏…

LNMP网站搭建

安装宝塔面板一键安装LNMP LNMP LNMP含义 L代表Linux 用来当作程序运行的系统平台 N代表Nginx 用来提供WEB网页服务 M代表Mysql 用来存储管理网站数据 P代表PHP 用来处理动态资源 LNMP搭建方法 1. yum安装依赖环境 yum -y install pcre-devel zlib-devel gcc gcc-c make安…

Cascade-MVSNet CVPR-2020 学习笔记总结 译文 深度学习三维重建

文章目录 4 Cascade-MVSNet CVPR-20204.0 主要特点4.1 背景介绍4.2 代价体构造回顾4.3 Cascade-MVSNet4.4 Loss的设置4.5 Cascade-MVSNet实战操作4.6 总结4 Cascade-MVSNet CVPR-2020 深度学习三维重建 cascade-MVSNet-CVPR-202(源码、原文、译文 )下载 4.0 主要特点 采用特…

一阶高通滤波器(博途SCL代码)

高通滤波器与低通滤波器刚好相反,允许信号的高频分量通过,可以和低通滤波器组合使用,组成带通滤波器。一阶低通滤波器相关算法介绍,可以查看下面文章链接: PLC信号处理系列之一阶低通(RC)滤波器算法_plc滤波算法程序_RXXW_Dor的博客-CSDN博客1、先看看RC滤波的优缺点 优点…

C#中的IQueryable vs IEnumerable (二)

概要 在前面的文章中&#xff0c;本人曾经分析了IQueryable和 IEnumerable两个接口的异同点。但是整个分析过程&#xff0c;侧重于基本概念层面&#xff0c;本文从设计和代码应用的角度来分析它们的区别。 现象讨论 相比于IEnumerable&#xff0c;IQueryable多了一个Express…

4.k8s部署私人仓库并且部署java服务案例

文章目录 前言一、搭建私人仓库1.1 拉取仓库镜像1.2 创建一个文件夹用来放用户名密码,然后在新创建一个账户1.3 Registry服务默认会将上传的镜像保存在容器的/var/lib/registry&#xff0c;我们将主机的/opt/registry目录挂载到该目录&#xff0c;即可实现将镜像保存到主机的/o…

多线程-锁的种类

1 作用 Java中的锁主要用于保障多并发线程情况下数据的一致性。在多线程编程中为了保障数据的一致性&#xff0c;我们通常需要在使用对象或者方法之前加锁&#xff0c;这时如果有其他线程也需要使用该对象或者该方法,则首先要获得锁,如果某个线程发现锁正在被其他线程使用,就会…