From 308c9753bb4d20cd2b5f5e3f6654b196bdad367b Mon Sep 17 00:00:00 2001 From: lzy Date: Tue, 19 Mar 2024 17:46:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E7=AB=A0=E7=AC=AC=E4=B8=80=E5=B0=8F=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chapter1/C1-绪论.md | 5 + Chapter2/C2-数据类型,运算符和表达式.md | 22 +- Chapter3/C3-输入输出专题.md | 283 +++++++++++++++++++++++- Chapter3/IO/printf.c | 43 +++- Chapter3/IO/scanf.c | 83 +++++++ 5 files changed, 421 insertions(+), 15 deletions(-) create mode 100644 Chapter3/IO/scanf.c diff --git a/Chapter1/C1-绪论.md b/Chapter1/C1-绪论.md index 9b91454..9a40ad0 100644 --- a/Chapter1/C1-绪论.md +++ b/Chapter1/C1-绪论.md @@ -28,6 +28,11 @@ - [防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放](#防止写越界防止内存泄漏谁打开谁关闭谁申请谁释放) + + + + + # 第一章 绪论 课程地址,[史上最强最细腻的linux嵌入式C语言学习教程【李慧芹老师】_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV18p4y167Md/?spm_id_from=333.999.0.0&vd_source=4e03f52e94cfa281cde032856b1f93a7)。 diff --git a/Chapter2/C2-数据类型,运算符和表达式.md b/Chapter2/C2-数据类型,运算符和表达式.md index a01b4b9..e3d41e3 100644 --- a/Chapter2/C2-数据类型,运算符和表达式.md +++ b/Chapter2/C2-数据类型,运算符和表达式.md @@ -13,6 +13,10 @@ - [表达式和语句的区别](#表达式和语句的区别) - [运算符相关代码](#运算符相关代码) + + + + # 第二章 数据类型,运算符和表达式 ## 数据类型(基本数据类型) @@ -86,14 +90,14 @@ ```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); @@ -102,14 +106,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); @@ -120,7 +124,7 @@ // 为什么i自增了两次? // 预处理结果 // printf("%d\n", ((i++) + (j++) ? (i++) : (j++))); - + exit(0); } ``` @@ -136,13 +140,13 @@ int A = a, B = b; \ ((A) > (B) ? (A) : (B)); \ }) - + #define MAX3(a, b) \ ({ \ typeof(a) A = a, B = b; \ ((A) > (B) ? (A) : (B)); \ }) - + ``` ### 变量 diff --git a/Chapter3/C3-输入输出专题.md b/Chapter3/C3-输入输出专题.md index 1e8d6db..bf850d2 100644 --- a/Chapter3/C3-输入输出专题.md +++ b/Chapter3/C3-输入输出专题.md @@ -3,6 +3,14 @@ - [第三章 输入输出专题](#第三章-输入输出专题) - [内容](#内容) - [格式化输入输出函数](#格式化输入输出函数) + - [`printf`](#printf) + - [`scanf`](#scanf) + - [字符输入输出函数](#字符输入输出函数) + + + + + # 第三章 输入输出专题 @@ -12,9 +20,9 @@ input & output -> I/O(标准IO,文件IO) ## 内容 -1. 格式化输入输出函数:`scanf`,`printf` -2. 字符输入输出函数:`getchar`,`putchar` -3. 字符串输入输出函数:`gets(!)`,`puts` +1. 格式化输入输出函数:`scanf`, `printf` +2. 字符输入输出函数:`getchar`, `putchar` +3. 字符串输入输出函数:`gets(!)`,`puts` @@ -24,9 +32,276 @@ input & output -> I/O(标准IO,文件IO) ![标准输出修饰符](https://s2.loli.net/2024/03/18/Z6gVaw1AOJ87Uil.png) +### `printf` + ```c int printf(const char *format, ...); format: "%【修饰符】格式字符",参照图片标准输出修饰符和格式字符 - ``` + + +- 有关`l`修饰符的提醒 + +```C +int main() +{ + FILE *fp; + long a = 11; + + fp = fopen(); + + // 可行,a定义了long型,与函数要求一致 + func(fp, a); + + // 早期的编译器不认可,这个12没有单位,不同编译器默认类型不同 + // 需要加上L修饰符 + func(fp, 12); + func(fp, 12L); + // 对于func(FILE *fp, long long i) + func(fp, 12LL); +} +``` + + + +传输一个5G的文件 + +```c +5LL*1204LL*1204LL*1204LL +``` + + + +定义一个宏,表示一年有多少秒 + +```c +// 定义一年有多少秒 +#define SEC_YEAR (60LL * 60LL * 24LL * 365LL) +``` + + + +- 函数 变参与定参重载的区别 + + - 变参:编译器只报警告,函数自己都不知道自己有多少个参数 + + - 定参重载:编译报错 + + + +- `\n`的作用 + +强制刷新缓冲区,以死循环调试举例。 + +```c +// 不加\n,before while()存入了缓冲区,故不输出 +// printf("[%s:%d]before while().", __FUNCTION__, __LINE__); +printf("[%s:%d]before while().\n", __FUNCTION__, __LINE__); +while (1) +{ +} +// printf("[%s:%d]after while().", __FUNCTION__, __LINE__); +printf("[%s:%d]after while().\n", __FUNCTION__, __LINE__); +``` + + + +- 完整代码 + +```c +#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; + // 不加\n,before while()存入了缓冲区,故不输出 + // printf("[%s:%d]before while().", __FUNCTION__, __LINE__); + printf("[%s:%d]before while().\n", __FUNCTION__, __LINE__); + while (1) + { + } + // printf("[%s:%d]after while().", __FUNCTION__, __LINE__); + printf("[%s:%d]after while().\n", __FUNCTION__, __LINE__); + // 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 + + // printf("hello world!\n"); + // 实参过多或者过少都会警告 + // printf("#d #e\n", i); + // printf("#d #e\n", i, f, l); + + exit(0); +} + +#if 0 +func(FILE *fp, long i) +{ +} + +int main() +{ + FILE *fp; + long a = 11; + + fp = fopen(); + + // 可行,a定义了long型,与函数要求一致 + func(fp, a); + + // 早期的编译器不认可,这个12没有单位,不同编译器默认类型不同 + // 需要加上L修饰符 + func(fp, 12); + func(fp, 12L); + // 对于func(FILE *fp, long long i) + func(fp, 12LL); +} +#endif + +// 定义一年有多少秒 +#define SEC_YEAR (60LL * 60LL * 24LL * 365LL) +``` + + + +### `scanf` + +```c +int scanf(const char *format, 地址表); +format:抑制符* +``` + + + +- 完整代码 + +```c +#include +#include + +/** + * int scanf(const char *format, 地址表); + */ + +// #define STRSIZE 32 +#define STRSIZE 3 +// 除掉尾0占一个 +// 相当于只能两个字符 +// 但是这时候运行输入hello,不会报错 +// 实际上是越界了 + +int main() +{ + int i; + float f; + char str[STRSIZE]; + int ret; + char ch; + + printf("Please enter:\n"); + + // scanf("%d", &i); + // ch = getchar(); + + // printf("i = %d, ch = %c\n", i, ch); + /* + out: + Please enter: + 4 h + i = 4, ch = + ch被吞掉了 + */ + + // scanf("%d", &i); + // scanf("%*c%c", &ch); + // 用 '%*c' 吃掉回车 + /* + out: + Please enter: + 5 + h + i = 5, ch = h + */ + + printf("i = %d, ch = %c\n", i, ch); + +#if 0 + // 输入a直接卡死,scanf直接放在循环中很危险 + // 需要加入校验,用ret接收scanf返回值 + while (1) + { + // scanf("%d", &i); + + ret = scanf("%d", &i); + if (ret != 1) + { + printf("Enter Error!\n"); + break; + } + + printf("i = %d\n", i); + } +#endif + + // printf("Please enter fot str:\n"); + // 这种情况下,不能有任何间隔符 + // 输入hello world,只会得到hello + // 对于scanf,不建议'%s' + // scanf("%s", str); + // printf("%s\n", str); + + // printf("Please enter for i[int]:\n"); + // 这里两个数字之间有',',输入就一定要有',' + // 最好不加,空格符可以是空格 回车 tab + // scanf("%d,%f", &i, &f); + // printf("i = %d\n", i); + // printf("f = %f\n", f); + + exit(0); +} +``` + + + +## 字符输入输出函数 + +S + diff --git a/Chapter3/IO/printf.c b/Chapter3/IO/printf.c index 6418308..31ea884 100644 --- a/Chapter3/IO/printf.c +++ b/Chapter3/IO/printf.c @@ -21,7 +21,14 @@ int main() char str[STRSIZE] = "helloworld"; double dou = 123.456; long long l = 123456; - + // 不加\n,before while()存入了缓冲区,故不输出 + // printf("[%s:%d]before while().", __FUNCTION__, __LINE__); + printf("[%s:%d]before while().\n", __FUNCTION__, __LINE__); + while (1) + { + } + // printf("[%s:%d]after while().", __FUNCTION__, __LINE__); + printf("[%s:%d]after while().\n", __FUNCTION__, __LINE__); // printf("f = %8.1f\n", f); // out:f = 123.5 // printf("i = %2d\n", i); @@ -45,5 +52,37 @@ int main() // dou = 123.456000 // l = 123456 + // printf("hello world!\n"); + // 实参过多或者过少都会警告 + // printf("#d #e\n", i); + // printf("#d #e\n", i, f, l); + exit(0); -} \ No newline at end of file +} + +#if 0 +func(FILE *fp, long i) +{ +} + +int main() +{ + FILE *fp; + long a = 11; + + fp = fopen(); + + // 可行,a定义了long型,与函数要求一致 + func(fp, a); + + // 早期的编译器不认可,这个12没有单位,不同编译器默认类型不同 + // 需要加上L修饰符 + func(fp, 12); + func(fp, 12L); + // 对于func(FILE *fp, long long i) + func(fp, 12LL); +} +#endif + +// 定义一年有多少秒 +#define SEC_YEAR (60LL * 60LL * 24LL * 365LL) \ No newline at end of file diff --git a/Chapter3/IO/scanf.c b/Chapter3/IO/scanf.c new file mode 100644 index 0000000..15d212f --- /dev/null +++ b/Chapter3/IO/scanf.c @@ -0,0 +1,83 @@ +#include +#include + +/** + * int scanf(const char *format, 地址表); + */ + +// #define STRSIZE 32 +#define STRSIZE 3 +// 除掉尾0占一个 +// 相当于只能两个字符 +// 但是这时候运行输入hello,不会报错 +// 实际上是越界了 + +int main() +{ + int i; + float f; + char str[STRSIZE]; + int ret; + char ch; + + printf("Please enter:\n"); + + // scanf("%d", &i); + // ch = getchar(); + + // printf("i = %d, ch = %c\n", i, ch); + /* + out: + Please enter: + 4 h + i = 4, ch = + ch被吞掉了 + */ + + // scanf("%d", &i); + // scanf("%*c%c", &ch); + // 用 '%*c' 吃掉回车 + /* + out: + Please enter: + 5 + h + i = 5, ch = h + */ + + printf("i = %d, ch = %c\n", i, ch); + +#if 0 + // 输入a直接卡死,scanf直接放在循环中很危险 + // 需要加入校验,用ret接收scanf返回值 + while (1) + { + // scanf("%d", &i); + + ret = scanf("%d", &i); + if (ret != 1) + { + printf("Enter Error!\n"); + break; + } + + printf("i = %d\n", i); + } +#endif + + // printf("Please enter fot str:\n"); + // 这种情况下,不能有任何间隔符 + // 输入hello world,只会得到hello + // 对于scanf,不建议'%s' + // scanf("%s", str); + // printf("%s\n", str); + + // printf("Please enter for i[int]:\n"); + // 这里两个数字之间有',',输入就一定要有',' + // 最好不加,空格符可以是空格 回车 tab + // scanf("%d,%f", &i, &f); + // printf("i = %d\n", i); + // printf("f = %f\n", f); + + exit(0); +} \ No newline at end of file