配套代码笔记Github地址。目录目录第一章 绪论第一节C语言发展史C语言特点C语言学习建议课程思路课程平台第二节神一般的Hello world!源文件到可执行文件gccmakevim第三节基本概念以Hello world为例对写程序的思路提出如下要求1. 头文件正确包含的重要性2. 以函数为单位来进行程序编写3. 声明部分+实现部分4. return 0/exit(0)5. 多用空格空行6. 添加注释算法程序进程防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放第一章 绪论课程地址,史上最强最细腻的linux嵌入式C语言学习教程【李慧芹老师】_哔哩哔哩_bilibili。第一节C语言发展史时间发展1960原型A语言->ALGOL语言1963CPL语言1967BCPL1967B语言1973C语言C语言特点基础性语言语法间接、紧凑、方便、灵活运算符,数据结构丰富结构化,模块化编程移植性好,执行效率高允许直接对硬件操作C语言学习建议概念的正确性动手能力阅读优秀的程序段大量练习,面试题课程思路基础概念数据类型,运算符和表达式输入输出专题流程控制数组指针函数构造类型动态内存管理调试工具(gdb,make)常用库函数课程平台老师:64位的redhat6,vim,gcc4.4.6(make)本人:WSL-debian,vscode(remote ssh),gcc12.2.0(make),ohmyzsh(theme:eastwood)我的gcc版本比较新,所以很多提示比较完善,老师这个课程是很早的课,那个时候的gcc提示没有现在厉害,所以还是要结合老师的视频的思路,在当时提示不完善的时候是如何手撕代码分析出来的。第二节神一般的Hello world!//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);。源文件到可执行文件gccC源文件=>预处理=>编译=>汇编=>链接=>可执行文件所有#后面的代码都在预处理解决# 单步执行 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$ make hello cc hello.c -o hello # cc就是make选择的编译器,这里是gcc $ ls hello hello.cvim老师对于常用的.vimrc做了一些介绍,笔者建议vscode的remote-ssh插件,可以在win的vscode编辑器享受linux的环境。第三节基本概念以Hello world为例对写程序的思路提出如下要求1. 头文件正确包含的重要性#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的警告!!!# 通过 -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语言程序往往如果能把警告都消除,错误也能解决。例如:#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); }这个程序运行报段错误,这个时候,查看一下警告就是问题所在。$ ./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库。加入这个库重新运行。[main][~/LinuxC/Chapter1/Section3]$ make a cc a.c -o a [main][~/LinuxC/Chapter1/Section3]$ ./a fopen():No such file or directory2. 以函数为单位来进行程序编写main`是特殊的定义,其实就是一个正在运行的线程。其实对于内核而言,是只有进程的概念,且与我们理解的进程、线程不一样。3. 声明部分+实现部分早期的编译器要求变量先定义后使用。4. return 0/exit(0)结束当前进程,是给父进程看的。对于带有return 0的程序:[main][~/LinuxC/Chapter1/Section3]$ ./hello Hello world! [main][~/LinuxC/Chapter1/Section3]$ echo $? 0如果不带return 0:老师演示的返回值是13,是printf的返回的Hello world!\n的长度。在我本地无法复现,新版本可能改了。5. 多用空格空行6. 添加注释//单行注释 /* * 多行注释 * 多行注释 * 多行注释 */ //大段的注释 #if 0 func(){ } #endif算法解决问题的方法。(流程图,NS图,FSM有限状态机)程序用某种语言实现算法进程防止写越界,防止内存泄漏,谁打开谁关闭,谁申请谁释放