🌈 style:

This commit is contained in:
lzy
2024-06-23 17:45:58 +08:00
parent 5598552b22
commit a5172579e3
16 changed files with 138 additions and 393 deletions

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [第一章 绪论](#第一章-绪论) - [第一章 绪论](#第一章-绪论)
- [第一节](#第一节) - [第一节](#第一节)
@@ -27,12 +28,6 @@
- [进程](#进程) - [进程](#进程)
- [防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放](#防止写越界防止内存泄漏谁打开谁关闭谁申请谁释放) - [防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放](#防止写越界防止内存泄漏谁打开谁关闭谁申请谁释放)
# 第一章 绪论 # 第一章 绪论
课程地址,[史上最强最细腻的linux嵌入式C语言学习教程【李慧芹老师】_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV18p4y167Md/?spm_id_from=333.999.0.0&vd_source=4e03f52e94cfa281cde032856b1f93a7)。 课程地址,[史上最强最细腻的linux嵌入式C语言学习教程【李慧芹老师】_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV18p4y167Md/?spm_id_from=333.999.0.0&vd_source=4e03f52e94cfa281cde032856b1f93a7)。
@@ -49,8 +44,6 @@
| 1967 | B语言 | | 1967 | B语言 |
| 1973 | C语言 | | 1973 | C语言 |
### C语言特点 ### C语言特点
1. 基础性语言 1. 基础性语言
@@ -60,8 +53,6 @@
5. 移植性好,执行效率高 5. 移植性好,执行效率高
6. 允许直接对硬件操作 6. 允许直接对硬件操作
### C语言学习建议 ### C语言学习建议
1. 概念的正确性 1. 概念的正确性
@@ -69,8 +60,6 @@
3. 阅读优秀的程序段 3. 阅读优秀的程序段
4. 大量练习,面试题 4. 大量练习,面试题
### 课程思路 ### 课程思路
1. 基础概念 1. 基础概念
@@ -85,17 +74,13 @@
10. 调试工具gdbmake) 10. 调试工具gdbmake)
11. 常用库函数 11. 常用库函数
### 课程平台 ### 课程平台
* 老师64位的`redhat6``vim``gcc4.4.6(make)` - 老师64位的`redhat6``vim``gcc4.4.6(make)`
* 本人:`WSL-debian``vscode(remote ssh)``gcc12.2.0(make)``ohmyzsh(theme:eastwood)` - 本人:`WSL-debian``vscode(remote ssh)``gcc12.2.0(make)``ohmyzsh(theme:eastwood)`
我的`gcc`版本比较新所以很多提示比较完善老师这个课程是很早的课那个时候的gcc提示没有现在厉害所以还是要结合老师的视频的思路在当时提示不完善的时候是如何手撕代码分析出来的。 我的`gcc`版本比较新所以很多提示比较完善老师这个课程是很早的课那个时候的gcc提示没有现在厉害所以还是要结合老师的视频的思路在当时提示不完善的时候是如何手撕代码分析出来的。
## 第二节 ## 第二节
### 神一般的`Hello world!` ### 神一般的`Hello world!`
@@ -122,8 +107,6 @@ int main(void)
用哪种`main`得看编译器环境,目前在`linux``gcc`下,`int main(void);`常用,需要传参用`int main(int argc, char **argv);` 用哪种`main`得看编译器环境,目前在`linux``gcc`下,`int main(void);`常用,需要传参用`int main(int argc, char **argv);`
### 源文件到可执行文件 ### 源文件到可执行文件
#### gcc #### gcc
@@ -147,8 +130,6 @@ gcc hello.c # 得到a.out可执行文件
gcc hello.c -o myhello # 得到myhello可执行文件 gcc hello.c -o myhello # 得到myhello可执行文件
``` ```
#### make #### make
```bash ```bash
@@ -159,14 +140,10 @@ $ ls
hello hello.c hello hello.c
``` ```
### vim ### vim
老师对于常用的`.vimrc`做了一些介绍,笔者建议`vscode``remote-ssh`插件可以在win的vscode编辑器享受linux的环境。 老师对于常用的`.vimrc`做了一些介绍,笔者建议`vscode``remote-ssh`插件可以在win的vscode编辑器享受linux的环境。
## 第三节 ## 第三节
### 基本概念 ### 基本概念
@@ -216,9 +193,9 @@ hello.c:6:9: warning: unused variable i [-Wunused-variable]
``` ```
* 例如说这个变量`i`定义了但是没用上,就是你清楚来龙去脉可以忽略的警告。 - 例如说这个变量`i`定义了但是没用上,就是你清楚来龙去脉可以忽略的警告。
*`malloc`那个警告就是在告诉你`malloc`所属的`stdlib.h`库未引入。 -`malloc`那个警告就是在告诉你`malloc`所属的`stdlib.h`库未引入。
* C语言程序往往如果能把警告都消除错误也能解决。例如 - C语言程序往往如果能把警告都消除错误也能解决。例如
```c ```c
#include <stdio.h> #include <stdio.h>
@@ -270,20 +247,14 @@ cc a.c -o a
fopen():No such file or directory fopen():No such file or directory
``` ```
##### 2. 以函数为单位来进行程序编写 ##### 2. 以函数为单位来进行程序编写
`main`是特殊的定义,其实就是一个正在运行的线程。其实对于内核而言,是只有进程的概念,且与我们理解的进程、线程不一样。 `main`是特殊的定义,其实就是一个正在运行的线程。其实对于内核而言,是只有进程的概念,且与我们理解的进程、线程不一样。
##### 3. 声明部分+实现部分 ##### 3. 声明部分+实现部分
早期的编译器要求变量先定义后使用。 早期的编译器要求变量先定义后使用。
##### 4. `return 0/exit(0)` ##### 4. `return 0/exit(0)`
结束当前进程,是给父进程看的。 结束当前进程,是给父进程看的。
@@ -303,12 +274,8 @@ Hello world!
在我本地无法复现,新版本可能改了。 在我本地无法复现,新版本可能改了。
##### 5. 多用空格空行 ##### 5. 多用空格空行
##### 6. 添加注释 ##### 6. 添加注释
```c ```c
@@ -328,25 +295,14 @@ func(){
#endif #endif
``` ```
#### 算法 #### 算法
解决问题的方法。流程图NS图FSM有限状态机 解决问题的方法。流程图NS图FSM有限状态机
#### 程序 #### 程序
用某种语言实现算法 用某种语言实现算法
#### 进程 #### 进程
#### 防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放 #### 防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [第二章 数据类型,运算符和表达式](#第二章-数据类型运算符和表达式) - [第二章 数据类型,运算符和表达式](#第二章-数据类型运算符和表达式)
- [数据类型(基本数据类型)](#数据类型基本数据类型) - [数据类型(基本数据类型)](#数据类型基本数据类型)
@@ -13,10 +14,6 @@
- [表达式和语句的区别](#表达式和语句的区别) - [表达式和语句的区别](#表达式和语句的区别)
- [运算符相关代码](#运算符相关代码) - [运算符相关代码](#运算符相关代码)
# 第二章 数据类型,运算符和表达式 # 第二章 数据类型,运算符和表达式
## 数据类型(基本数据类型) ## 数据类型(基本数据类型)

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [第三章 输入输出专题](#第三章-输入输出专题) - [第三章 输入输出专题](#第三章-输入输出专题)
- [内容](#内容) - [内容](#内容)
@@ -6,26 +7,22 @@
- [`printf`](#printf) - [`printf`](#printf)
- [`scanf`](#scanf) - [`scanf`](#scanf)
- [字符输入输出函数](#字符输入输出函数) - [字符输入输出函数](#字符输入输出函数)
- [字符串输入输出函数](#字符串输入输出函数)
- [练习专题](#练习专题)
- [夸脱水](#夸脱水)
- [三角形面积](#三角形面积)
- [求根公式](#求根公式)
# 第三章 输入输出专题 # 第三章 输入输出专题
input & output -> I/O(标准IO文件IO) input & output -> I/O(标准IO文件IO)
## 内容 ## 内容
1. 格式化输入输出函数:`scanf`, `printf` 1. 格式化输入输出函数:`scanf`, `printf`
2. 字符输入输出函数:`getchar`, `putchar` 2. 字符输入输出函数:`getchar`, `putchar`
3. 字符串输入输出函数:`gets(!)`,`puts` 3. 字符串输入输出函数:`gets(!)`,`puts`
## 格式化输入输出函数 ## 格式化输入输出函数
![标准输出格式字符](https://s2.loli.net/2024/03/18/OMiu6CUDZy5RH3P.png) ![标准输出格式字符](https://s2.loli.net/2024/03/18/OMiu6CUDZy5RH3P.png)
@@ -39,8 +36,6 @@ int printf(const char *format, ...);
format: "%【修饰符】格式字符" format: "%【修饰符】格式字符"
``` ```
- 有关`l`修饰符的提醒 - 有关`l`修饰符的提醒
```C ```C
@@ -63,16 +58,12 @@ int main()
} }
``` ```
传输一个5G的文件 传输一个5G的文件
```c ```c
5LL*1204LL*1204LL*1204LL 5LL*1204LL*1204LL*1204LL
``` ```
定义一个宏,表示一年有多少秒 定义一个宏,表示一年有多少秒
```c ```c
@@ -80,16 +71,12 @@ int main()
#define SEC_YEAR (60LL * 60LL * 24LL * 365LL) #define SEC_YEAR (60LL * 60LL * 24LL * 365LL)
``` ```
- 函数 变参与定参重载的区别 - 函数 变参与定参重载的区别
- 变参:编译器只报警告,函数自己都不知道自己有多少个参数 - 变参:编译器只报警告,函数自己都不知道自己有多少个参数
- 定参重载:编译报错 - 定参重载:编译报错
- `\n`的作用 - `\n`的作用
强制刷新缓冲区,以死循环调试举例。 强制刷新缓冲区,以死循环调试举例。
@@ -105,8 +92,6 @@ while (1)
printf("[%s:%d]after while().\n", __FUNCTION__, __LINE__); printf("[%s:%d]after while().\n", __FUNCTION__, __LINE__);
``` ```
- 完整代码 - 完整代码
```c ```c
@@ -200,8 +185,6 @@ int main()
#define SEC_YEAR (60LL * 60LL * 24LL * 365LL) #define SEC_YEAR (60LL * 60LL * 24LL * 365LL)
``` ```
### `scanf` ### `scanf`
```c ```c
@@ -211,8 +194,6 @@ format:抑制符*
``` ```
- 完整代码 - 完整代码
```c ```c
@@ -301,8 +282,6 @@ int main()
} }
``` ```
## 字符输入输出函数 ## 字符输入输出函数
```c ```c
@@ -357,8 +336,6 @@ char *fgets(char *s, int size, FILE *stream);// 最多读到'size-1'个
`getline``GNU libc`的方言,可以动态内存保证读取一整行。 `getline``GNU libc`的方言,可以动态内存保证读取一整行。
## 练习专题 ## 练习专题
### 夸脱水 ### 夸脱水
@@ -474,4 +451,3 @@ void root(void)
printf("x2 = %f\n", x2); printf("x2 = %f\n", x2);
} }
``` ```

View File

@@ -1,5 +1,6 @@
# 目录 # 目录
- [目录](#目录)
- [流程控制](#流程控制) - [流程控制](#流程控制)
- [关键字](#关键字) - [关键字](#关键字)
- [详解选择](#详解选择) - [详解选择](#详解选择)
@@ -26,29 +27,22 @@
- [11](#11) - [11](#11)
- [12](#12) - [12](#12)
# 流程控制 # 流程控制
1. 顺序,选择,循环 1. 顺序,选择,循环
2. NS图流程图工具VisioDia 2. NS图流程图工具VisioDia
3. 简单结构与复杂结构:自然流程 3. 简单结构与复杂结构:自然流程
- 顺序:语句逐句执行 - 顺序:语句逐句执行
- 选择:出现了一种以上的情况 - 选择:出现了一种以上的情况
- 循环:在某个条件成立的情况下,重复执行某个动作 - 循环:在某个条件成立的情况下,重复执行某个动作
## 关键字 ## 关键字
- 选择:`if-else``switch-case` - 选择:`if-else``switch-case`
- 循环:`while``do-while``for``if-goto` - 循环:`while``do-while``for``if-goto`
- 辅助控制:`continue``break` - 辅助控制:`continue``break`
## 详解选择 ## 详解选择
### `if-else` ### `if-else`
@@ -156,8 +150,6 @@ int main()
} }
``` ```
### `switch-case` ### `switch-case`
```c ```c
@@ -243,8 +235,6 @@ int main()
} }
``` ```
## 详解循环 ## 详解循环
### `while` ### `while`
@@ -255,8 +245,6 @@ while(exp)
loop; loop;
``` ```
### `do-while` ### `do-while`
```c ```c
@@ -268,8 +256,6 @@ do
``` ```
### `for` ### `for`
```c ```c
@@ -278,15 +264,11 @@ for(exp1;exp2;exp3)
loop; loop;
``` ```
### `goto` ### `goto`
- 慎重使用`if-goto` - 慎重使用`if-goto`
- `goto`实现的是 无条件的跳转,且不能跨函数跳转 - `goto`实现的是 无条件的跳转,且不能跨函数跳转
### 死循环 ### 死循环
```c ```c
@@ -296,16 +278,10 @@ for(;;);
`ctrl + c`杀掉死循环。 `ctrl + c`杀掉死循环。
### 辅助控制 ### 辅助控制
`break``continue` `break``continue`
## 练习专题 ## 练习专题
### 1 ### 1
@@ -364,8 +340,6 @@ for(;;);
> >
> F > F
### 10 ### 10
> 包括钻石型 > 包括钻石型

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [数组](#数组) - [数组](#数组)
- [一维数组](#一维数组) - [一维数组](#一维数组)
@@ -21,19 +22,14 @@
- [单词计数](#单词计数) - [单词计数](#单词计数)
- [多维数组](#多维数组) - [多维数组](#多维数组)
# 数组 # 数组
构造类型之一,连续存放。 构造类型之一,连续存放。
> [!warning] > [!warning]
> >
> 时间关系,大量的练习题,没有做笔记,只记录了题目。自己思考加看课程足矣。 > 时间关系,大量的练习题,没有做笔记,只记录了题目。自己思考加看课程足矣。
## 一维数组 ## 一维数组
1. 定义 1. 定义
@@ -57,8 +53,6 @@
5. 数组越界 5. 数组越界
### 练习部分 ### 练习部分
#### 斐波那契数列前10项 #### 斐波那契数列前10项
@@ -230,8 +224,6 @@ static void primer(void)
} }
``` ```
## 二维数组 ## 二维数组
1. 定义,初始化 1. 定义,初始化
@@ -285,10 +277,6 @@ static void primer(void)
`a+1`跨越了行而不是单个元素。 `a+1`跨越了行而不是单个元素。
### 练习部分 ### 练习部分
#### 行列互换 #### 行列互换
@@ -299,10 +287,6 @@ static void primer(void)
#### 矩阵乘积 #### 矩阵乘积
## 字符数组 ## 字符数组
1. 定义,初始化,存储特点 1. 定义,初始化,存储特点
@@ -316,8 +300,6 @@ static void primer(void)
3. 常用函数 3. 常用函数
### 常用函数 ### 常用函数
1. `strlen`和`sizeof` 1. `strlen`和`sizeof`
@@ -375,8 +357,6 @@ static void primer(void)
// out:hello world // out:hello world
``` ```
4. `strcmp`与`strncmp` 4. `strcmp`与`strncmp`
```c ```c
@@ -387,17 +367,12 @@ static void primer(void)
// 指定比较前5个字符 // 指定比较前5个字符
``` ```
### 练习部分 ### 练习部分
#### 单词计数 #### 单词计数
## 多维数组 ## 多维数组
```c ```c
int a[2][3][4]; int a[2][3][4];
``` ```

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [指针](#指针) - [指针](#指针)
- [变量与地址](#变量与地址) - [变量与地址](#变量与地址)
@@ -16,7 +17,6 @@
- [指针数组与数组指针](#指针数组与数组指针) - [指针数组与数组指针](#指针数组与数组指针)
- [多级指针](#多级指针) - [多级指针](#多级指针)
# 指针 # 指针
## 变量与地址 ## 变量与地址
@@ -27,8 +27,6 @@
`100`是存放在这个地址的变量的值。 `100`是存放在这个地址的变量的值。
## 指针与指针变量 ## 指针与指针变量
```c ```c
@@ -39,14 +37,10 @@ int **q = &p;
p是一个指针变量他所存放的值是指针指向另一个变量`i`的地址。 p是一个指针变量他所存放的值是指针指向另一个变量`i`的地址。
## 直接访问与间接访问 ## 直接访问与间接访问
同样对于上面那个存放值为`100`的变量,既可以通过`i`直接访问,也可以通过`*p, **q`来间接访问。 同样对于上面那个存放值为`100`的变量,既可以通过`i`直接访问,也可以通过`*p, **q`来间接访问。
```c ```c
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -122,8 +116,6 @@ int main()
} }
``` ```
## 空指针与野指针 ## 空指针与野指针
- 野指针:`int *p = 0x14532534`,不确定这个地址的情况,盲目的指过去,那么读或者写都是非法的。 - 野指针:`int *p = 0x14532534`,不确定这个地址的情况,盲目的指过去,那么读或者写都是非法的。
@@ -147,16 +139,12 @@ int main()
} }
``` ```
## 空类型 ## 空类型
`void *q` `void *q`
万能类型。 万能类型。
## 定义与初始化的书写规则 ## 定义与初始化的书写规则
```c ```c
@@ -164,14 +152,10 @@ int *p;
int* p; int* p;
``` ```
## 指针运算 ## 指针运算
`&` `*` 关系运算 `++` `--` `&` `*` 关系运算 `++` `--`
## 指针与数组 ## 指针与数组
### 指针与一维数组 ### 指针与一维数组
@@ -269,8 +253,6 @@ int main()
} }
``` ```
### 指针与二维数组 ### 指针与二维数组
```c ```c
@@ -326,8 +308,6 @@ int main()
} }
``` ```
### 指针与字符数组 ### 指针与字符数组
```c ```c
@@ -387,8 +367,6 @@ int main()
} }
``` ```
## const 与指针 ## const 与指针
- 常量指针:**指向常量的指针** - 常量指针:**指向常量的指针**
@@ -494,10 +472,6 @@ int main()
``` ```
## 指针数组与数组指针 ## 指针数组与数组指针
- 数组指针:指向数组的**指针**。 - 数组指针:指向数组的**指针**。
@@ -512,8 +486,6 @@ int main()
如:`int *arr[3];` 看成 `int *[3] arr;` 如:`int *arr[3];` 看成 `int *[3] arr;`
```c ```c
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -552,9 +524,4 @@ int main()
} }
``` ```
## 多级指针 ## 多级指针

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [函数](#函数) - [函数](#函数)
- [函数的定义](#函数的定义) - [函数的定义](#函数的定义)
@@ -16,15 +17,12 @@
- [函数指针数组](#函数指针数组) - [函数指针数组](#函数指针数组)
- [指向指针函数的函数指针数组](#指向指针函数的函数指针数组) - [指向指针函数的函数指针数组](#指向指针函数的函数指针数组)
# 函数 # 函数
## 函数的定义 ## 函数的定义
数据类型 函数名 【数据类型 形参名,数据类型 形参,...】 数据类型 函数名 【数据类型 形参名,数据类型 形参,...】
```c ```c
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -45,8 +43,6 @@ int main(int argc, char *argv[])
} }
``` ```
```c ```c
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -70,8 +66,6 @@ void print_hello(void)
} }
``` ```
## 函数的传参 ## 函数的传参
值传递 值传递
@@ -127,10 +121,6 @@ int main()
} }
``` ```
## 函数的调用 ## 函数的调用
### 嵌套调用 ### 嵌套调用
@@ -170,8 +160,6 @@ int main()
} }
``` ```
### 递归调用 ### 递归调用
```c ```c
@@ -229,10 +217,6 @@ int main()
} }
``` ```
## 函数与数组 ## 函数与数组
### 一维数组 ### 一维数组
@@ -253,8 +237,6 @@ int *p = a;
| *p | int | | *p | int |
| p+1 | int* | | p+1 | int* |
```c ```c
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -310,8 +292,6 @@ int main()
} }
``` ```
### 二维数组 ### 二维数组
```c ```c
@@ -326,8 +306,6 @@ int (*q)[N] = a;
// 行指针 // 行指针
``` ```
| 传参 | 类型 | | 传参 | 类型 |
| -------------------------- | -------------------------------------- | | -------------------------- | -------------------------------------- |
| `a[i][j]` | int | | `a[i][j]` | int |
@@ -421,10 +399,6 @@ int main()
} }
``` ```
### 字符数组 ### 字符数组
```c ```c
@@ -470,10 +444,6 @@ int main()
} }
``` ```
## 函数与指针 ## 函数与指针
### 指针函数 ### 指针函数
@@ -484,8 +454,6 @@ int main()
如:`int * fun(int);` 如:`int * fun(int);`
### 函数指针 ### 函数指针
是一个**指针**,指向**函数**。 是一个**指针**,指向**函数**。
@@ -494,8 +462,6 @@ int main()
如: `int (*p)(int);` 如: `int (*p)(int);`
### 函数指针数组 ### 函数指针数组
由**函数指针**组成的数组。 由**函数指针**组成的数组。
@@ -504,14 +470,10 @@ int main()
如: `int (*arr[N])(int);` 如: `int (*arr[N])(int);`
### 指向指针函数的函数指针数组 ### 指向指针函数的函数指针数组
`int *(*funcp[N])(int)` `int *(*funcp[N])(int)`
```c ```c
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -553,4 +515,3 @@ int main()
exit(0); exit(0);
} }
``` ```

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [构造类型](#构造类型) - [构造类型](#构造类型)
- [结构体](#结构体) - [结构体](#结构体)
@@ -19,7 +20,6 @@
- [枚举](#枚举) - [枚举](#枚举)
- [typedef](#typedef) - [typedef](#typedef)
# 构造类型 # 构造类型
## 结构体 ## 结构体
@@ -39,26 +39,16 @@ struct 结构体名
}; };
``` ```
### 嵌套定义 ### 嵌套定义
### 定义变量(变量,数组,指针),初始化及成员引用 ### 定义变量(变量,数组,指针),初始化及成员引用
成员引用: 变量名. 成员名,指针->成员名,(*指针).成员名 成员引用: 变量名. 成员名,指针->成员名,(*指针).成员名
### 结构体占用的内存空间大小 ### 结构体占用的内存空间大小
### 函数传参(值,地址) ### 函数传参(值,地址)
```c ```c
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -175,10 +165,6 @@ int main()
} }
``` ```
> 跳过 > 跳过
## 共用体 ## 共用体
@@ -196,8 +182,6 @@ union 共用体名
}; };
``` ```
### 嵌套定义 ### 嵌套定义
### 定义变量(变量,数组,指针),初始化及成员引用 ### 定义变量(变量,数组,指针),初始化及成员引用
@@ -208,12 +192,6 @@ union 共用体名
### 位域 ### 位域
## 枚举 ## 枚举
```c ```c

View File

@@ -1,10 +1,10 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [动态内存管理](#动态内存管理) - [动态内存管理](#动态内存管理)
- [函数传参相关问题](#函数传参相关问题) - [函数传参相关问题](#函数传参相关问题)
- [关于 free](#关于-free) - [关于 free](#关于-free)
# 动态内存管理 # 动态内存管理
```` c ```` c
@@ -14,12 +14,8 @@ void free(void *ptr);
void *realloc(void *ptr, size_t size); // 重新分配空间 void *realloc(void *ptr, size_t size); // 重新分配空间
```` ````
原则:谁申请谁释放。 原则:谁申请谁释放。
## 函数传参相关问题 ## 函数传参相关问题
1. 要么用二级指针 1. 要么用二级指针
@@ -65,10 +61,6 @@ int main()
``` ```
## 关于 free ## 关于 free
`free`操作没有扣掉那块内存,没有改变那块内存的值,也没有改变指针的指向。 `free`操作没有扣掉那块内存,没有改变那块内存的值,也没有改变指针的指向。
@@ -110,6 +102,3 @@ int main()
} }
``` ```

View File

@@ -4,8 +4,6 @@
`make`会优先使用`makefile`,发布的项目一般是一个`Makefile`,方便用户写自己的`makefile` `make`会优先使用`makefile`,发布的项目一般是一个`Makefile`,方便用户写自己的`makefile`
## 参考资料 ## 参考资料
[跟我一起写Makefile — 跟我一起写Makefile 1.0 文档 (seisman.github.io)](https://seisman.github.io/how-to-write-makefile/) [跟我一起写Makefile — 跟我一起写Makefile 1.0 文档 (seisman.github.io)](https://seisman.github.io/how-to-write-makefile/)

View File

@@ -1,14 +1,14 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [数据结构](#数据结构) - [数据结构](#数据结构)
- [架构梳理](#架构梳理) - [架构梳理](#架构梳理)
- [静态库与动态库](#静态库与动态库) - [静态库与动态库](#静态库与动态库)
- [静态库](#静态库) - [静态库](#静态库)
- [以链式双向链表的`lib2`为例](#以链式双向链表的lib2为例) - [以链式双向链表的`lib2`为例](#以链式双向链表的lib2为例)
- [动态库](#动态库) - [动态库](#动态库)
- [还是以`lib2`为例](#还是以lib2为例) - [还是以`lib2`为例](#还是以lib2为例)
- [以链式存储栈为例,`libstack`依赖`libllist`](#以链式存储栈为例libstack依赖libllist) - [以链式存储栈为例,`libstack`依赖`libllist`](#以链式存储栈为例libstack依赖libllist)
# 数据结构 # 数据结构
@@ -52,8 +52,6 @@
2. 球钟算法 2. 球钟算法
三个栈1h5min1min。27个球过了多久队列里又是1到27的顺序。 三个栈1h5min1min。27个球过了多久队列里又是1到27的顺序。
- 树状1:N - 树状1:N
**递归**。**递归**转**非递归**。 **递归**。**递归**转**非递归**。
@@ -87,34 +85,24 @@
先加中,或者,中加后,都可以逆推出树。先加后不行。 先加中,或者,中加后,都可以逆推出树。先加后不行。
- 平衡: - 平衡:
有很多种条件判定。 有很多种条件判定。
这棵树的左右子树个数差值为1。 这棵树的左右子树个数差值为1。
- 广义表 - 广义表
`( root ( left ) ( right) )`,进行嵌套。 `( root ( left ) ( right) )`,进行嵌套。
- 搜索树 - 搜索树
空间换时间,查找是**o(1)**。 空间换时间,查找是**o(1)**。
**课后作业:词频统计** **课后作业:词频统计**
-N:M -N:M
## 静态库与动态库 ## 静态库与动态库
- 静态库: - 静态库:
@@ -124,8 +112,6 @@
- 公交车,只能在指定的路径。 - 公交车,只能在指定的路径。
- 运行时引入,占用运行时间。 - 运行时引入,占用运行时间。
### 静态库 ### 静态库
1. `libxx.a` 1. `libxx.a`
@@ -140,9 +126,7 @@
5. `ldd -print shared libirary dependencies` 5. `ldd -print shared libirary dependencies`
打印所用到的动态库的内容 打印所用到的动态库的内容
#### 以链式双向链表的`lib2`为例
#### 以链式双向链表的`lib2`为例。
```bash ```bash
*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ldd ./main *[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ldd ./main
@@ -180,10 +164,9 @@
1 std1 77 15 1 std1 77 15
0 std0 83 86 0 std0 83 86
``` ```
这时`main.c`路径下都不需要`llist.c``llist.h`了,`#include`时也从`"llist.h"`变为`<llist.h>` 这时`main.c`路径下都不需要`llist.c``llist.h`了,`#include`时也从`"llist.h"`变为`<llist.h>`
### 动态库 ### 动态库
1. `libxx.so` 1. `libxx.so`
@@ -203,10 +186,7 @@ cp xx.co ~/lib
export LD_LIBRARY_PATH= ~/lib export LD_LIBRARY_PATH= ~/lib
``` ```
#### 还是以`lib2`为例
#### 还是以`lib2`为例。
```bash ```bash
*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ls *[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ls
@@ -246,9 +226,7 @@ export LD_LIBRARY_PATH= ~/lib
> >
> 当动态库和静态库重名,会优先链接**静态库**。 > 当动态库和静态库重名,会优先链接**静态库**。
#### 以链式存储栈为例,`libstack`依赖`libllist`
#### 以链式存储栈为例,`libstack`依赖`libllist`。
```bash ```bash
*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ ls *[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ ls

View File

@@ -11,4 +11,3 @@
2. 输入设备 2. 输入设备
3. 并发 3. 并发

View File

@@ -1,10 +1,11 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [I/O操作](#io操作) - [I/O操作](#io操作)
- [标准IO](#标准io) - [标准IO](#标准io)
- [文件IO/系统调用IO](#文件io系统调用io) - [文件IO/系统调用IO](#文件io系统调用io)
- [文件描述符的概念](#文件描述符的概念) - [文件描述符的概念](#文件描述符的概念)
- [文件IO操作相关函数](#文件io操作相关函数) - [文件IO操作相关函数](#文件io操作相关函数)
- [例题通过文件IO处理csv表格](#例题通过文件io处理csv表格) - [例题通过文件IO处理csv表格](#例题通过文件io处理csv表格)
- [文件IO与标准IO的区别](#文件io与标准io的区别) - [文件IO与标准IO的区别](#文件io与标准io的区别)
- [IO的效率问题](#io的效率问题) - [IO的效率问题](#io的效率问题)
@@ -17,7 +18,6 @@
- [同步](#同步) - [同步](#同步)
- [/dev/fd/目录](#devfd目录) - [/dev/fd/目录](#devfd目录)
# I/O操作 # I/O操作
输入输出是一切实现的基础。 输入输出是一切实现的基础。
@@ -28,8 +28,6 @@
优先使用**标准IO**,兼容性更好,还有合并系统调用的优势。 优先使用**标准IO**,兼容性更好,还有合并系统调用的优势。
## 标准IO ## 标准IO
```c ```c
@@ -205,23 +203,17 @@ FILE *tmpfile(void);
``` ```
## 文件IO/系统调用IO ## 文件IO/系统调用IO
文件描述符(`fd`是在文件IO中贯穿始终的类型。 文件描述符(`fd`是在文件IO中贯穿始终的类型。
### 文件描述符的概念 ### 文件描述符的概念
是一个整型数,是一个指针数组的下标。 是一个整型数,是一个指针数组的下标。
优先使用当前可用范围内最小的。 优先使用当前可用范围内最小的。
### 文件IO操作相关函数
### 文件IO操作相关函数
- `open` - `open`
- `close` - `close`
@@ -305,8 +297,6 @@ off_t lseek(int fd, offt offset, int whence);
``` ```
### 例题通过文件IO处理csv表格 ### 例题通过文件IO处理csv表格
```csv ```csv
@@ -320,8 +310,6 @@ off_t lseek(int fd, offt offset, int whence);
可以使用16进制查看工具 可以使用16进制查看工具
### 文件IO与标准IO的区别 ### 文件IO与标准IO的区别
区别:响应速度&吞吐量 区别:响应速度&吞吐量
@@ -330,17 +318,11 @@ off_t lseek(int fd, offt offset, int whence);
响应速度快就文件IO吞吐量大就标准IO。 响应速度快就文件IO吞吐量大就标准IO。
> [!warning] > [!warning]
> 二者不可混用 > 二者不可混用
转换方法:`fileno`, `fdopen` 转换方法:`fileno`, `fdopen`
### IO的效率问题 ### IO的效率问题
#### 习题 #### 习题
@@ -399,8 +381,6 @@ rm $dst
``` ```
#### 结果 #### 结果
```bash ```bash
@@ -424,8 +404,6 @@ Max BUFSIZE before segfault: 8388608
`ulimit -a`中,我的系统的`stack size``8192`,所以`BUFSIZE`不能超过`8192`,否则会段错误。与测试结果一致。 `ulimit -a`中,我的系统的`stack size``8192`,所以`BUFSIZE`不能超过`8192`,否则会段错误。与测试结果一致。
### 文件共享 ### 文件共享
多个任务共同操作一个文件或者协同完成任务 多个任务共同操作一个文件或者协同完成任务
@@ -465,8 +443,6 @@ p1->read -> p2->write
``` ```
### 原子操作 ### 原子操作
指不可分割的操作 指不可分割的操作
@@ -475,8 +451,6 @@ p1->read -> p2->write
`tmpnam`函数,产生文件名和创建文件是两步,会有并发问题。 `tmpnam`函数,产生文件名和创建文件是两步,会有并发问题。
### 程序中的重定向:`dup`, `dup2` ### 程序中的重定向:`dup`, `dup2`
```c ```c
@@ -489,8 +463,6 @@ int dup(int oldfd);
int dup2(int oldfd, int newfd); int dup2(int oldfd, int newfd);
``` ```
### 同步 ### 同步
同步内核层面的buffer和cache 同步内核层面的buffer和cache
@@ -508,8 +480,6 @@ int ioctl(int fd, unsigned long request, ... /* arg */);
``` ```
### /dev/fd/目录 ### /dev/fd/目录
**虚目录**:显示当前进程的文件描述符信息 **虚目录**:显示当前进程的文件描述符信息

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [文件系统](#文件系统) - [文件系统](#文件系统)
- [目录和文件](#目录和文件) - [目录和文件](#目录和文件)
@@ -13,15 +14,12 @@
- [函数之间正常的跳转](#函数之间正常的跳转) - [函数之间正常的跳转](#函数之间正常的跳转)
- [资源的获取及控制](#资源的获取及控制) - [资源的获取及控制](#资源的获取及控制)
# 文件系统 # 文件系统
`ls`的实现,如`myls -l -a -i -n` `ls`的实现,如`myls -l -a -i -n`
`cmd --长格式 -短格式 非选项的传参` `cmd --长格式 -短格式 非选项的传参`
## 目录和文件 ## 目录和文件
1. 获取文件属性 1. 获取文件属性
@@ -100,7 +98,6 @@ int fchmod(int fd, mode_t mode);
2. `UFS` 2. `UFS`
缺点:不善于处理大量的小文件,因为每个文件都有一个`inode`,占用空间。 缺点:不善于处理大量的小文件,因为每个文件都有一个`inode`,占用空间。
> 面试题: > 面试题:
> 不用比较比较两个uint32_t的大小 > 不用比较比较两个uint32_t的大小
> 使用位图 > 使用位图
@@ -114,13 +111,11 @@ int fchmod(int fd, mode_t mode);
限制:不能给分区建立,不能给目录建立 限制:不能给分区建立,不能给目录建立
- 符号链接 - 符号链接
`ln -s bigfile_link bigfile_s` `ln -s bigfile_link bigfile_s`
优点:可以跨分区,可以给目录建立 优点:可以跨分区,可以给目录建立
```c ```c
int link(const char *oldpath, const char *newpath); int link(const char *oldpath, const char *newpath);
@@ -275,8 +270,6 @@ long telldir(DIR *dirp);
作业:用另一套函数实现`mydu` 作业:用另一套函数实现`mydu`
## 系统数据文件和信息 ## 系统数据文件和信息
> 不同环境可能有区别以具体查询为准这里以Linux为例 > 不同环境可能有区别以具体查询为准这里以Linux为例
@@ -434,8 +427,6 @@ size_t strftime(char *s, size_t max, const char *format,
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
``` ```
## 进程环境 ## 进程环境
### `main`函数 ### `main`函数
@@ -444,8 +435,6 @@ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
int main(int argc, char *argv[]); int main(int argc, char *argv[]);
``` ```
### 进程的终止 ### 进程的终止
1. 正常终止: 1. 正常终止:
@@ -470,7 +459,6 @@ int main(int argc, char *argv[]);
- 接到一个信号并终止 - 接到一个信号并终止
- 最后一个线程对其取消请求作出响应 - 最后一个线程对其取消请求作出响应
```c ```c
/** /**
* 注册一个函数,当进程终止时调用 * 注册一个函数,当进程终止时调用
@@ -481,8 +469,6 @@ int main(int argc, char *argv[]);
int atexit(void (*function)(void));// 钩子函数 int atexit(void (*function)(void));// 钩子函数
``` ```
### 命令行参数的分析 ### 命令行参数的分析
```c ```c
@@ -498,8 +484,6 @@ int getopt_long(int argc, char *const argv[], const char *optstring,
const struct option *longopts, int *longindex); const struct option *longopts, int *longindex);
``` ```
### 环境变量 ### 环境变量
**KEY = VALVE** **KEY = VALVE**
@@ -525,14 +509,10 @@ int unsetenv(const char *name);
int putenv(char *string); int putenv(char *string);
``` ```
### C程序的存储空间布局 ### C程序的存储空间布局
`pmap`命令,查看进程空间布局 `pmap`命令,查看进程空间布局
### 库 ### 库
- 动态库 - 动态库
@@ -549,8 +529,6 @@ int putenv(char *string);
// Link with -ldl // Link with -ldl
``` ```
### 函数之间正常的跳转 ### 函数之间正常的跳转
`goto`无法跨函数跳转。 `goto`无法跨函数跳转。
@@ -573,8 +551,6 @@ int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val); void longjmp(jmp_buf env, int val);
``` ```
### 资源的获取及控制 ### 资源的获取及控制
`ulimit -a` `ulimit -a`
@@ -591,4 +567,3 @@ struct rlimit {
rlim_t rlim_max; /* hard limit */ rlim_t rlim_max; /* hard limit */
}; };
``` ```

View File

@@ -1,4 +1,5 @@
# 目录 # 目录
- [目录](#目录) - [目录](#目录)
- [进程基本知识](#进程基本知识) - [进程基本知识](#进程基本知识)
- [进程标识符`pid`](#进程标识符pid) - [进程标识符`pid`](#进程标识符pid)
@@ -13,7 +14,6 @@
- [守护进程](#守护进程) - [守护进程](#守护进程)
- [系统日志](#系统日志) - [系统日志](#系统日志)
# 进程基本知识 # 进程基本知识
已经进入**多进程**阶段 已经进入**多进程**阶段
@@ -36,8 +36,6 @@ pid_t getpid(void);
pid_t getppid(void); pid_t getppid(void);
``` ```
## 进程的产生 ## 进程的产生
`pid_t fork();` `pid_t fork();`
@@ -68,8 +66,6 @@ pid_t getppid(void);
pid_t vfork(void); pid_t vfork(void);
``` ```
## 进程的消亡及释放资源 ## 进程的消亡及释放资源
```c ```c
@@ -90,8 +86,6 @@ wait4();
池类算法: 池类算法:
上游往池子里放任务,下游三个线程从池子里取任务。 上游往池子里放任务,下游三个线程从池子里取任务。
## `exec`函数族 ## `exec`函数族
eg. `bash`进程创建`primer`进程 eg. `bash`进程创建`primer`进程
@@ -172,8 +166,6 @@ int setregid(gid_t rgid, gid_t egid);
``` ```
## 观摩课:解释器文件 ## 观摩课:解释器文件
> unix讲究机制而非策略 > unix讲究机制而非策略
@@ -188,8 +180,6 @@ int setregid(gid_t rgid, gid_t egid);
`#!`是一种约定俗成的标记,告诉系统这个脚本应该用什么解释器来执行。 `#!`是一种约定俗成的标记,告诉系统这个脚本应该用什么解释器来执行。
## `system()`函数 ## `system()`函数
```c ```c
@@ -202,8 +192,6 @@ int system(const char *command);
相当于`fork+exec+wait`的封装 相当于`fork+exec+wait`的封装
## 进程会计 ## 进程会计
```c ```c
@@ -211,8 +199,6 @@ int system(const char *command);
int acct(const char *filename); int acct(const char *filename);
``` ```
## 进程时间 ## 进程时间
```c ```c
@@ -229,8 +215,6 @@ struct tms{
``` ```
## 守护进程 ## 守护进程
1. 守护进程`PPID`为1 1. 守护进程`PPID`为1
@@ -254,13 +238,10 @@ pid_t getpgrp(psid_t pid); //! 方言
- 终端: - 终端:
我们接触的都是虚拟终端 我们接触的都是虚拟终端
**单实例守护进程**:锁文件`/var/run/name.pid` **单实例守护进程**:锁文件`/var/run/name.pid`
启动脚本文件:`/etc/rc*...` 启动脚本文件:`/etc/rc*...`
## 系统日志 ## 系统日志
`syslogd`服务 `syslogd`服务

View File

@@ -299,3 +299,74 @@ struct timeval {
此外都和标准信号一样 此外都和标准信号一样
## 线程(强烈异步) ## 线程(强烈异步)
### 线程的概念
会话-->进程-->线程
一个正在运行的函数。
`main`函数可以叫做main线程不应该说主线程线程之间平等。
`posix`线程是一套标准,而不是实现。
`openmp`线程。
例如,线程标识: `pthread_t`, 具体类型怎么实现是不知道的
在linux环境可以通过`ps axm`或者`ps -ax -L`查看线程信息。
发现线程消耗了进程号。
```c
#include <pthread.h>
//* Compile and link with -pthread
/**
* 比较两个pthread_t是否相等
* @param: t1: pthread_t
* @param: t2: pthread_t
*
* @return: 相等返回非0不相等返回0
*/
int pthread_equal(pthread_t t1, pthread_t t2);
/**
* 获取当前线程的pthread_t
* @return: 当前线程的pthread_t
*/
pthread_t pthread_self(void);
```
### 线程的操作
创建,终止,取消,栈的清理
线程的调度取决于调度器策略。
```c
#include <pthread.h>
// Compile and link with -pthread
/**
* 创建线程
* @param: thread: 线程ID指针
* @param: attr: 线程属性指针
* NULL: 默认属性
* @param: start_routine: 线程函数指针
* void *(*)(void *)
* @param: arg: 线程函数参数
*
* @return: 成功返回0失败返回errCode
* 建议使用strerror而非perror
*/
int pthread_create(pthread_t * thread,
const pthread_attr_t *attr,
void *(*start_routine)(void *),
void *arg);
```
### 线程的同步
### 线程属性,线程同步的属性
### 重入,线程与信号,线程与`fork`