C语言知识点复习纲要
1.初始C语言
- 8种数据类型及其大小
- 变量 常量
变量的作用域和生命周期
常量的定义方法——const 和 define - 字符串的定义方式
- 转移字符的使用
- 选择语句,循环语句,函数
- 数组——整型数组,字符数组
char ch3[] = “hello”;//后面默认有一个/0 - 运算符
加减乘除
取模 移位
按位与或非
sizeof
按位取反——对存在内存中的补码进行取反的
强制类型转换——()
&& ||
三目操作符——max = (a > b ? a : b)
逗号表达式——从左往右依次计算,结果是最后一个表达式的结果 - 关键字
typedef——类型重命名
register——寄存器
static——修饰局部变量,修饰全局变量,修饰函数 - #define定义常量和宏
- 指针——指针变量的大小取决于地址的大小 (4/8)
- 结构体
2.基础语句
1. 分支语句
(1)单分支
(2)多分支
(3)悬空else——else遵循就近原则
(4)switch语句——switch 语句中,条件的入口为case,出口为break
2. 循环语句——for循环,while循环,do while循环
(1)while循环中continue和break的区别
(2)do while循环中continue和break的区别
(3)循环语句的应用——二分查找,利用getchar输入或吸收字符,求最大公约数,打印素数
3.函数,递归函数
- 库函数
- 自定义函数
- 函数参数——实参,形参
- 函数调用——传值调用,传址调用
- 函数的嵌套调用和链式访问
举例:
printf("%d", printf("%d", printf("%d", 43)))
43 2 1
打印结果为:4321个数
printf函数返回打印数组的
- 函数的声明和定义
- 函数递归
(1)什么是递归——把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求
(2)递归的两个条件
<1>存在限制条件,当满足这个限制条件的时候,递归便不再继续。
<2>每次递归调用之后越来越接近这个限制条件。
(3)递归的应用
——接受一个整型(无符号),按照顺序打印他的每一位
——不创建临时变量,用自定义函数求字符串长度
——求n的阶乘
——求斐波那契数
链接: 函数,递归函数.
4.数组
- 一维数组的创建和初始化
- 二维数组的创建和初始化
- 一维数组,二维数组在内存中的存储——连续存储
- 数组越界——编译器也不一定报错
- 数组作为函数参数
——在用数组名进行传参时,传过去的是数组的首元素地址,在调用函数中无法通过sizeof计算数组的大小。 - 除以下两种情况之外,所有的数组名都表示数组首元素的地址
- 数组应用——三子棋,扫雷
链接: 数组.
5.指针初阶
- 指针是什么
——指针就是变量,用来存放地址的变量 - 一个小的单元
——指针的大小在32位平台是4个字节,在64位平台是8个字节 - 指针和指针类型
(1)指针类型的意义
——指针的类型决定了指针向前或者向后走一步有多大(距离)
——决定了对指针解引用的时候有多大的权限(能操作几个字节)
4. 野指针的成因
(1)指针未初始化
(2)指针越界访问
(3)指针指向的空间释放 - 指针运算
(1)指针± 整数
(2)指针-指针=两个指针之间元素的个数
(3)指针的关系运算——允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。 - 指针与数组——p+i 其实计算的是数组 arr 下标为i的地址
- 二级指针
- 指针数组
链接: 指针初阶.
6.结构体
- 结构体成员的访问
- 结构体传参——传结构体的地址
链接: 结构体.
7.调式技巧
- debug 和 release的区别
- 调试手段
(1)查看零时变量的值——监视窗口
(2)查看内存信息
(3)查看调用堆栈
(4)查看汇编信息
(5)查看寄存器信息
(6)条件断点的使用 ——通过 F5 跳转
3. const修饰指针变量的时候的作用:
const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。但是指针变量本身的内容可变。
const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。
- 一个死循环的分析
链接: 实用调试技巧.
7.深度剖析数据在内存中的存储
- 数据类型详细介绍
(1)数据类型的意义
(2)类型的基本归类——整型家族,浮点数家族,构造类型,指针类型,空类型 - 整型在内存中的存储
(1)原码,反码,补码
——正数的原反补相同
——负数的原反补不相同
——对于整型来说,数据存放在内存中存放的其实是补码(原因分析)
3. 大小端字节序介绍及判断
(1)什么大端小端?
(2)设计一个小程序来判断当前机器的字节序
(3)练习 - 浮点数在内存中的存储
链接: 深度剖析数据在内存中的存储.
8.深度理解指针
- 字符指针
- 指针数组
- 数组指针
- 函数指针
- 函数指针数组
- 指向函数指针数组的指针
- 回调函数——把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数
链接: 深度理解指针.
9.有关数组和指针的笔试题
链接: 有关数组和指针的笔试题.
10.字符函数和字符串函数
1.strlen函数——计算字符串长度
size_t strlen ( const char * str );
2.strcpy函数——字符串复制函数
char* strcpy(char * destination, const char * source);
3.strcat函数——字符串追加函数
char * strcat ( char * destination, const char * source );
4.strcmp函数——字符串比较函数
int strcmp ( const char * str1, const char * str2 );
5.strncpy函数——有长度限制的字符串复制函数
char * strncpy ( char * destination, const char * source, size_t num );
6.strncat函数——有长度限制的字符串追加函数
char * strncat ( char * destination, const char * source, size_t num );
7.strncmp函数——有长度限制的字符串比较函数
int strncmp ( const char * str1, const char * str2, size_t num );
8.strstr函数——字符串查找函数
char * strstr ( const char str2, const char * str1);
9.strtok函数——字符串分割函数
char * strtok ( char * str, const char * sep );
10.strerror函数——字符串报错函数
char * strerror ( int errnum);
返回错误码对应的错误信息
11.memcpy函数——内存复制函数
void * memcpy ( void * destination, const void * source, size_t num );
12.memmove函数——memcpy的升级
void * memmove ( void * destination, const void * source, size_t num );
13.memcmp函数——逐个字节的比较
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
比较从ptr1和ptr2指针开始的num个字节
14.memset函数——逐个字节设置内存
void memset( void dest, int c, size_t count );
将 内存dest 开始的 count 个字节设置成 c;
15.字符分类函数——头文件为 #include<ctype.h>
链接: 字符函数和字符串函数.
11.自定义类型——结构体,枚举,联合
一.结构体
- 结构体类型声明
没有typedef的声明
有typedef的声明
匿名结构体类型 - 结构体的自引用
- 结构体变量的定义和初始化
- 结构体内存对齐原则
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的值为8,Linux环境没有默认对齐数,对齐数就是成员自身大小。
- 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍
- 用 #pragma pack( )修改默认对齐数
- 为什么存在对齐
- 结构体传参
二.位段
1.什么是位段?
2.位段的内存分配
3.位段的跨平台使用
4.位段的使用
三.枚举, 联合体
链接: 自定义类型——结构体,枚举,联合.