vim指令的使用,C编译过程以及多文件进行编译运行,静态库与动态库,gdb调试(附详细解析以及步骤教学,保姆级+图片展示)

目录

指令:

GCC内容:从安装到使用,一步步详细解析(附图示):

C语言的编译过程:(面试题)

1.预处理:#格式开头的指令称为预处理指令(或预处理命令)

3. 预处理阶段的特点

4. 预处理指令的注意事项

2.编译:-S

3.汇编:

4.链接:生成可执行文件.exe

GDB调试器:设置断点进行编译调试:

多文件的联合使用编译运行的过程(GCC):

动态库与静态库(工程管理Makefile):详细解析以及用法。

动态库:程序不执行,就不会进行调用库。

方法一解决办法:提供一个库环境,把库放在lib目录下。

方法二:放到自定义的库中。

静态库:直接把库编译进man执行文件中。

两者的区别:


指令:

该模式在退出所有模式下才能使用(esc退出)

复制:yy

粘贴:p

将光标从任意一行跳转到行首,然后删除全篇:gg +d +G 


对vim编辑器进行个性化设置,在哪里进行修改?

打开加目录下的vim 的隐藏配置文件:~/.vimrc:

(这个配置文件当运行vim时就会运行)

在这里可以加入自己需要的设置:例如

(注意!!!)建议这里不要加入Tab转空格。在有些代码编写上会对缩进有要求,不同的配置可能会出现问题。


GCC内容:从安装到使用,一步步详细解析(附图示):

C语言的编译器名为gcc。故而在Linux中编译C语言代码也需要gcc编译器。

安装编译器件指令:(该指令可以把很多的编译器都下载进来)

sudo apt-get install build-essential

在我们进行软件的安装的时候,有些需要我们不断地进行确认才能往下进行,有什么办法可以不用点击,直接输入指令就可以一直下载呢?

解决:在输入下载指令的末尾加入  -y 。那么在安装软件的时候就可以直接一步到低。

sudo apt-get install build-essential  -y

在安装完软件后,我们开始使用gcc编译器:

生成可执行文件(默认生成a.out,使用-o可实现自定义文件名): gcc  文件名 ,就可生成可执行文件;然后输入 :   ./可执行文件       就可执行出结果。

gcc ws.c -o hello

C语言的编译过程:(面试题)

相关资料:

如下对该代码进行详细解析编译的四个过程:

1.预处理:#格式开头的指令称为预处理指令(或预处理命令

gcc -E main.c -o  main.i #生成一个main.i文件

 

作用:它们是预处理器(Preprocessor)在编译阶段之前处理的特殊指令,用于对源代码进行文本替换、条件编译、文件包含等操作。用于控制编译环境和代码生成。

  • 文本替换:通过#define定义宏,简化代码或提高可读性 
  • #define:定义无参宏或带参宏
  • #define PI 3.1415926      // 无参宏
    #define MAX(a, b) ((a) > (b) ? (a) : (b))  // 带参宏

    #undef:取消已定义的宏。

  • 条件编译:通过#if#ifdef等指令选择性编译代码,适配不同平台或调试需求
  • #if 、#elif、#else、#endif:根据条件判断是否编译某段代码。 #ifdef、#ifndef:检查某个宏是否已定义。 
  • #ifdef DEBUG
        printf("调试模式开启");
    #endif
    
  • 文件包含:通过#include将头文件内容插入当前源文件,引入函数声明或常量定义 

文件包含:#include :插入头文件或用户自定义文件。

#include <stdio.h>   // 标准库头文件
#include "myheader.h" // 用户自定义头文件

错误与警告控制:

  • #error:强制停止编译并输出错误信息 
  • #pragma:向编译器传递平台相关指令,如对齐方式、警告控制等 
#pragma once         // 防止头文件重复包含
#pragma warning(disable:4996)  // 禁用特定警告

#line:修改编译器记录的行号和文件名,常用于代码生成的工具。

3. 预处理阶段的特点

  • 预处理与编译分离:预处理在编译之前完成,生成一个“纯净”的代码文件供编译器处理 
  • 文本替换性质:宏替换仅是文本层面的操作,不涉及类型检查或计算,可能导致副作用(如多次求值) 
  • 跨平台支持:通过条件编译指令,同一份代码可适配不同操作系统或硬件环境 

4. 预处理指令的注意事项

  • 无分号结尾:预处理指令末尾不加分号(例如#define PI 3.14而非#define PI 3.14;) 
  • 作用域限制:宏的作用域从定义处开始,直到#undef或文件结束 
  • 括号使用:带参宏的参数和整体表达式需用括号包裹,避免运算符优先级问题 

注意!!!预处理仅仅是处理#开头的那些语句,不检查后续的代码语法,意思就是就算我后面代码写错了它也可以运行。

2.编译:-S

指令:将预编译生成的main.i文件再生成main.s文件。

gcc -S main.i  -o main.s

3.汇编:

汇编不能使用gcc编译器(这个编译器编译的是c的),汇编有自己的编译器。

as指令:汇编二进制,使用.o 文件格式,故上文编译可以不生成.s而生成.o文件。

as main.s -o main.o

生成的.o文件无法使用cat查看,需要使用nm  查看。

4.链接:生成可执行文件.exe

gcc -o main mian.o  #生成可执行文件,其中exe可要可不要

最后运行./mai执行出程序的结果。

上图的编译过程只是为了演示过程分析,一般编译不使用这个方法。


GDB调试器:设置断点进行编译调试:

在进行调试的时候会出现一个问题:关于DEbug的文件类型的设置。

问题:no debugging symbols found,使用基础的指令:

gcc -c main.c -o main #生成可执行文件(默认是release模式)

而我们使用的调试工具是debug模式,故需要把可执行文件编程debug模式,使用-g指令。

gcc -g  main.c 0o main #生成一个debug格式的可执行文件

然后执行 指令:进入调试界面。

gdb mian

步骤:输入file main 进入int main()中的代码程序:

然后在第五行设置断点,再进行run运行,会发现执行出第五行

清除断点:clear 5(该指令表示的是清除代码中的第五行设置的断点)

注意~~~在进行断点的设置的时候,好像填写的断点所在的行是不执行的,但是会显示出来。


多文件的联合使用编译运行的过程(GCC):

例如文件中现在含有主程序main.c以及子程序add.c 、add.h文件。

先对主程序mian.c进行编译:然后会出现以问题:对add未进行引用。如何解决呢?

我们单独编译add.c会出现问题,会出现main函数的未定义引用的错误,是因为add.c函数中把该add的函数当成了主函数main,但是一个工程中只能有一个Mian函数。所以这两个函数我们不能单独编译。

我们将两个.c文件合并起来进行编译。

gcc main.c add.c  -o  main

就可以执行出结果。这里我们会发现一个弊端,就是我们需要把两个.c文件放到指令中去打,如果.c多了有上千个咋办?一个一个敲,太逆天了哈哈哈哈,怎么解决呢?我们再进行讲解。


动态库与静态库(工程管理Makefile):详细解析以及用法。

简述:将所有的.c单独编译成为一个库,(库:可直接使用,如printf函数,我们可以直接使用它来打印数据,但是我们看不到它内部怎么写的)

想象你有一个巨大的快递仓库(C语言项目),每天需要处理成千上万的包裹(代码文件),并且要把它们打包成最终的大包裹(可执行程序)。但手动处理每一个包裹效率太低,还容易出错。这时候你需要两样东西:Makefile(自动化流水线)和(预制工具包)。

调用函数的三要素:1.定义 2.声明 3.调用

如果我们不想让别人窃取我们的劳动果实,辛辛苦苦写出来的.c代码,我们可以建立一个库(libadd.so),把函数的定义放入库里面。

动态库:程序不执行,就不会进行调用库。

lib开头,加上库名,以.so结尾   例如libws.so

意思就是不输入指令./main  就不会调用这个库。

如何创建一个动态库:指令:

gcc -shared add.c  -o  libadd.so #创建一个动态库。

此时如果直接编译源文件main.c会出现报错。因为我们未调用指定库。

其中的指令:gcc main.c  -o  main  -ladd  -L./      中-ladd,其中  -l   是一个指令符,后面的add是库libadd.so的中间add库名,-L后面直接接上库所在的路径。

注意!!!如果执行的终端目前的用户路径与库的路径不一致,一定要填写库的详细路径。

会出现以下错误:原因是编译库的时候并没有被编译到main执行文件里面去,当程序执行对应代码后,才会调用库。

方法一解决办法:提供一个库环境,把库放在lib目录下。

此时我们在路径/lib中进行查找:就会找到生成的库文件。

方法二:放到自定义的库中。

虽然我们可以直接放入系统库目录中,但是到后期随着项目的增加,我们自己添加的库和系统库存放在一起就会显得很乱,所以我们采用方式三,存放自己的库,分开存储。

静态库:直接把库编译进man执行文件中。

命名方式:lib开头加上库名,以.a结尾。例如libadd.a

使用过程:创建一个静态库,由.c文件创建

通过add.o来创建静态库。

ar -r libadd.a  add.o  来创建一个静态库。

然后生成可执行文件(将main.c与libadd.a一起生成可执行文件)

两者的区别:

如果使用静态库,add.c增加功能,想要使用,那么需要编译静态库,然后要重新编译mian.c,

然后再一起生成可执行文件。再运行使用。

如果是动态库:增加功能,那么只需要编译动态库即可,因为上文得知,动态库是不与mian.c一同编译成可执行文件的,只是需要存放在相应路径即可。类似于游戏更新,并没有删掉原来的东西。

mst:


到这里要告一段落了,下一篇讲解Makefile的操作,该篇讲解了静态库与动态库的编译,这里编译也是需要在指令端进行gcc然后调用库,下一篇直接编写Makefilie文件,然后进行make指令就可以执行程序啦,静态库与动态库很重要,大家一定要多加了解学习,在后期的lnux操作都是需要对库的掌控。2025.3.1---学习记录,与大家一起共勉!!!欢迎一起探讨技术问题。


问题:如果网络不在线,无法联网,怎么使用离线安装?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值