【linux】Linux编译器-gcc/g++使用

简介: 【linux】Linux编译器-gcc/g++使用

先写一段代码演示

1 #include<stdio.h>
    2 #define M 100
    3 int main()
    4 {
    5 printf("hello linux");
    6 printf("hello linux");
    7 //printf("hello linux");
    8 //printf("hello linux");
    9 //printf("hello linux");
   10 //printf("hello linux");
   11 //printf("hello linux");
   12 //printf("hello linux");
   13 //printf("hello linux");
   14 //printf("hello linux");
   15 //printf("hello linux");
   16 //printf("hello linux");
   17 printf("hello linux");
   18 
   19 printf("hello M");
   20 printf("%d",M);                                                                                                                                                   
   21 }

1.预处理

gcc -E test.c -o test.i//这条指令-E的含义是从现在开始进行程序翻译,预处理完成,就停下.

生成test.i

vim test.i//打开预处理生成的文件

1.头文件展开

我们发现多了800多行代码

stdio.h库中库函数都在这个路径下面

我们使用vim打开该头文件下的库

我们发现代码中多的八百多行代码,其实就是头文件展开了,去注释后两者一样.

2.宏替换

vim再次打开test.i

对比test.c 和test.i 发现宏定义消失,宏定义的M被直接替换成了100,而字符串中出现的M不会被替换掉.

3.去掉注释

再次对比发现test.c中的注释也被去掉了

4.条件编译

在预处理阶段,还会处理条件编译,在公司推出一款软件时,往往会出现社区版,以及个人版等,实现功能不太语言,那公司是由一套代码维护还是多套呢?

不同的条件编译(这里宏定义M2)就可以实现社区版和个人版用同一套代码维护啦!!

我们也可以通过命令行来进行不同的条件编译

gcc -DM2=1 test1.c

这条指令条件编译,宏定义 M2 1

总结:预处理完成宏替换,去注释,头文件展开,条件编译


2.编译

gcc -S test.i -o test.s//这条指令-S代表从现在开始进行程序的编译,编译完成就停下来

生成了test.s文件

vim打开test.s

发现代码已经变成汇编代码,里面都是汇编指令

总结:编译过程将c语言代码变成汇编语言,此时如果出现变量名没写对会出现编译错误,会进行语法检查


3. 汇编

gcc -c test.s -o test.o//-c选项从现在开始进行程序的翻译,汇编完成就停下来.

生成了test.o

vim打开test.o

我们在vs中也会生成这种obj目标文件

总结:汇编过程是将汇编语言变成二进制目标文件


4.链接

gcc test.o -o test.exe//形成可执行程序

形成可执行程序

总结:链接生成可执行程序


5.c++中的函数重载

1.创建一个.cpp文件

add函数满足参数类型不同构成重载函数

2.g++编译代码

g++ -o my.exe add.cpp// -o后面接着是生成文件的别名

3.查看汇编代码

objdump -S my.exe

为什么c++支持函数重载,而c语言不支持函数冲重载,c语言依靠函数名来区分不同函数,而c++会对重载的函数名加以修饰。


6.编译器的自居过程

当我们没有c语言时,我们用的是汇编语言编程,当没有汇编语言时,我们用的是二进制编程.

而我们c语言的翻译过程就是历史推演的逆过程.我们想一想图中1过程简单,还是2过程简单呢?

当然是2过程了,因为前人已经可以将汇编语言转成二进制了,就是我们的汇编过程.

那是先有编译器呢?还是先有语言呢?第一个汇编编译器是怎么得到的呢?第一个c语言编译器又是怎么得到的呢?

首先编译器是个软件,软件由编译器写的,我们使用二进制编程可以写一个汇编的编译器,然后通过汇编的编译器就可以编写汇编的语言了,然后我们可以用汇编的语言写一个c语言的编译器,然后通过c语言的编译器就可以写c语言了,这就是编译器的自居过程.


7.链接精讲

链接是我们的程序和库结合的过程,语言一定要有自己的标准库,比方说我们写了一个程序,需要使用printf函数,这个printf函数就是标准库里面的.

链接分为动态链接和静态链接,链接可以让我们提高开发效率,比如说我们要实现人物的移动通过键盘,我们可以使用图形库中的函数GetAsyncKeyState来实现,这样是将我们的程序和图形库链接起来.

1.在Linux系统下利用ldd指令查看动态库依赖关系;

2.我们将所依赖的动态库在上述路径下,我们ls -l 这个路径下,发现有个库文件

linux

动态库:.so

静态库:.a

windows

动态库:.dll

静态库: .lib

链接时,动态库进行动态链接,静态库进行静态链接

1.如何理解动态链接和静态链接?

讲一个小故事帮助理解,假如说你在一个高中上学,你在学校里要有你自己的作息,相当于任务,假如说上网是你的作息的一种,你的老学长会告诉你网吧的地址,网吧的机子是你上网的方法。这里你的老学长就相当于你的编译器,会告诉你目标库的地址,然后你的作息是你要执行的程序,包括上网,网吧就是你的动态库,动态库里面的机子就是你的方法,也就相当于你要调用标准库里面的printf函数,假如说有人向派出所举报了这个网吧,也就相当于共享的动态库被删除,要使用这个动态库的函数就不行了,如果将电脑机子搬回你的学校寝室,也就相当于在编译的时候,把库中的方法拷贝到我自己的程序中了.

2.c动态库是默认提供的,gcc默认形成可执行程序,默认采用动态链接

3.动态库,动态链接地优缺点

不能丢失,也就是不能删库

节省资源

静态库,静态链接的优缺点

一旦形成,和库无关

浪费资源

优点 缺点
动态库 节省资源 不能丢失,也就是不能删库,一旦缺失,所有程序都无法运行
静态库 一旦形成,和库无关,可移植性高 浪费资源,静态链接生成程序体积大

gcc编译默认生成动态库

如果要静态链接,输入指令( 比动态多-static)

gcc he.c -o he.exe -static

会出现下面这个情况,默认情况,linux一般静态库都是没有安装的


静态库安装(c语言)

sudo yum install glibc-static

静态库安装(c++)

sudo yum install -y libstdc++-static

gcc he.c -o he3.exe -static//静态链接指令

静态比动态大好多,是动态一百倍.

但是如果我们向别人发送一个可执行程序时,对方没有安装对应的标准库,动态库对对方来说是编不了的,虽然静态库大,但是他会把库里面的方法都拷贝你的可执行程序中,这样就可以在别人的电脑里跑了,这也是静态链接产生的程序为什么容量大的原因了

目录
相关文章
|
2月前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
4月前
|
Linux C语言
成功解决 在Linux CentOS 7 中安装gcc
这篇文章介绍了如何在Linux CentOS 7系统中安装gcc (g++) 8工具集。由于CentOS 7默认的gcc版本是4.8,而这个版本与Qt 5.14、Qt 5.15或更高版本不兼容,可能会导致编译时出现系统头文件错误。文章中提到,即使在项目配置中添加了`CONFIG+=c++11`,如果仍然报错,那么很可能是gcc版本的问题。为了解决这个问题,文章提供了使用CentOS的Software Collections (scl)来安装更新版本的gcc的步骤。
成功解决 在Linux CentOS 7 中安装gcc
|
3月前
|
Linux 编译器 C语言
Linux内核对GCC版本的检测
Linux内核对GCC版本的检测
|
4月前
|
Java Linux 编译器
【Linux】gcc简介+编译过程
【Linux】gcc简介+编译过程
105 0
|
6月前
|
Java 编译器 Linux
程序技术好文:详解Linux安装GCC方法
程序技术好文:详解Linux安装GCC方法
194 0
|
6月前
|
NoSQL 编译器 Linux
【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用
【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用
93 0
|
23天前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
52 8
|
23天前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
144 6
|
24天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
65 3
|
24天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
60 2