初识C语言
- 1972年,贝尔实验室
- 编译器
- C标准
- C库
- UNIX、LINUX
基本数据类型
- 基本数据类型
- 变量和常量
- 数据类型关键字
- 字符和转义字符
- 八进制和十六进制
- 可移植类型:stdint.h 和 inttypes.h
- _Bool 类型
- 复数和虚数
- 类型大小:sizeof(int)
字符串格式化输入和输出
- 头文件 string.h
- 字符串和char类型数组
- 编译器自动在字符串末尾加上一个空字符
- 字符串长度函数 strlen()
- 符号常量和预处理器
- const限定符号:只读常量
- 明示常量 limits.h
- printf() 和 scanf()
- 底层类型 size_t
运算符、表达式、语句
- while循环
- 基本运算符
- 运算符和求值顺序
- 常用运算符:sizeof、size_t、%、++
- 运算符和优先级
- 表达式和语句
- 类型转换
循环
- while
- do while
- for
- 关系运算符
- 赋值运算符+=
分支和跳转
- if else
- ctype.h
- 逻辑运算符
- 条件运算符 ?:
- 循环辅助 continue、break
- switch
- goto 语句
字符输入输出 I/O
- 输入缓冲区、行缓冲、完全缓冲
- 文件缓冲区
- UNIX库和ANSI C库的区分
- 文件和底层I/O
- 流的概念
- 标准输入stdin和输出设备stdout
- 文件末尾EOF(end of file)
- 停止输入 Ctrl+D、Ctrl+Z
- 重定向和文件
- ”»“运算符 文件追加
- ”|” 一个文件输出链接另一个文件输入
- 输入验证
- C程序把每个字符解释成一个字符编码
函数
- 函数声明
- 形式参数和实际参数
- 变量和作用域
- 可变参数函数声明(stdargs.h)
- 递归
- 编译多源码文件的程序
- 取地址运算符 &
- 间接运算符 *
- 指针声明 int * p
数组和指针
- 数组声明和初始化
- 二维数组
- 数组和指针
- 函数和指针
- 指针表示法
- 指针操作
- 对形式参数使用const,表示不修改指针或者数组的内容
- 指针常量和常量指针
- 指针和多维指针
- 指向数组的指针
- 函数和多维数组
- C99 变长数组-动态内存分配
- C99 符合字面常量
字符串和字符串函数
- 字符串常量
- 字符串初始化
- 字符串和指针
- 字符串输入
- get()和put()方法
- C11-fgets()和fputs()
- 字符串输出
- 字符串函数 string.h
- strlen() 字符串长度
- strcat() 拼接字符串
- strncat() 限制拼接字符串长度
- strcmp 比较字符串(即使数组大小也不同)
- strncmp 比较字符串(查找”abc”开头的字符串)
- strcpy 拷贝字符串(值拷贝)
- strncpy 安全拷贝
- ctype.h字符函数和字符串
- 命令行参数(main(int argc, char *argv[]))
- stdlib.h 字符串转整数atoi()
存储类别、链接和内存管理
- 左值:如果可以使用左值修改对象中的值,该左值就是一个可修改的左值
- 作用域:块作用域名、函数作用域、函数原型作用域或者文件作用域名、全局作用域
- 链接:外部链接、内部链接、无链接
- 翻译单元:一个源代码文件和它所包含的头文件
- 存储期:自动和静态
- 寄存器变量:register
- 静态变量在程序载入内存时便已经执行初始化
- 不允许声明形式参数为静态
- 外部存储类别到静态变量: extern 关键字
- 变量的定义式声明和引用式声明,文件之间通过定义式声明和引用式声明共享变量
- 存储类别说明符:auto,register,static,extern,_Thread_local
- typedef
- 外部函数和静态函数(只能本文件访问)
- 保护性程序设计的黄金法则是:“按需知道”,尽量少使用外部存储变量
- 随机数函数rand()
- malloc 和 free
- 存储类别和动态内存分配(堆区:动态内存分配、栈区:自动内存分配、静态区:静态数据)
- const 只读变量, 指针常量:值是只读的, 常量指针:指针是只读的
- volatile 限定符告诉计算机,代理(不是变量所在的程序)可以改变该变量的值
- restrict关键字允许编译器优化某部分代码以更好的支持计算
- C11-_Atomic类型限定符号(原子访问,处理并发问题)
文件输入和输出
- 文件:文本模式和二进制模式
- 底层I/O和标准C库I/O
- 标准文件:标准输入(stdin)、标准输出(stdout)、标准错误输出(stderr)
- 输入和输出缓冲区
- 文件指针FILE, 指向结构体FILE的指针
- fopen和fclose
- 文件结尾EOF
- 文件I/O函数: fprintf()和fscanf()
- rewind() 返回文件开始处
- fgets()和fputs()
- 随机访问:fseek()和ftell()
- 标准I/O的工作原理
- ungetc() 将指定字符放入输入流
- fflush() 输出缓冲区中所有未写入数据被发送到指定输出文件
- fread()和fwrite()二进制形式处理数据
- C 程序把输入和输出看作是字节流,输入流来源于文件、输入设备,输出来源于文件、屏幕等,如何解释输入和输出流取决于使用的输入和输出函数
结构和其他数据形式
- 结构体声明 struct
- 定义结构体变量
- 结构体初始化
- 结构体的成员访问
- 结构数组
- 结构体的嵌套
- 指向结构的指针
- ”->” 使用指针访问结构体成员
- 结构体指针作为函数参数
- 使用结构体存储字符串,使用字符数组比较简单,使用字符串指针注意风险
- 使用malloc为结构体分配存储空间
- C99-符合字面量
- 把结构内容保存到文件中
- 链式结构
- 联合union-联合成员共享一个共同的存储空间,联合同一时间只能存储一个单独的数据项,不像结构体那样同时储存多个数据类型
- 枚举类型(声明符号名称来表示整型常量,提高程序可读性)
- 共享名称空间namespace
- typedef 为某一个类型自定义名称,由编译器解释
- 其他复杂的声明
- 函数指针(存储着函数代码起始处的地址,类似于java中的接口回调)
位操作
- C在提供高级语言便利的同时,还能在为汇编语言所保留的级别上工作,这使其成为编写设备驱动程序和嵌入式代码的首选语言
- 二进制数
- 符号整数和二进制补码:符号整数,00000001表示1,二进制补码对应的负数为反转每一位+1, 即11111110 + 1 = 11111111表示-1
- 二进制浮点数
- 八进制和十六进制
- 按位逻辑运算符:取反、与、或、异或
- 掩码MASK
- 移位运算符 “« »”
C预处理器和C库
- 预处理器
- 预处理之前到翻译工作
- #define指令–宏替换
- 在#defince中使用参数
- 预处理器黏合剂:##运算符
- 可变参数宏:…和_ VA_ARGS _
- 宏和函数的选择:实际上是时间和空间的权衡,宏生成内联代码,即在程序中生成语句,空间占用大,函数需要控制跳转,时间占用大
- 文件包含:#include
- 头文件常见的内容:#define指令、宏指令、外部变量声明、结构声明、typedef和函数原型
- #undef 取消已经定义的#define指令
- 条件编译指令 #ifdef #else #endif #ifndef
- 使用#ifndef处理头文件重复包含问题
- 预定义宏 _ DATE 当前日期, _ _FILE _当前文件名
- #line指令重置 _ line__和 _FILE__ 宏报告的行号和文件名
- #error指令让预处理发出一条错误消息,该消息包含指令中的文本,编译可能中断
- #pragma把编译器指令放入源代码中,_Pragma
- C11-泛型选择
- C99-内联函数:使用内联代码替换函数调用,内联函数定义和调用必须在同一个文件中,一般放在头文件,内部链接
- C11-_Noreturn: 告诉用户和编译器,这个特殊的函数不会把控制返回主调用函数
- C库
- 数学库 math.h
- 通用工具库 stdlib.h 包括随机数生成器、查找和排序函数,转换函数和内存管理函数
- qsort() 快速排序函数
- 断言库 assert.h, assert()宏接受一个整形表达式作为参数,如果表达式为假的,则在标准错误流写入一条错误信息
- string.h库中的memcpy()和memmove() 处理数组的拷贝
- 可变参数: stdarg.h
C 预处理器和C库是C语言两个重要的附件。C预处理器遵循预处理器指令,在编译源代码之前调整源代码。C库提供许多有有助于完成各种任务的函数包括输入、输出、文件处理、内存管理、排序和搜索、数学运算、字符串处理等
高级数据表示
- 链表:链表是一个能储存一系列项目可以对其进行所需操作的数据对象
- 建立ADT接口
- 抽象数据类型编程步骤:a.以抽象、通用的方式描述一个类型,包括该类型的操作 b.设计一个函数接口表示这个新类型 c.实现接口
- 队列
- 数组和链表的比较
- 二叉查找树