README
# 专栏笔记总结大全
# 01.基础语法
- 1.1.1 标准简史:新增了⼀些语法,泛型、国际化⽀持. ⽬前为⽌最新版本是 C11。
- 1.1.5 C语⾔特点:C 语言的语法都是基础语法,不提供高级的数据结构,比如 C 语言没有“类”class,复杂结构需要自己构造。
- 1.1.6 C语言版本:2011年,标准化组织再一次对 C 语言进行修订,增加了 Unicode 和多线程的支持。这个版本称为 C11。
- 1.2.1 编译器:编译器是将C语言源代码转换为可执行程序的工具。
- 1.2.2 集成开发环境:IDE 提供了代码编辑、编译、调试等一体化功能,适合大型项目开发。
- 1.2.3 构建工具:构建工具用于自动化编译和链接过程。
- 1.3.3 编译源文件:使用gcc编译器,将源文件
hello.c编译成二进制代码。还可以通过-std=c99指定编译版本。 - 1.4.2 语句块:使用一对大括号{},组成一个块,也称为复合语句。
- 1.4.5 标准库头文件:“标准库”,因为它们是写入标准的,到底包括哪些功能,应该怎么使用的,都是规定好的,这样才能保证代码的规范和可移植。
- 1.5.1 修饰符:修饰符是用来修改基本数据类型的含义的关键字,通常用于声明变量或函数的类型。
- 1.5.2 标识符:标识符是用来标识变量、函数、数组等程序实体的名称。必须以字母或者下划线开头!
- 1.5.3 常见关键字:在C语言中被赋予了特定含义的英文单词,一共有32个关键字。关键字是高亮显示的!
# 02.数据类型
- 2.1.1 基本数据类型:基本数据类型有三种,字符(char)、整数(int)和浮点数(float)。
- 2.1.2 字符类型char:字符类型指的是单个字符,类型声明使用char关键字。char 类型通常占用 1 字节(8 位)的内存空间。
- 2.1.3 整数类型:char类型,short类型,int类型,还有long类型。
- 2.1.4 浮点型:提供了三种浮点类型:
float、double和long double。 - 2.1.5 布尔类型:并没有为布尔值单独设置一个类型,而是使用整数0表示伪,所有非零值表示真。头文件stdbool.h定义了另一个类型别名bool,并且定义了true代表1、false代表0。
- 2.2.1 变量:可以理解成一块内存区域的名字。通过变量名,可以引用这块内存区域,获取里面存储的值。
- 2.2.2 变量的声明:必须先声明后使用。如果一个变量没有声明,就直接使用,会报错。
- 2.2.3 变量的赋值:声明变量以后,变量会是一个随机的值。所以,变量一定要赋值以后才能使用。
- 2.2.4 变量的作用域:凡是在块作用域里面声明的变量,只在当前代码块有效,代码块外部不可见。
- 2.3.1 const常量:const说明符表示变量是只读的,不得被修改。
- 2.3.2 static常量:
- 2.4.1 枚举定义:enum colors {RED, GREEN, BLUE}; 枚举,Enum 内部的常量名,遵守标识符的命名规范,但是通常都使用大写。
- 2.4.2 枚举别名:typedef 命令可以为 Enum 类型起别名。声明变量时,使用这个别名即可。
- 2.4.3 枚举常量:Enum 的属性会自动声明为常量。C 语言会自动从0开始递增,为常量赋值。
- 2.5.1 字符串介绍:是由字符组成的数组,以空字符
\0结尾。没有内置的字符串类型,字符串通常通过字符数组或字符指针来表示。 - 2.5.2 字符串声明:第一种 char str[] = "Hello, World!";第二种 const char *str = "Hello, World!";
# 03.运算符
- 3.1.1 自增自减运算:这个 ++:是自增运算符,这个 --:是自减运算符。
- 3.1.2 自增自减前缀后缀区别:放在变量前,先 +1、-1 再取值使用。放在变量后,先 取值用,再 +1、-1。
- 3.2.1 基本数学运算:加法,减法,除法,乘法,取模运算等等。
# 04.循环和选择
- 4.2.1 if语句:
if语句用于在条件为真时执行代码块。 - 4.2.2 if-else语句:
if-else语句用于在条件为真时执行一个代码块,否则执行另一个代码块。 - 4.2.3 多条件语句:
if-else if-else语句用于处理多个条件。这种很常见。 - 4.2.4 switch语句:
switch语句用于根据变量的值执行不同的代码块。 - 4.2.5 嵌套选择结构:
- 4.2.6 三元运算符:
05.输入输出
- 5.1 输入输出库:输入输出函数定义在
<stdio.h>头文件中,主要包括格式化输入输出、字符输入输出和文件输入输出。 - 5.2.1 printf介绍:
printf函数用于将格式化的数据输出到标准输出设备(通常是屏幕)。 - 5.2.2 占位符:(格式说明符)是用于格式化输入/输出函数(如
printf和scanf)的特殊标记,用于指定变量类型和格式化规则。 - 5.2.3 输出多个常量:printf("我亲亲女朋友的姓名是:%s。性别:%s。年龄:%d岁。身高:%f。体重:%d斤", "小诗诗","女",18,1.82,110);
- 5.3 格式化输入:
scanf函数用于从标准输入设备(通常是键盘)读取格式化数据。 - 5.4.1 读取一个字符:
getchar从标准输入读取一个字符。 - 5.4.2 写入一个字符:
putchar向标准输出写入一个字符。 - 5.5.1 字符串输入:
fgets从文件或标准输入读取一行字符串。 - 5.5.1 字符串输出:
puts向标准输出写入字符串。
06.函数
- 6.1.1 函数概念:是程序的基本构建块,用于将代码组织成可重用的模块。函数可以接收输入参数,执行特定任务,并返回结果。
- 6.1.2 函数的定义:
- 6.1.3 函数声明:函数声明(也称为函数原型)告诉编译器函数的名称、返回类型和参数列表。
- 6.2.1 调用函数语法:通过函数名和参数列表调用函数。
- 6.2.2 理解栈帧:当函数被调用时,系统会在 stack 空间上申请一块内存,用来给函数调用提供空间。函数调用结束时,这块内存空间,会被自动释放 (消失) 。
- 6.3.1 参数:形式参数,函数定义中的参数。实际参数,函数调用时传递的参数。
- 6.4 函数返回值:使用
return语句返回函数的结果。如果返回类型是void,则不需要return语句。 - 6.6.1 数组作为函数参数:数组可以作为函数参数传递,实际传递的是数组的首地址。
07.指针
- 7.1.1 通俗的案例:计算机中为了访问数据,将内存中的信息进行编号。类似现实中通过家庭地址去找某个人一样
- 7.1.2 一切都是地址:在 C 语言中,所有数据(变量、数组、指针、函数等)最终都存储在内存中,而内存中的每个存储单元都有地址。都是通过地址访问数据!
- 7.1.3 指针基本概念:指针的本质是一个变量,它存储的是另一个变量的内存地址。通过指针,我们可以间接地访问和操作内存中的数据。
- 7.2.1 声明指针:字符*表示指针,通常跟在类型关键字的后面,表示指针指向的是什么类型的值。比如:int *a; Student *std;
- 7.2.2 初始化指针:int *p = 1 这种是错误的。正确的应该是 int *p = &x; 将 p 初始化为 x 的地址。
- 7.2.3 访问指针的值:访问指针的值是通过 解引用操作符
*来实现的。 - 7.3.1 基本指针操作:
*是解引用运算符,用于访问指针指向的地址中的值。可以修改指针指向的变量的值。 - 7.3.4 *和&运算符:
*这个符号除了表示指针以外,用来取出指针变量所指向的内存地址里面的值。&运算符用来取出一个变量所在的内存地址。 - 7.4.2 指针类型转换:可以使用强制类型转换将一种指针类型转换为另一种指针类型。注意:指针类型转换可能导致未定义行为,需谨慎使用。
- 7.4.3 泛型指针:void 指针是一种特殊类型的指针,可以指向任何类型的数据,因为它不指向特定的数据类型。
- 7.5.3 指针比较运算:指针之间的比较运算通常用于比较指针所指向的内存地址的大小关系。
- 7.6 指针与字符串:字符串通常被表示为字符数组,而指针可以用来指向字符串的首地址。
- 7.8 多级指针:主要是指针指向另一个指针的指针,也就是指针的指针。多级指针主要用来处理复杂数据。
- 7.9.1 空指针:指针未初始化时,应将其设置为
NULL。 - 7.9.2 野指针:野指针(dangling pointer)是指指向已释放的内存地址或未初始化的内存地址的指针。
- 7.9.3 指针类型匹配:指针的类型必须与指向的数据类型匹配。如果类型不匹配则会报错。
- 7.9.4 指针算术运算:指针的算术运算基于指向的数据类型的大小。
09.类和内存
- 9.1.0 没有类概念:C 语言没有类的概念,但可以通过结构体和函数指针模拟面向对象的特性。
- 9.1.1 结构体模拟类:结构体可以用来封装数据,类似于类中的成员变量。但是这种类只有成员变量……
- 9.1.2 模拟成员方法:
- 9.1.3 模拟继承:
- 9.1.4 模拟多态:
- 9.2.1 栈(Stack):用于存储局部变量、函数参数和函数调用的上下文。比如函数中的变量就是存储在栈上,生命周期跟随函数调用而创建和销毁。
- 9.2.2 堆(Heap):用于动态内存分配
- 9.2.3 全局/静态区:用于存储全局变量和静态变量。
- 9.2.4 常量区:用于存储字符串常量和
const变量。
10.流和文件
11.结构体
- 11.1 结构体介绍:结构体(Structure)是一种用户定义的数据类型,用于将不同类型的数据组合在一起。
- 11.2 结构体定义:使用
struct关键字定义结构体。 - 11.3.1 结构体声明:定义结构体后,可以声明结构体变量。比如,struct 结构体名 变量名;
- 11.3.2 结构体访问:使用点运算符
.访问结构体成员。比如,stu.id = 1; - 11.3.3 结构体初始化:
- 11.3.5 结构体大小:使用
sizeof运算符可以获取结构体的大小。 - 11.3.6 结构体嵌套:结构体可以包含其他结构体作为成员。
- 11.4 结构体数组:可以定义结构体数组来存储多个结构体变量。
- 11.5 结构体指针:可以使用指针访问结构体成员。
- 11.6.1 结构体作为函数参数:
- 11.6.2 结构体指针作为函数参数:
- 11.7 结构体和函数:
- 11.8 结构体对齐:结构体的成员在内存中可能对齐,以提高访问效率。可以使用
#pragma pack控制对齐方式。
12.线程和锁
- 12.1 线程:线程是通过 POSIX 线程库(pthread) 来实现的。
pthread是 标准线程库,提供了创建、管理和同步线程的 API。 - 12.1.1 基本概念:线程是程序执行的最小单元,一个进程可以包含多个线程,线程共享进程的内存空间。
- 12.1.2 pthread介绍:
- 12.1.3 创建线程:使用
pthread_create函数创建线程,可以设置线程属性,线程执行函数。 - 12.1.4 线程的终止:第一种情况,线程函数执行完毕后,线程会自动终止。使用
pthread_cancel强制终止线程。 - 12.1.5 线程分离:使用
pthread_detach将线程设置为分离状态,线程结束后自动释放资源。 - 12.1.6 线程属性:可以通过
pthread_attr_t设置线程属性,如栈大小、调度策略等。 - 12.1.7 线程返回值:线程函数可以通过
return或pthread_exit返回结果,主线程使用pthread_join获取返回值。 - 12.3.1 互斥锁Mutex:
- 12.3.2 条件变量:
13.预处理器
# 学习资源
- 书籍:
- 《C程序设计语言》(K&R)
- 《C Primer Plus》
- 在线教程:
- 练习平台:
2.1 C语言的一个简单实例 2.2 实例说明 2.3 一个简单程序的结构 2.4 使程序可读的技巧 2.5 更进一步 2.6 多个函数 2.7 调试 2.8 关键字和保留标识符 2.9 关键概念 2.10 总结 2.11 复习题 2.12 编程练习
3.1 示例程序 3.2 变量与常量数据 3.3 数据:数据类型关键字 3.4 C数据类型 3.5 使用数据类型 3.6 参数和易犯的错误 3.7 另一个例子:转义序列 3.8 关键概念 3.9 总结 3.10 复习题 3.11 编程练习
4.1 前导程序 4.2 字符串简介 4.3 常量和C预处理器 4.4 研究和利用printf()和scanf() 4.5 关键概念 4.6 总结 4.7 复习题 4.8 编程练习
5.1 循环简介 5.2 基本运算符 5.3 其他运算符 5.4 表达式和语句 5.5 类型转换 5.6 带有参数的函数 5.7 一个示例程序 5.8 关键概念 5.9 总结 5.10 复习题 5.11 编程练习
6.1 再探while循环 6.2 while语句 6.4 不确定循环与计数循环 6.5 for循环 6.6 更多赋值运算符:+=、-=、*=、/=和%= 6.7 逗号运算符 6.8 退出条件循环:do while 6.9 选择哪种循环 6.10 嵌套循环 6.11 数组 6.12 使用函数返回值的循环例子 6.13 关键概念 6.14 总结 6.15 复习题
7.1 if语句 7.2 在if语句中添加else关键字 7.3 获得逻辑性 7.4 一个统计字数的程序 7.5 条件运算符?: 7.6 循环辅助手段:continue和break 7.7 多重选择:switch和break 7.8 goto语句 7.9 关键概念 7.10 总结 7.11 复习题 7.12 编程练习
8.1 单字符I/O:getchar()和putchar() 8.2 缓冲区 8.3 终止键盘输入 8.5 创建一个更友好的用户界面 8.6 输入确认 8.7 菜单浏览 8.8 关键概念 8.9 总结 8.10 复习题 8.11 编程练习
9.1 函数概述 9.2 ANSI C的函数原型 9.3 递归 9.4 多源代码文件程序的编译 9.5 地址运算符:& 9.6 改变调用函数中的变量 9.7 指针简介 9.8 关键概念 9.9 总结 9.10 复习题 9.11 编程练习
10.1 数组 10.2 多维数组 10.3 指针和数组 10.4 函数、数组和指针 10.5 指针操作 10.6 保护数组内容 10.7 指针和多维数组 10.8 变长数组(VLA) 10.9 复合文字 10.10 关键概念 10.11 总结 10.12 复习题 10.13 编程练习
12.1 存储类 12.2 存储类说明符 12.3 存储类和函数 12.4 随机数函数和静态变量 12.5 掷骰子 12.6 分配内存:malloc()和free() 12.7 ANSI C的类型限定词 12.8 关键概念 12.9 总结 12.10 复习题 12.11 编程练习
13.1 和文件进行通信 13.2 标准I/O 13.3 一个简单的文件压缩程序 13.4 文件I/O:fprintf ( )、fscanf ( )、fgets ( )和fputs ( )函数 13.5 随机存取:fseek()和ftell()函数 13.6 标准I/O内幕 13.7 其他标准I/O函数 13.8 关键概念 13.9 总结 13.10 复习题 13.11 编程练习
14.1 示例问题:创建图书目录 14.2 建立结构声明 14.3 定义结构变量 14.4 结构数组 14.5 嵌套结构 14.6 指向结构的指针 14.7 向函数传递结构信息 14.8 把结构内容保存到文件中 14.9 结构:下一步是什么 14.10 联合简介 14.11 枚举类型 14.12 typedef简介 14.13 奇特的声明 14.14 函数和指针 14.15 关键概念 14.16 总结 14.17 复习题 14.18 编程练习
15.1 二进制数、位和字节 15.2 其他基数 15.3 C的位运算符 15.4 位字段 15.5 关键概念 15.6 总结 15.7 复习题 15.8 编程练习
第16章 C预处理器和C库 16.1 翻译程序的第一步 16.2 明显常量:#define 16.3 在#define中使用参数 16.4 宏,还是函数 16.5 文件包含:#include 16.6 其他指令 16.7 内联函数 16.8 C库 16.9 数学库 16.10 通用工具库 16.11 诊断库 16.12 string.h库中的memcpy()和memmove() 16.13 可变参数:stdarg.h 16.14 关键概念 16.15 总结 16.16 复习题 16.17 编程练习
第17章 高级数据表示 17.1 研究数据表示 17.2 从数组到链表 17.3 抽象数据类型(ADT) 17.4 队列ADT 17.5 用队列进行模拟 17.6 链表与数组 17.7 二叉搜索树 17.8 其他说明 17.9 关键概念 17.10 总结 17.11 复习题 17.12 编程练习