From ad3056a8b8b7c0c540a923bb114938d4d2e54053 Mon Sep 17 00:00:00 2001 From: lzy Date: Mon, 18 Mar 2024 14:31:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=EF=BC=8C=E5=B9=B6=E4=B8=94=E5=86=99=E4=BA=86?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E7=AC=AC=E4=B8=89=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chapter1/C1-绪论.md | 32 ++++++++- Chapter2/C2-数据类型,运算符和表达式.md | 96 ++++++++++++------------- Chapter3/C3-输入输出专题.md | 32 +++++++++ Chapter3/IO/printf.c | 49 +++++++++++++ 4 files changed, 160 insertions(+), 49 deletions(-) create mode 100644 Chapter3/C3-输入输出专题.md create mode 100644 Chapter3/IO/printf.c diff --git a/Chapter1/C1-绪论.md b/Chapter1/C1-绪论.md index d5f5e12..9b91454 100644 --- a/Chapter1/C1-绪论.md +++ b/Chapter1/C1-绪论.md @@ -1,3 +1,33 @@ +# 目录 +- [目录](#目录) +- [第一章 绪论](#第一章-绪论) + - [第一节](#第一节) + - [C语言发展史](#c语言发展史) + - [C语言特点](#c语言特点) + - [C语言学习建议](#c语言学习建议) + - [课程思路](#课程思路) + - [课程平台](#课程平台) + - [第二节](#第二节) + - [神一般的`Hello world!`](#神一般的hello-world) + - [源文件到可执行文件](#源文件到可执行文件) + - [gcc](#gcc) + - [make](#make) + - [vim](#vim) + - [第三节](#第三节) + - [基本概念](#基本概念) + - [以`Hello world`为例对写程序的思路提出如下要求](#以hello-world为例对写程序的思路提出如下要求) + - [1. 头文件正确包含的重要性](#1-头文件正确包含的重要性) + - [2. 以函数为单位来进行程序编写](#2-以函数为单位来进行程序编写) + - [3. 声明部分+实现部分](#3-声明部分实现部分) + - [4. `return 0/exit(0)`](#4-return-0exit0) + - [5. 多用空格空行](#5-多用空格空行) + - [6. 添加注释](#6-添加注释) + - [算法](#算法) + - [程序](#程序) + - [进程](#进程) + - [防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放](#防止写越界防止内存泄漏谁打开谁关闭谁申请谁释放) + + # 第一章 绪论 课程地址,[史上最强最细腻的linux嵌入式C语言学习教程【李慧芹老师】_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV18p4y167Md/?spm_id_from=333.999.0.0&vd_source=4e03f52e94cfa281cde032856b1f93a7)。 @@ -55,7 +85,7 @@ ### 课程平台 * 老师:64位的`redhat6`,`vim`,`gcc4.4.6(make)` -* 本人:`WSL-Ubuntu22.04`,`vscode(remote ssh)`,`gcc11.4.0(make)`,`ohmyzsh(theme:eastwood)` +* 本人:`WSL-debian`,`vscode(remote ssh)`,`gcc12.2.0(make)`,`ohmyzsh(theme:eastwood)` 我的`gcc`版本比较新,所以很多提示比较完善,老师这个课程是很早的课,那个时候的gcc提示没有现在厉害,所以还是要结合老师的视频的思路,在当时提示不完善的时候是如何手撕代码分析出来的。 diff --git a/Chapter2/C2-数据类型,运算符和表达式.md b/Chapter2/C2-数据类型,运算符和表达式.md index 8475012..a01b4b9 100644 --- a/Chapter2/C2-数据类型,运算符和表达式.md +++ b/Chapter2/C2-数据类型,运算符和表达式.md @@ -1,3 +1,18 @@ +# 目录 +- [目录](#目录) +- [第二章 数据类型,运算符和表达式](#第二章-数据类型运算符和表达式) + - [数据类型(基本数据类型)](#数据类型基本数据类型) + - [常量与变量](#常量与变量) + - [常量](#常量) + - [定义](#定义) + - [分类](#分类) + - [变量](#变量) + - [定义](#定义-1) + - [变量的生命周期与作用范围](#变量的生命周期与作用范围) + - [运算符和表达式](#运算符和表达式) + - [表达式和语句的区别](#表达式和语句的区别) + - [运算符相关代码](#运算符相关代码) + # 第二章 数据类型,运算符和表达式 ## 数据类型(基本数据类型) @@ -39,8 +54,6 @@ 5. 数据类型得与后续代码的输入输入相匹配(自相矛盾) - - ## 常量与变量 ### 常量 @@ -51,14 +64,14 @@ #### 分类 -* 整型常量:1,790,76 +- 整型常量:1,790,76 -* 实型常量:3.14,5.26 -* 字符常量:由单引号引起来的单个字符或转义字符,如`'a'`,`'X'`,`'\n'`,`'\ddd'`(d可以是`0-7`,三位八进制,例如`'\015'`),`'\xhh'`(h可以是`0-F`,二位十六进制,`'\x7f'`) -* 字符串常量:由双引号引起来的一个或多个字符组成的序列(特殊情况,空串),如:`""`,`"a"`,`"abXYZ"`,`"abc\n\021\018"`(注意这个字符串,`\n`,`\021`都是算单个字符,`\018`又不算) +- 实型常量:3.14,5.26 +- 字符常量:由单引号引起来的单个字符或转义字符,如`'a'`,`'X'`,`'\n'`,`'\ddd'`(d可以是`0-7`,三位八进制,例如`'\015'`),`'\xhh'`(h可以是`0-F`,二位十六进制,`'\x7f'`) +- 字符串常量:由双引号引起来的一个或多个字符组成的序列(特殊情况,空串),如:`""`,`"a"`,`"abXYZ"`,`"abc\n\021\018"`(注意这个字符串,`\n`,`\021`都是算单个字符,`\018`又不算) > 我问gpt,"\018"在C语言几个字符。 -> 在C语言中,字符串是以字符数组的形式表示,而每个字符串的末尾都有一个特殊的字符`'\0'`(空字符),用于标识字符串的结束。当你提到的`"\018"`在C语言中出现时,它表示一个包含特殊字符的字符串字面量。 +> 在C语言中,字符串是以字符数组的形式表示,而每个字符串的末尾都有一个特殊的字符`'\0'`(空字符),用于标识字符串的结束。当你提到的`"\018"`在C语言中出现时,它表示一个包含特殊字符的字符串字面量。 > > 具体来说,`\0`在C语言中是一个转义字符,用于表示字符串的结束符(null terminator)。该符号用于标记字符串的结束,确保字符串处理函数如`printf`、`strcpy`等知道在哪里停止处理。 > @@ -66,21 +79,21 @@ > > 总结来说,在C语言中`"\018"`实际上会被看作一个包含单一结束字符(null terminator)的字符串,而不是包含多个字符。这种处理方式是因为C语言使用空字符来标记字符串的结束。 -* 标识常量:`#define` +- 标识常量:`#define` 特点:完整的用宏体替换宏名,**不做任何检查**。 ```c #include #include - + #define PI 3.14 #define ADD 2 + 3 #define ADD1 (2 + 3) - + #define MAX(a, b) (a > b ? a : b) #define MAX1(a, b) ((a) > (b) ? (a) : (b)) - + int main() { // printf("%d\n", ADD * ADD); @@ -89,14 +102,14 @@ // printf("%d\n", ADD1 * ADD1); // 相当于(2+3)*(2+3) // 正常输出25 - + int i = 5, j = 3; // printf("%d\n", MAX(i, j)); // 输出5 - + // printf("%d\n", MAX(i, j * 2)); // 输出6 - + printf("i=%d\tj=%d\n", i, j); printf("%d\n", MAX1(i++, j++)); printf("i=%d\tj=%d\n", i, j); @@ -107,7 +120,7 @@ // 为什么i自增了两次? // 预处理结果 // printf("%d\n", ((i++) + (j++) ? (i++) : (j++))); - + exit(0); } ``` @@ -123,41 +136,33 @@ int A = a, B = b; \ ((A) > (B) ? (A) : (B)); \ }) - + #define MAX3(a, b) \ ({ \ typeof(a) A = a, B = b; \ ((A) > (B) ? (A) : (B)); \ }) - + ``` - - - - - - ### 变量 用来保存一些特定内容,并且在程序执行过程中值**随时会发生变化**的量。 #### 定义 -| [存储类型] | 数据类型 | 标识符 | = | 值 | -| :--------: | :------: | :----: | :--: | :---: | -| | TYPE | NAME | = | VALUE | - -* 标识符:由字母,数字,下划线组成且不能以数字开头的一个标识序列。拟定时尽量做到见名知义。 -* 数据类型:基本数据类型、构造类型 -* 值:注意匹配 -* 存储类型:`auto`,`static`,`register`,`extern`(说明型) - * `auto`:默认,自动分配空间,自动回收空间。 - * `register`:(建议型,编译器不一定采用)寄存器类型,只能定义局部变量,不能定义全局变量;大小有定义,只能定义32位大小的数据类型,如`double`就不可以;集尘器没有地址,所以一个寄存器类型的变量无法打印出地址查看或使用。 - * `static`:静态型,自动初始化为0值或空值,并且变量的值有继承性。另外,常用来修饰一个变量和函数,防止其对外扩散。 - * `extern`:说明型,意味着不能改变被说明的变量的值或类型。 - +| [存储类型] | 数据类型 | 标识符 | = | 值 | +| :--------: | :------: | :----: | :-: | :---: | +| | TYPE | NAME | = | VALUE | +- 标识符:由字母,数字,下划线组成且不能以数字开头的一个标识序列。拟定时尽量做到见名知义。 +- 数据类型:基本数据类型、构造类型 +- 值:注意匹配 +- 存储类型:`auto`,`static`,`register`,`extern`(说明型) + - `auto`:默认,自动分配空间,自动回收空间。 + - `register`:(建议型,编译器不一定采用)寄存器类型,只能定义局部变量,不能定义全局变量;大小有定义,只能定义32位大小的数据类型,如`double`就不可以;集尘器没有地址,所以一个寄存器类型的变量无法打印出地址查看或使用。 + - `static`:静态型,自动初始化为0值或空值,并且变量的值有继承性。另外,常用来修饰一个变量和函数,防止其对外扩散。 + - `extern`:说明型,意味着不能改变被说明的变量的值或类型。 ```c #include @@ -272,8 +277,6 @@ int main() } ``` - - #### 变量的生命周期与作用范围 1. 全局变量和局部变量 @@ -282,7 +285,7 @@ int main() ![存储类型比较](https://s2.loli.net/2024/03/12/y8pMEXS3LBIDAuc.png) -> 这一块具体讲解见代码仓库`/Chapter2/变量/`。 +> 这一块具体讲解见代码仓库`/Chapter2/变量/`。 在`minproj`例子中,如果在`proj.c`和`proj.h`中`static`定义`func`函数,而在`main.c`中调用`func`。 @@ -297,27 +300,25 @@ main.c:(.text+0x2f): undefined reference to `func' collect2: error: ld returned 1 exit status ``` - - ### 运算符和表达式 #### 表达式和语句的区别 -* 运算符部分 +- 运算符部分 ![运算符](https://s2.loli.net/2024/03/12/3MkPpF5anv7eEGu.png) - * 每个运算符所需要的参与运算的操作数个数 + - 每个运算符所需要的参与运算的操作数个数 - * 结合性 + - 结合性 - * 优先级 + - 优先级 - * 运算符的特殊用法 + - 运算符的特殊用法 如:`%`(要求左右两边都是整形),`=`与`==`,逻辑运算(`&&`和`||`)的短路特性 - * 位运算的重要性 + - 位运算的重要性 `<< >> ~ | ^ &` @@ -445,4 +446,3 @@ int main() #endif ``` - diff --git a/Chapter3/C3-输入输出专题.md b/Chapter3/C3-输入输出专题.md new file mode 100644 index 0000000..1e8d6db --- /dev/null +++ b/Chapter3/C3-输入输出专题.md @@ -0,0 +1,32 @@ +# 目录 +- [目录](#目录) +- [第三章 输入输出专题](#第三章-输入输出专题) + - [内容](#内容) + - [格式化输入输出函数](#格式化输入输出函数) + +# 第三章 输入输出专题 + +input & output -> I/O(标准IO,文件IO) + + + +## 内容 + +1. 格式化输入输出函数:`scanf`,`printf` +2. 字符输入输出函数:`getchar`,`putchar` +3. 字符串输入输出函数:`gets(!)`,`puts` + + + +## 格式化输入输出函数 + +![标准输出格式字符](https://s2.loli.net/2024/03/18/OMiu6CUDZy5RH3P.png) + +![标准输出修饰符](https://s2.loli.net/2024/03/18/Z6gVaw1AOJ87Uil.png) + +```c +int printf(const char *format, ...); +format: "%【修饰符】格式字符",参照图片标准输出修饰符和格式字符 + +``` + diff --git a/Chapter3/IO/printf.c b/Chapter3/IO/printf.c new file mode 100644 index 0000000..6418308 --- /dev/null +++ b/Chapter3/IO/printf.c @@ -0,0 +1,49 @@ +#include +#include + +/*** + * printf("%[修饰符]格式字符", 输出表项); + * + */ + +#define STRSIZE 10 + +int main() +{ + // printf("hello world\n"); + + // char ch = 65; + // printf("%c\n", ch); + // out: A + + int i = 255; + float f = 123.45678; + char str[STRSIZE] = "helloworld"; + double dou = 123.456; + long long l = 123456; + + // printf("f = %8.1f\n", f); + // out:f = 123.5 + // printf("i = %2d\n", i); + // out: i = 123 + + // printf("%-10.5s[over]\n", str); + // printf("%+10.5s[over]\n", str); + // out: + // hello [over] + // hello[over] + + // 同样对于i进行八进制核对十六进制的输出 + // printf("i = %#o\n", i); + // out: i = 0377 + // printf("i = %#x\n", i); + // out: i = 0xff + + // printf("dou = %lf\n", dou); + // printf("l = %ld\n", l); + // out: + // dou = 123.456000 + // l = 123456 + + exit(0); +} \ No newline at end of file