1、makefile原理(增量编译生成代码) # (注释符)
目标------依赖
目标不存在//目标比依赖旧才会执行命令;
makefile的实现
1、命名要求(Makefile/makefile)
2、规则的集合
目标文件(1):
依赖文件(0--n):
<tab>命令(0-n)
3、把最终生成的文件作为第一个规则的目标
伪目标()--------每次make都一定执行的指令。
目标不存在,执行命令生成不了目标。 目标由依赖和命令组成
rebuild:全量编译
.PHONY :描述伪目标
变量
1、自定义变量 变量名:=值 (所有的值都是字符串类型)
引用变量用 $ (变量名)
变量替换
2、预定义变量
有无CC:= gcc 区别
3、自动变量----同一个变量名值会随规则变化而变化
用%字符管理格式关系:
百分号负责从字符串中把数据匹配出来:
可以用在第二个规则中,按格式从第一个规则的依赖文件中匹配,来构成新依赖。
使用 % 后可以直接只在第一规则的依赖中进下修改
内置函数
wildcard(通配符)
从当前目录的所有文件中取出符合要求的文件,
通过通配符取所有.c文件并存入变量,定义个all的伪目标来查看内容;
echo用于在终端上显示文本或变量的值可以重定向,区别于cat用于查看文件内容
patsubst (pattern substtitude)---模式匹配
把一个字符串中的内容匹配出来换成新的目标文件;最终文件。
单独编译链接
三个单独的c文件,通过makefile分别生成可执行程序。
首先找到目标,由于是三个目标,所以采用伪目标all。
Linux系统编程:
要直接使用操作系统功能要直接使用system call(系统调用),
shell 和库函数是间接使用系统调用;
posix (系统调用的规范)unix linux macos
库函数遵循 ISOC 规范,支持c语言的平台都支持
系统调用也是使用的c语言函数,但是该函数不是在用户态里面,而是在内核态里面进行压栈出栈。
怎么学系统编程:
1、看man帮助手册
重点看2,3,7号手册
安装库函数帮助手册:sudo apt install manpages-posix-dev
man 3 printf (查看3号手册的库函数)
1号手册的printf
帮助手册:名字---声明---细节---返回值
先阅读名字,
再看声明和返回值,(头文件,指针类型的参数(有没有const,无const会修改参数,传入传出参数),指针类型的返回值(主调函数是否要释放内存,例子:fopen / fclose,,,malloc))
主调函数额外释放。在L
inux系统调用中,返回值不实现功能,只是用来处理报错。
细节--按需查看
----------------------------------------------------------------
文件:
狭义:储存在外部储存介质上的数据集合;
广义:速度慢,容量大,可以持久存储,(万物皆文件)
文件的类型:
普通文件
目录文件
软链接
字符设备文件(消息传递以字符为单位)
块设备文件(以块为单位,一般512字节为单位。磁盘传输单位)
管道文件(通信,让两个软件直接进行通信)
socket (网络通信,两个设备之间通信)
文件的使用:
fopen:
库函数;
FILE (文件流/用户态文件缓冲区)
列出系统报错信息:perror
封装带参数的宏定义(经常重复的代码,把他封装成带参数的宏定义)
可以使用反斜杠 \ 调整格式换行
---------------------------
--------------------------------------------------------
追加模式:
“a” append (只写追加,默认从文件的结尾写入)
"a+" 读写追加,打开时处于文件的开始,写入时ptr跳到文件的末尾;
日志系统:在服务器挂机的时候用于复盘修复数据,记录行为的工具,绝对不允许修改;
“a” 模式实例:
“a+”模式实例:
文件流:
fseek():移动文件流的指针ptr
ftell():返回ptr的位置
-----------------------
改变文件权限:chmod
man -f chmod :查看参考手册出现该命令的位置;
sscanf('输入参数',‘格式’,输出参数)//把输入参数按照格式输出到输出参数;
getcwd : 获得当前工作目录
buf不为空,直接返回buf
buf为空,返回一个堆空间的地址
当接收参数是空指针的时候,getcwd会自动分配堆空间 (但是堆空间未释放,导致内存泄漏)
chdir改变当前工作目录
当前工作目录cwd是进程的一个属性;
该程序中有两个进程一个是shell进程一个是shell的子进程
父级进程为终端文件目录,子进程默认继承,chdir后子进程被修改,父级进程不变。
mkdir / rmdir 所有创建文件的行为都会受到掩码umask的影响
rmdir /删除空目录
目录流:
(文件流)指针会自动后移(不了解结构的情况下访问所有数据)(迭代器模式)
(目录流)目录在磁盘中以链表的形式进行存储,每一个链表结点(目录项dirent(directory entry))存储了孩子的基本信息
目录流是目录文件在内存中的缓冲区。(循环遍历当前接口即可访问目录流)
opendir: 创建目录流
closedir:销毁目录流
readdir:读取目录流
运用了c的可变长数组来存储文件名(reclen取决于name)
readdir返回值会存在数据段(数据段是静态区用于存放全局变量)
struct dirent --->目录项()
主调函数申请了一个以struck dirent为基类型的指针变量;
自行编写ls遍历文件:
telldir:获取ptr位置
seekdir:回到指定位置
先readdir再telldir只能读到下一个位置:读取第一个目录时ptr指向下一个目录
rewinddir : 把ptr回到最开始目录流
stat:
主调函数分配内存:
找到最近修改时间在一天内的文件:find