新增了文档目录,并且写了一点第三节
This commit is contained in:
@@ -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提示没有现在厉害,所以还是要结合老师的视频的思路,在当时提示不完善的时候是如何手撕代码分析出来的。
|
||||
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#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 <stdio.h>
|
||||
@@ -272,8 +277,6 @@ int main()
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 变量的生命周期与作用范围
|
||||
|
||||
1. 全局变量和局部变量
|
||||
@@ -282,7 +285,7 @@ int main()
|
||||
|
||||

|
||||
|
||||
> 这一块具体讲解见代码仓库`/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
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 运算符和表达式
|
||||
|
||||
#### 表达式和语句的区别
|
||||
|
||||
* 运算符部分
|
||||
- 运算符部分
|
||||
|
||||

|
||||
|
||||
* 每个运算符所需要的参与运算的操作数个数
|
||||
- 每个运算符所需要的参与运算的操作数个数
|
||||
|
||||
* 结合性
|
||||
- 结合性
|
||||
|
||||
* 优先级
|
||||
- 优先级
|
||||
|
||||
* 运算符的特殊用法
|
||||
- 运算符的特殊用法
|
||||
|
||||
如:`%`(要求左右两边都是整形),`=`与`==`,逻辑运算(`&&`和`||`)的短路特性
|
||||
|
||||
* 位运算的重要性
|
||||
- 位运算的重要性
|
||||
|
||||
`<< >> ~ | ^ &`
|
||||
|
||||
@@ -445,4 +446,3 @@ int main()
|
||||
#endif
|
||||
|
||||
```
|
||||
|
||||
|
||||
32
Chapter3/C3-输入输出专题.md
Normal file
32
Chapter3/C3-输入输出专题.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# 目录
|
||||
- [目录](#目录)
|
||||
- [第三章 输入输出专题](#第三章-输入输出专题)
|
||||
- [内容](#内容)
|
||||
- [格式化输入输出函数](#格式化输入输出函数)
|
||||
|
||||
# 第三章 输入输出专题
|
||||
|
||||
input & output -> I/O(标准IO,文件IO)
|
||||
|
||||
|
||||
|
||||
## 内容
|
||||
|
||||
1. 格式化输入输出函数:`scanf`,`printf`
|
||||
2. 字符输入输出函数:`getchar`,`putchar`
|
||||
3. 字符串输入输出函数:`gets(!)`,`puts`
|
||||
|
||||
|
||||
|
||||
## 格式化输入输出函数
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
```c
|
||||
int printf(const char *format, ...);
|
||||
format: "%【修饰符】格式字符",参照图片标准输出修饰符和格式字符
|
||||
|
||||
```
|
||||
|
||||
49
Chapter3/IO/printf.c
Normal file
49
Chapter3/IO/printf.c
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/***
|
||||
* 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);
|
||||
}
|
||||
Reference in New Issue
Block a user