合并了笔记内容
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@
|
||||
# 允许跟踪所有的.c和.h文件
|
||||
!**/*.c
|
||||
!**/*.h
|
||||
!**/*.md
|
||||
303
Chapter1/C1-绪论.md
Normal file
303
Chapter1/C1-绪论.md
Normal file
@@ -0,0 +1,303 @@
|
||||
# 第一章 绪论
|
||||
|
||||
课程地址,[史上最强最细腻的linux嵌入式C语言学习教程【李慧芹老师】_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV18p4y167Md/?spm_id_from=333.999.0.0&vd_source=4e03f52e94cfa281cde032856b1f93a7)。
|
||||
|
||||
## 第一节
|
||||
|
||||
### C语言发展史
|
||||
|
||||
| 时间 | 发展 |
|
||||
| ---- | -------------------- |
|
||||
| 1960 | 原型A语言->ALGOL语言 |
|
||||
| 1963 | CPL语言 |
|
||||
| 1967 | BCPL |
|
||||
| 1967 | B语言 |
|
||||
| 1973 | C语言 |
|
||||
|
||||
|
||||
|
||||
### C语言特点
|
||||
|
||||
1. 基础性语言
|
||||
2. 语法间接、紧凑、方便、灵活
|
||||
3. 运算符,数据结构丰富
|
||||
4. 结构化,模块化编程
|
||||
5. 移植性好,执行效率高
|
||||
6. 允许直接对硬件操作
|
||||
|
||||
|
||||
|
||||
### C语言学习建议
|
||||
|
||||
1. 概念的正确性
|
||||
2. 动手能力
|
||||
3. 阅读优秀的程序段
|
||||
4. 大量练习,面试题
|
||||
|
||||
|
||||
|
||||
### 课程思路
|
||||
|
||||
1. 基础概念
|
||||
2. 数据类型,运算符和表达式
|
||||
3. 输入输出专题
|
||||
4. 流程控制
|
||||
5. 数组
|
||||
6. 指针
|
||||
7. 函数
|
||||
8. 构造类型
|
||||
9. 动态内存管理
|
||||
10. 调试工具(gdb,make)
|
||||
11. 常用库函数
|
||||
|
||||
|
||||
|
||||
### 课程平台
|
||||
|
||||
* 老师:64位的`redhat6`,`vim`,`gcc4.4.6(make)`
|
||||
* 本人:`WSL-Ubuntu22.04`,`vscode(remote ssh)`,`gcc11.4.0(make)`,`ohmyzsh(theme:eastwood)`
|
||||
|
||||
我的`gcc`版本比较新,所以很多提示比较完善,老师这个课程是很早的课,那个时候的gcc提示没有现在厉害,所以还是要结合老师的视频的思路,在当时提示不完善的时候是如何手撕代码分析出来的。
|
||||
|
||||
|
||||
|
||||
## 第二节
|
||||
|
||||
### 神一般的`Hello world!`
|
||||
|
||||
```c
|
||||
//hello.c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if 0
|
||||
void main(void);
|
||||
void main(int argc, char **argv);// char *argv[]
|
||||
int main(int argc, char **argv);
|
||||
int main(void);
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello world!\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
用那种`main`得看编译器环境,目前在`linux`的`gcc`下,`int main(void);`常用,需要传参用`int main(int argc, char **argv);`。
|
||||
|
||||
|
||||
|
||||
### 源文件到可执行文件
|
||||
|
||||
#### gcc
|
||||
|
||||
C源文件=>预处理=>编译=>汇编=>链接=>可执行文件
|
||||
|
||||
> 所有`#`后面的代码都在预处理解决
|
||||
|
||||
```bash
|
||||
# 单步执行
|
||||
gcc -E hello.c > hello.i # 预处理生成hello.i
|
||||
gcc -S hello.i # 编译生成hello.s
|
||||
gcc -c hello.s # 汇编生成hello.o
|
||||
gcc hello.o -o hello # 链接生成hello
|
||||
./hello # 运行
|
||||
Hello world!
|
||||
|
||||
# 一次到位
|
||||
gcc hello.c # 得到a.out可执行文件
|
||||
# 指定名字
|
||||
gcc hello.c -o myhello # 得到myhello可执行文件
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### make
|
||||
|
||||
```bash
|
||||
$ make hello
|
||||
cc hello.c -o hello
|
||||
# cc就是make选择的编译器,这里是gcc
|
||||
$ ls
|
||||
hello hello.c
|
||||
```
|
||||
|
||||
|
||||
|
||||
### vim
|
||||
|
||||
老师对于常用的`.vimrc`做了一些介绍,笔者建议`vscode`的`remote-ssh`插件,可以在win的vscode编辑器享受linux的环境。
|
||||
|
||||
|
||||
|
||||
## 第三节
|
||||
|
||||
### 基本概念
|
||||
|
||||
#### 以`Hello world`为例对写程序的思路提出如下要求
|
||||
|
||||
##### 1. 头文件正确包含的重要性
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int *p = NULL;
|
||||
int i;
|
||||
p = malloc(sizeof(int));
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
printf("Hello world!\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
这里我的gcc版本比较新,所以和老师的不一致,总之老师的意思就是
|
||||
|
||||
> 不要忽略gcc的警告!!!
|
||||
|
||||
```bash
|
||||
# 通过 -Wall 参数让gcc显示全部警告
|
||||
# 注意'W'要大写
|
||||
$ gcc hello.c -Wall
|
||||
hello.c: In function ‘main’:
|
||||
hello.c:7:9: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
|
||||
7 | p = malloc(sizeof(int));
|
||||
| ^~~~~~
|
||||
hello.c:2:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’
|
||||
1 | #include <stdio.h>
|
||||
+++ |+#include <stdlib.h>
|
||||
2 |
|
||||
hello.c:7:9: warning: incompatible implicit declaration of built-in function ‘malloc’ [-Wbuiltin-declaration-mismatch]
|
||||
7 | p = malloc(sizeof(int));
|
||||
| ^~~~~~
|
||||
hello.c:7:9: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’
|
||||
hello.c:6:9: warning: unused variable ‘i’ [-Wunused-variable]
|
||||
6 | int i;
|
||||
| ^
|
||||
|
||||
```
|
||||
|
||||
* 例如说这个变量`i`定义了但是没用上,就是你清楚来龙去脉可以忽略的警告。
|
||||
* 而`malloc`那个警告就是在告诉你`malloc`所属的`stdlib.h`库未引入。
|
||||
* C语言程序往往如果能把警告都消除,错误也能解决。例如:
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen("tmp", "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
fprintf(stderr, "fopen():%s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
puts("ok!");
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
这个程序运行报段错误,这个时候,查看一下警告就是问题所在。
|
||||
|
||||
```bash
|
||||
$ ./a
|
||||
[1] 1960 segmentation fault ./a
|
||||
|
||||
$ gcc a.c -Wall
|
||||
a.c: In function ‘main’:
|
||||
a.c:12:41: warning: implicit declaration of function ‘strerror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
|
||||
12 | fprintf(stderr, "fopen():%s\n", strerror(errno));
|
||||
| ^~~~~~~~
|
||||
| perror
|
||||
a.c:12:35: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
|
||||
12 | fprintf(stderr, "fopen():%s\n", strerror(errno));
|
||||
| ~^ ~~~~~~~~~~~~~~~
|
||||
| | |
|
||||
| | int
|
||||
| char *
|
||||
| %d
|
||||
```
|
||||
|
||||
用`%s`需要的类型是`char *`,但是`strerror(errno)`的类型是`int`,它是所以是`int`,是因为C语言对没有找到原型的函数返回值都是`int`,所以根源在于`strerror`函数没有原型,没有引入需要的`string.h`库。加入这个库重新运行。
|
||||
|
||||
```bash
|
||||
[main][~/LinuxC/Chapter1/Section3]$ make a
|
||||
cc a.c -o a
|
||||
[main][~/LinuxC/Chapter1/Section3]$ ./a
|
||||
fopen():No such file or directory
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2. 以函数为单位来进行程序编写
|
||||
|
||||
main`是特殊的定义,其实就是一个正在运行的线程。其实对于内核而言,是只有进程的概念,且与我们理解的进程、线程不一样。
|
||||
|
||||
|
||||
|
||||
##### 3. 声明部分+实现部分
|
||||
|
||||
早期的编译器要求变量先定义后使用。
|
||||
|
||||
##### 4. `return 0/exit(0)`
|
||||
|
||||
结束当前进程,是给父进程看的。
|
||||
|
||||
对于带有`return 0`的程序:
|
||||
|
||||
```bash
|
||||
[main][~/LinuxC/Chapter1/Section3]$ ./hello
|
||||
Hello world!
|
||||
[main][~/LinuxC/Chapter1/Section3]$ echo $?
|
||||
0
|
||||
```
|
||||
|
||||
如果不带`return 0`:
|
||||
|
||||
老师演示的返回值是13,是`printf`的返回的`Hello world!\n`的长度。
|
||||
|
||||
在我本地无法复现,新版本可能改了。
|
||||
|
||||
##### 5. 多用空格空行
|
||||
|
||||
##### 6. 添加注释
|
||||
|
||||
```c
|
||||
//单行注释
|
||||
|
||||
/*
|
||||
* 多行注释
|
||||
* 多行注释
|
||||
* 多行注释
|
||||
*/
|
||||
|
||||
//大段的注释
|
||||
#if 0
|
||||
func(){
|
||||
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
#### 算法
|
||||
|
||||
解决问题的方法。(流程图,NS图,FSM有限状态机)
|
||||
|
||||
#### 程序
|
||||
|
||||
用某种语言实现算法
|
||||
|
||||
#### 进程
|
||||
|
||||
#### 防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放
|
||||
|
||||
|
||||
|
||||
448
Chapter2/C2-数据类型,运算符和表达式.md
Normal file
448
Chapter2/C2-数据类型,运算符和表达式.md
Normal file
@@ -0,0 +1,448 @@
|
||||
# 第二章 数据类型,运算符和表达式
|
||||
|
||||
## 数据类型(基本数据类型)
|
||||
|
||||
> 数据类型所占字节数随机器硬件不同而不同,以`int`为基准,`char`比它小,`float`和`double`比它大。
|
||||
|
||||
1. 所占字节数
|
||||
|
||||
2. 存储区别
|
||||
|
||||
3. 不同类型的数据间转换(隐式和**显式**=>强制类型转换)
|
||||
|
||||
4. 特殊性
|
||||
|
||||
1. 布尔型(`bool`):
|
||||
|
||||
`false`:`0`,`true`:非零值。
|
||||
|
||||
2. `float`类型,不够精确,其实是一个小范围。
|
||||
|
||||
```c
|
||||
int func(float f)
|
||||
{
|
||||
if (f < 0)
|
||||
return -1;
|
||||
// else if (f == 0)
|
||||
else if (fabs(f - 0) <= 1e-6)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
```
|
||||
|
||||
3. `char`型是否有符号,未定义
|
||||
|
||||
4. 不同形式的零值
|
||||
|
||||
`0`,`'0'`,`"0"`,`'\0'`,`NULL`
|
||||
|
||||
5. 数据类型得与后续代码的输入输入相匹配(自相矛盾)
|
||||
|
||||
|
||||
|
||||
## 常量与变量
|
||||
|
||||
### 常量
|
||||
|
||||
#### 定义
|
||||
|
||||
在程序执行过程中值不会发生变化的量。
|
||||
|
||||
#### 分类
|
||||
|
||||
* 整型常量: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`又不算)
|
||||
|
||||
> 我问gpt,"\018"在C语言几个字符。
|
||||
> 在C语言中,字符串是以字符数组的形式表示,而每个字符串的末尾都有一个特殊的字符`'\0'`(空字符),用于标识字符串的结束。当你提到的`"\018"`在C语言中出现时,它表示一个包含特殊字符的字符串字面量。
|
||||
>
|
||||
> 具体来说,`\0`在C语言中是一个转义字符,用于表示字符串的结束符(null terminator)。该符号用于标记字符串的结束,确保字符串处理函数如`printf`、`strcpy`等知道在哪里停止处理。
|
||||
>
|
||||
> 在`"\018"`中,`\0`表示字符串的结束,后面跟的`18`并不会作为字符串的一部分来处理。因此,如果你在C语言中使用`"\018"`,它实际上会被视为只包含一个空字符(`\0`)的字符串。这意味着,尽管看起来字符串中有更多的字符,但由于`\0`的存在,它实际上在C语言处理中表示一个空字符串。
|
||||
>
|
||||
> 总结来说,在C语言中`"\018"`实际上会被看作一个包含单一结束字符(null terminator)的字符串,而不是包含多个字符。这种处理方式是因为C语言使用空字符来标记字符串的结束。
|
||||
|
||||
* 标识常量:`#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);
|
||||
// 相当于 2+3*2+3
|
||||
// 故输出11而不是25
|
||||
// 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);
|
||||
// 输出:
|
||||
// i = 5 j = 3
|
||||
// 6
|
||||
// i = 7 j = 4
|
||||
// 为什么i自增了两次?
|
||||
// 预处理结果
|
||||
// printf("%d\n", ((i++) + (j++) ? (i++) : (j++)));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
解决办法:
|
||||
|
||||
1. 使用函数:函数与宏的区别在于,一个占用编译时间,一个占用运行时间。在`linux`内核中多用宏。
|
||||
2. 在宏中进行变量保存,这种写法超出标准C,属于`GNU C`的扩展部分,只能在支持的编译器(如`gcc`)中使用,在`linux`内核中非常常用。
|
||||
|
||||
```c
|
||||
#define MAX2(a, b) \
|
||||
({ \
|
||||
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`:说明型,意味着不能改变被说明的变量的值或类型。
|
||||
|
||||
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if 0
|
||||
void func(void)
|
||||
{
|
||||
int x = 0;
|
||||
x = x + 1;
|
||||
printf("%p->%d\n", &x, x);
|
||||
}
|
||||
|
||||
void func1(void)
|
||||
{
|
||||
static int x = 0;
|
||||
x = x + 1;
|
||||
printf("%p->%d\n", &x, x);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
// auto int i;
|
||||
// printf("i=%d\n", i);
|
||||
// out:i=21915,每次都不一样
|
||||
|
||||
// static int i;
|
||||
// printf("i=%d\n", i);
|
||||
// out:i=1
|
||||
|
||||
// func();
|
||||
// func();
|
||||
// func();
|
||||
// out::
|
||||
// 0x7ffc3c4ca4f4->1
|
||||
// 0x7ffc3c4ca4f4->1
|
||||
// 0x7ffc3c4ca4f4->1
|
||||
// 三次地址看着一样
|
||||
// 但是是每次函数开始取用,结束销毁的
|
||||
// 只是gcc刚好都取的栈上同一块地址
|
||||
|
||||
func1();
|
||||
func1();
|
||||
func1();
|
||||
// out::
|
||||
// 0x55fd83c96014->1
|
||||
// 0x55fd83c96014->2
|
||||
// 0x55fd83c96014->3
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int i = 100;
|
||||
|
||||
void func(int i)
|
||||
{
|
||||
printf("i=%d\n", i);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
int i = 3;
|
||||
|
||||
// printf("i=%d\n", i);
|
||||
// out:
|
||||
// i=3
|
||||
|
||||
// {
|
||||
// printf("i=%d\n", i);
|
||||
// }
|
||||
// out:
|
||||
// i=3
|
||||
|
||||
// {
|
||||
// i = 5;
|
||||
// printf("i=%d\n", i);
|
||||
// }
|
||||
// out:
|
||||
// i=5
|
||||
|
||||
// func(i);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
|
||||
void print_star(void)
|
||||
{
|
||||
for (i = 0; i < 5; i++)
|
||||
printf("*");
|
||||
printf("\n");
|
||||
printf("[%s]i=%d\n", __FUNCTION__, i);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
for (i = 0; i < 5; i++)
|
||||
print_star();
|
||||
printf("\n");
|
||||
|
||||
// out:
|
||||
// *****
|
||||
// [print_star] i = 5
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 变量的生命周期与作用范围
|
||||
|
||||
1. 全局变量和局部变量
|
||||
2. 局部变量和局部变量
|
||||
3. 参考图片存储类型比较
|
||||
|
||||

|
||||
|
||||
> 这一块具体讲解见代码仓库`/Chapter2/变量/`。
|
||||
|
||||
在`minproj`例子中,如果在`proj.c`和`proj.h`中`static`定义`func`函数,而在`main.c`中调用`func`。
|
||||
|
||||
```bash
|
||||
[main][~/LinuxC/Chapter2/Section5/minproj]$ gcc *.c
|
||||
In file included from main.c:4:
|
||||
proj.h:4:13: warning: ‘func’ used but never defined
|
||||
4 | static void func(void);
|
||||
| ^~~~
|
||||
/usr/bin/ld: /tmp/ccQ2317U.o: in function `main':
|
||||
main.c:(.text+0x2f): undefined reference to `func'
|
||||
collect2: error: ld returned 1 exit status
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 运算符和表达式
|
||||
|
||||
#### 表达式和语句的区别
|
||||
|
||||
* 运算符部分
|
||||
|
||||

|
||||
|
||||
* 每个运算符所需要的参与运算的操作数个数
|
||||
|
||||
* 结合性
|
||||
|
||||
* 优先级
|
||||
|
||||
* 运算符的特殊用法
|
||||
|
||||
如:`%`(要求左右两边都是整形),`=`与`==`,逻辑运算(`&&`和`||`)的短路特性
|
||||
|
||||
* 位运算的重要性
|
||||
|
||||
`<< >> ~ | ^ &`
|
||||
|
||||
1. 将操作数中第n位置1,其他位不变:`num = num | 1 << n;`
|
||||
|
||||
2. 将操作数中第n位清0,其他位不变:`num = num & ~(1 << n);`
|
||||
|
||||
3. 测试第n位:`if(num & 1 << n)`
|
||||
|
||||
4. 从一个指定宽度的数中取出某几位:
|
||||
|
||||
```c
|
||||
// 假设取一个32位整数的第10位到第15位
|
||||
unsigned int number;
|
||||
unsigned int mask = ((1 << 6) - 1) << 9; // 6 是位数(15-10+1),9 是起始位置(10-1)
|
||||
unsigned int result = number & mask;
|
||||
result = result >> 9;
|
||||
```
|
||||
|
||||
#### 运算符相关代码
|
||||
|
||||
```c
|
||||
#if 0
|
||||
i++相当于i=i+1
|
||||
i--相当于i=i-1
|
||||
|
||||
int i=1;
|
||||
i++;表达式值为1,i值为2
|
||||
++i;表达式值为2,i值为2
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if 0
|
||||
int main()
|
||||
{
|
||||
int i = 1, j = 10, value;
|
||||
|
||||
// value = i++ + ++j;
|
||||
// 相当于
|
||||
// j = j + 1;
|
||||
// value = i + j;
|
||||
// i = i + 1;
|
||||
// out:
|
||||
// i = 0 j = 11 value = 10
|
||||
|
||||
// value = --i + j++;
|
||||
// i = i - 1;
|
||||
// value = i + j;
|
||||
// j = j + 1;
|
||||
// out:
|
||||
// i = 1 j = 12 value = 12
|
||||
|
||||
// value = i++ + ++i - i-- + --i;
|
||||
// 避免单个变量多次自增或者自减
|
||||
// 不同编译器可能结果不同,也难为自己和他人
|
||||
|
||||
// printf("i=%d\n", i);
|
||||
// printf("j=%d\n", j);
|
||||
// printf("value=%d\n", value);
|
||||
|
||||
// printf("%d\n", i > j);
|
||||
|
||||
int a = 1, b = 2, c = 3, d = 4;
|
||||
int m = 1, n = 1;
|
||||
|
||||
// (m = a > b) && (n = c > d);
|
||||
// printf("m = %d\nn = %d\n", m, n);
|
||||
// a>b为假,所以左边为0,右边直接不判断了,n依旧为1而不是0!
|
||||
// out:
|
||||
// m = 0
|
||||
// n = 1
|
||||
|
||||
(m = a > b) || (n = c > d);
|
||||
printf("m = %d\nn = %d\n", m, n);
|
||||
// a>b为假,所以左边为0,右边继续判断
|
||||
// out:
|
||||
// m = 0
|
||||
// n = 0
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int main()
|
||||
{
|
||||
int i = 0, j = 10, value;
|
||||
|
||||
// int a = 6;
|
||||
// a -= a *= a += 3;
|
||||
// a -=.. 81-81=0
|
||||
// a *=.. 9*9=81给上面
|
||||
// a += 3; 6+3=9给上面
|
||||
// 故a=0
|
||||
|
||||
// printf("%d\n", sizeof(int));
|
||||
// printf("%d\n", sizeof(double));
|
||||
// out:
|
||||
// 4
|
||||
// 8
|
||||
|
||||
// int a = 3;
|
||||
// float f = 3.9;
|
||||
// a = f;
|
||||
// printf("a=%d\n", a);
|
||||
// printf("f=%f\n", f);
|
||||
// out:
|
||||
// a=3
|
||||
// f=3.900000
|
||||
|
||||
// int a = 3;
|
||||
// float f = 3.9;
|
||||
// a = (int)f; // 这个过程不改变f本身的地址和值
|
||||
// printf("a=%d\n", a);
|
||||
// printf("f=%f\n", f);
|
||||
// out:
|
||||
// a=3
|
||||
// f=3.900000
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
```
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Linux-C-Code
|
||||
# Linux-C-Notes
|
||||
Linux环境C语言开发学习笔记
|
||||
## 课程地址
|
||||
[史上最强最细腻的linux嵌入式C语言学习教程【李慧芹老师】_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV18p4y167Md/?spm_id_from=333.999.0.0&vd_source=4e03f52e94cfa281cde032856b1f93a7)
|
||||
|
||||
## 本仓库内容
|
||||
教学过程中所有的代码,注释清晰。
|
||||
配套学习笔记在另外一个仓库,[Linux-C-Note](https://github.com/sinlatansen/Linux-C-Note)。
|
||||
教学过程中所有的课程笔记和代码示例。
|
||||
|
||||
## 作者博客
|
||||
[fugu的小站](https://lzyyyyyy.fun/index.php/tag/%E6%9D%8E%E6%85%A7%E8%8A%B9/)也会同步更新,欢迎造访以获得更好的在线`markdown`阅读体验。
|
||||
|
||||
Reference in New Issue
Block a user