目录
动态库与静态库(工程管理Makefile):详细解析以及用法。
指令:
该模式在退出所有模式下才能使用(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---学习记录,与大家一起共勉!!!欢迎一起探讨技术问题。
问题:如果网络不在线,无法联网,怎么使用离线安装?