linux下gcc/g++相关内容整理

目录

  • 1.简单gcc运用
  • 2.gcc相关指令详解
    • 预处理:
    • 编译:
    • 汇编
    • 链接:
  • 3.图像总结记忆
  • 4.整体延伸
    • 1.为什么C程序的翻译是这个过程?
    • 2.链接如何理解?

1.简单gcc运用

先写一段程序
linux下gcc/g++相关内容整理_第1张图片
即:

#include                                                                                                                                                                                                
    
#define Num 100    
    
int main()    
{    
  printf("Hello vim!");    
  //printf("Hello vim!");    
  //printf("Hello vim!");    
  //printf("Hello vim!");    
  //rintf("Hello vim!");    
  printf("Num = %d\n",Num);    
  return 0;    
}    

然后保存退出
linux下gcc/g++相关内容整理_第2张图片
gcc编辑我们写的代码
然后就会生成a.out(可执行程序)
运行该程序
./a.out
linux下gcc/g++相关内容整理_第3张图片

补充:

  1. 无论你gcc test.c文件几次都会只生成一个a.out
  2. ./ .当前路径 /路径分割符 即:执行当前路径下的a.out
  3. a.out 是执行不想起来的
  4. 也可以用路径即:
    linux下gcc/g++相关内容整理_第4张图片

2.gcc相关指令详解

预处理:

gcc -E test.c
如果后面不指定文件保存,内容就会直接显示下图
这样也无意义,所以一般情况下要指定文件保存一下内容
linux下gcc/g++相关内容整理_第5张图片
-E 后生成的文件我们一般用 .i 保存
即:
gcc -E test.c -o test.i
这样之后,预处理之后的结果就会放在 .i 文件中

vim test.i 文件
vs test.c
linux下gcc/g++相关内容整理_第6张图片
我们会发现,.i文件将.c文件的头文件展开,并将注释部分全部删除,宏直接被替换

编译:

  1. 编译文件可以从.c开始,也可以从.i开始
  2. 编译文件可以不用-o,因为会默认生成.s文件
  3. 当然也可以写上-o test.s

指令:
gcc -S test.c
gcc -S test.c -o test.s
或者
gcc -S test.i
gcc -S test.i -o test.s

linux下gcc/g++相关内容整理_第7张图片

汇编

gcc -c
可以后接我们生成的.c .s .i .o 都可以
也可以再后接-o test.o 生成指定.o文件

vim test.o
linux下gcc/g++相关内容整理_第8张图片
也可以
od test.o
(二进制查看工具)
linux下gcc/g++相关内容整理_第9张图片

补充:
汇编虽然形成了二进制文件,并不可以直接进行,可重定向目标文件
test.o文件等价于test.obj文件

链接:

延伸:

  1. 语言也是有库的
  2. 语言一般给我们提供:一套头文件+一套库文件(libc.a或者libc.so)
    需要链接来将我们自己的代码中的函数调用,外部数据,和库关联起来
  3. 此时我们不需要别的 - 来,直接gcc 即可
  4. 用法和上面一样也可以后面加-o 形成我们指定的文件test
  5. 可以不带任何选项,编译器会自动再系统中帮我们找C/C++相关的库,帮我们和我们自己写的可重定向目标文件进行链接,形成-o指名的目标文件
    linux下gcc/g++相关内容整理_第10张图片
    linux下gcc/g++相关内容整理_第11张图片

补充:
gcc -o test test.c
gcc test.c -o test
两者皆可

3.图像总结记忆

linux下gcc/g++相关内容整理_第12张图片

linux下gcc/g++相关内容整理_第13张图片

4.整体延伸

1.为什么C程序的翻译是这个过程?

  1. 最早的编程是:纸带打孔
  2. 因为太麻烦所以出来了:汇编—助记符(用一些较为接近人的语言来描述一个程序逻辑)
    因为计算机只认识二进制,所以汇编语言也要做到将汇编语言翻译成二进制程序
    所以诞生了编译器
  3. 汇编语言开发效率比较低,所以对汇编语言进行模块化,所以产生了C语言
    C语言要让计算机所接受,也要变成二进制程序
    因为C语言变成汇编更简单,还要兼容汇编
    所以需要C语言先翻译成汇编,然后再翻译成二进制程序

预处理的为什么?
C语言需要被提前处理的,比如头文件展开,去注释,条件编译,宏替换等

链接的为什么?
C库,等语言库的运用

2.链接如何理解?

ldd
是查看一个可执行程序依赖第三方库的命令
linux下gcc/g++相关内容整理_第14张图片

在这里插入图片描述
可以看出我们链接的是
c标准库2.17版本
libc-2.17.so就是我们需要的库文件

Linux中库分为两种:
静态库:.a
动态库:.so

windows下的库:
静态库:.lib
动态库:.dll

静态库和动态库都和
程序成功运行有关

链接就是:
自己写的c程序和语言上或者第三方库提供的方法关联起来

因为库有静态库和动态库
所以程序的链接有:静态链接和动态链接

动态链接和静态链接的区别:
动态链接:你的.c文件调用了库文件的一些代码,
当你的程序运行时,需要那个库文件代码,就会跑到库文件里查找这个代码,然后调用执行
静态链接:你将库的一些代码下载到你的文件里面,当你的.c编译时
就不需要去库里面查找代码了

linux下gcc/g++相关内容整理_第15张图片
我们可以看到test的大小只有8360
可以推断出:gcc默认动态链接方式,形成可执行程序

在这里插入图片描述
dynamically linked 动态链接
uses shared libs使用共享库(使用动态链接)

当你在你的linux中下载了C语言静态库
你在编译你的.c文件时,你会将C语言的库的所有内容加载到你的这个最后可执行程序中

总结:
1.静态链接时,占用空间会很大
2.动态链接时,当你链接的内容,被别人删除时,你的程序就会出现问题
3.默认情况下gcc是动态链接
4.静态链接的时候,需要.a静态库
5.动态链接的时候,需要.so动态库
6.当你一旦在后缀加了_static,就会在系统中查找.a静态库,如果有就静态链接成功,如果没有就报错
7.static链接时是很难链接到.so的

你可能感兴趣的:(linux学习,linux,c语言,运维)