VIM
三种模式
正常
a i 进入插入模式
20 shift g 跳到20行
5yy 复制往下5行 加p 输出
5dd 删除往下5行
<-ESC
插入
正常编辑
ESC->
命令
:set nu 显示行号
:wq 保存退出
:u 撤回
GCC编译

大写E S
gcc -I 头文件目录
gcc -c
gcc
-v/-version 查看gcc版本号
-I 目录 指定头文件目录,注意-I和目录之间没有空格
-c 只编译 生成.o文件 不进行链接
-g 包含调试信息
-On n=0~3 编译优化,n越大优化越多
-Wall 提示更多警报信息
-D
:gcc mian.c -D
-M 生成.c文件与头文件依赖关系以用于Makefile,包括系统库的头文件
-MM 生成.c文件与头文件依赖关系以用户Makefile,不包括系统库的头文件
动态库和静态库
静态库在文件中静态展开,所以有多少文件就展开多少次,非常吃内存,100M 展开 100 次,就是 1G, 但是这样的好处就是静态加载的速度快 使用动态库会将动态库加载到内存,10 个文件也只需要加载一次,然后这些文件用到库的时候临时 去加载,速度慢一些,但是很省内存 动态库和静态库各有优劣,根据实际情况合理选用即可。
简言之 静态库 在编译时与程序一起 对空间要求较低 而时间要求较高
动态库 在编译时不与程序一起 对时间要交较低 而空间要求较高
创建一个静态库
1.将 .c 生成 .o
2.使用ar工具制作静态库
ar rcs libmylib.a add.o sub.o
3.需要将包含其他源文件的函数声明文件作为头文件包括进去
#ifndef MYMATH_H
#define MYMATH_H
endif
- 编译静态库到可执行文件中
gcc test.c libmylib.a -o test.o -I ./inc
创建一个动态库
制作动态库的步骤
1. 生成位置无关的.o 文件 gcc -c add.c -o add.o -fPIC 使用这个参数过后,生成的函数就和位置无关,挂上@plt 标识,等待动态绑定
2. 使用 gcc -shared 制作动态库 gcc -shared -o lib 库名.so add.o sub.o div.o
3. 编译可执行程序时指定所使用的动态库。-l:指定库名 -L:指定库路径
gcc test.c -o a.out -l mymath -L ./lib
4. 运行可执行程序./a.ou
gdb调试工具
查看逻辑错误
gcc -g 进入调试模式
基础指令: -g:使用该参数编译可以执行文件,得到调试表。
gdb ./a.out
list: list 1 列出源码。根据源码指定 行号设置断点。
b: b 20 在 20 行位置设置断点。
run/r: 运行程序
n/next: 下一条指令(会越过函数)
s/step: 下一条指令(会进入函数)
p/print:p i 查看变量的值。
continue:继续执行断点后续指令。
finish:结束当前函数调用。
quit:退出 gdb 当前调试
其他指令:
run:使用 run 查找段错误出现位置。
set args: 设置 main 函数命令行参数 (在 start、run 之前)
run 字串 1 字串 2 …: 设置 main 函数命令行参数
info b: 查看断点信息表
b 20 if i = 5: 设置条件断点。
ptype:查看变量类型。
bt:列出当前程序正存活着的栈帧。
frame: 根据栈帧编号,切换栈帧。
display:设置跟踪变量
undisplay:取消设置跟踪变量。 使用跟踪变量的编号
Makefile项目管理
项目代码编译管理
节省编译项目时间
一次编写终身受益
操作示例文件 add .c sub,c mul,c div.c main.c
基本规则
2.检查规则中的目标是否需要更新,必须先检查它的所有依赖,依赖中有任一个被更新,则目标必须更新。
- 分析各个目标和依赖之间的关系
- 根据依赖关系自底向上执行命令
- 根据修改时间比目标新 确定更新
- 如果目标不依赖任何条件 则执行对应命令 以示更新
命名 Makefile makefile
目标:一个 依赖
(tab)命令
- 目标的时间必须晚于依赖条件的时间,否则,更新目标
2. 依赖条件如果不存在,找寻新的规则去产生依赖条件。
注意makefile是从小到上执行命令 一般最终目标就是最后的
除非在开头写上
ALL:目标
ALL:指定 makefile 的终极目标
Makefile 函数
src = $(wildcard *.c)
找到当前目录下所有后缀为.c的文件,赋值给src
obj=$(patsubst %.c,%.o,$(src))
把src变量里所有后缀为.c文件替换成.o
就是将参数3里面满足参数1的都替换为参数2
clean
用途 清楚编译生成的之间.o文件和最终目标文件
make clean 如果当前目录下有同名clean文件 则不执行clean对应的命令
伪目标声明: .PHONY:clean
clean命令中的特殊符号
-“-”
-“@”、
makefile自动变量
$@ 表示规则中的目标
$<表示规则中的第一个条件
$^表示规则中的所有条件,组成一个列表,以空格隔开 如果这个列表还有重复项则消除重复项
makefile自动推导
objects = main.o kbd.o command.o display.o \insert.o search.o files.o utils.oedit : $(objects)cc -o edit $(objects)main.o : defs.hkbd.o : defs.h command.hcommand.o : defs.h command.hdisplay.o : defs.h buffer.hinsert.o : defs.h buffer.hsearch.o : defs.h buffer.hfiles.o : defs.h buffer.h command.hutils.o : defs.h.PHONY : cleanclean :rm edit $(objects)
objects = main.o kbd.o command.o display.o \insert.o search.o files.o utils.oedit : $(objects)cc -o edit $(objects)$(objects) : defs.h.PHONY : cleanclean :rm edit $(objects)
Linux编译C工程
先创建一个文件夹 ,利用vi来编写 .c 和.h 文件,通过GCC编译器来对每个文件进行编译并 *.o文件链接到main.o 但是每次运行都需要重新编译,所有使用make工具来对工程编译运行
创建一个Makefile 文件到工程目录,
vi Makefile//进入编译模式main: main.o input.o calcu.o//应该使用TABgcc -o main main.o input.o calcu.omian.o:mian.cgcc -c mian.cinput.o: input.cgcc -c input.ccalcu.o: calcu.cgcc -c calcu.cclean:rm *.orm main//ESC :wq 保存并退出
在终端中输入 make 系统会自动识别出文件的修改时间是否被改动,只编译修改过的文件
输入 make clean 清除编译文件 然后就可以重新编译文件
makefile 语法
目标: 处理的文件命令(如何处理)
makefile中变量只为字符串 使用时需要 $(object)
普通等号为c++中引用的方法,即看变量的最后一次的值
若要单纯赋值 用 := 方法赋值
变量可 +=
print:@echo object:$(object)
终端输入:make print
输出:object:
若要将全部.c编译成.o文件 百分号%可以代表任意长度的字符串
可以用 %.o: %.c
所以代码可改为
objects =mian.o input.oobjects += calcu.omain: $(objects)gcc -o main $(objects)%.o: %.cgcc -c $<clean:rm *.orm main
*在linux文件系统中可以代表任意多个字符
clean在这里是伪目标 不是为了创建clean目标 而是为了执行它下面的命令,在之前的命令中也没有创建clean文件,所以每次输入 make clean 都会重新编译 即执行它的命令, 如果不小心创建了clean文件规则没有依赖文件, 所以目标会被认为是最新的 ,就不会执行它的命令了 所以为了避免这个问题 ,我们可以在此前将clean声明为伪目标
声明方式:
.PHONY: clean
更改为:
objects =mian.o input.oobjects += calcu.omain: $(objects)gcc -o main $(objects)%.o: %.cgcc -c $<.PHONY:cleanclean:rm *.orm mian
看 makefile 语法书
putty xftp
连接 传输
