复习:
预处理命令
1、文件包含
#include 把一个头文件导入到当前文件中
#include <>
#include ""
编译参数 -I路径 指定加载路径
修改系统的环境变量
2、定义宏
宏常量
#define 宏名 替换的字面值数据
#define format %d%c%hhd%s%hd
如果在代码中使用了宏,那么在预处理时会把所有的宏替换为它后面的字面值数据
优点:提高可扩展性、提高可读性、提高安全性、与case配合使用
注意:一般宏名全部大写,末尾不加分号,不能直接换行(可以在末尾加 \ 续行符)
__func__ __FILE__ __LINE__ __DATE__ __TIME__
宏函数
不是真正函数,只是带参数的宏,使用宏函数,先替换成宏函数后面的代码,提供的参数会替换代码中相应的位置
#define AVG(a,b) {(a+b)/2;}
二义性:由于宏函数所处位置、参数的不同,导致同一个宏函数有多种解释结果,这种叫做宏的二义性
每个参数加小括号、整个式子也加小括号、不要在参数中使用自变运算符
运算符:
# 把宏函数的参数变成字符串
## 合并两个参数变成标识符
3、条件编译
根据条件决定哪些代码参与编译
#if #elif #else #ifdef #ifndef #endif
头文件卫士:
#ifndef FILENAME_H
#define FILENAME_H
...
#endif//FILENAME_H
版本控制:
#if VERSION >=3
#elif VERSION >=2
#else
#endif
判断编译器:
#if __cplusplus
printf("C++");
#else
printf("C");
#endif
4、常考的笔试面试题
定义一个宏表示100年总共有多少秒?
#define SEC (3600*24*365*100u)
#define和typedef的区别?
在定义常量时const与#define有什么区别?
宏函数与普通函数的区别?
5、头文件
重点:头文件中只能有声明语句,不能有定义语句
规则:
1、每个.c都应该有一个它的.h文件,对它进行说明
2、其他文件想要使用.c中的内容,只需要把它的.h导入即可
3、自己的.h也要导入,为了声明与定义一致
头文件相互包含:
解决方法:提取相互包含的内容,重新写另一个.h,然后再包含该.h
未知类型名“XXXX”,确认自己没写错名字,也导入对应的头文件,大概率就是头文件相互包含
5、Makefile
Makefile是一个由一系列编译指令组成的编译脚本,可以进行自动化编译
能写出最简单的Makefile即可
---------------------
一、结构
结构是一种由程序员自己设计的数据类型,用于描述一个事物的各项特征数据,由若干个不同的基础类型组成
设计:
struct 结构类型名
{
类型 成员名1;
类型 成员名2;
...
};
定义结构变量:
struct 结构类型名 结构变量名;
注意:struct在C语言中,定义结构变量时不能省略
定义结构变量并初始化:
struct 结构类型名 结构变量名 = {v1,v2,v3...};
初始化顺序一定要与成员顺序一致
struct 结构类型名 结构变量名 = {.成员名2=v2,.成员名1=v1,...};
只初始化某些成员,顺序无序一致
注意:同类型的结构变量可以直接给另一个结构变量初始化
注意:这种赋值方式只能在定义时使用
访问成员:
结构变量名.成员名;
由于结构变量的字节数一般都比较大,普通的值传递效率非常低,因此传递结构变量的地址,也即是传递结构指针变量,此时想要通过结构指针变量访问成员时借助 -> ,如果不需要修改指针变量的成员值,可以使用const保护
结构指针变量名->成员名;
练习1:设计一个教师结构体类型,类型中要有成员:姓名、性别、工龄、工号,定义一个教师结构变量,使用scanf输入每个成员的值并显示
typedef重定义结构类型名:
typedef struct 结构类型名 结构类型名;
typedef struct 结构类型名
{
}结构类型名;
之后定义结构变量,可以不加struct
如何计算结构体的总字节数:
结构成员顺序会影响它的总字节数,如果能够在设计结构体时合理地安排成员顺序,可以大大地节约内存
内存对齐:
假设第一个成员从零地址开始,存储每个成员的地址编号必须能被该成员的类型字节数整除,如果不能整除则填充空白字节
内存补齐:
结构体的总字节数,必须是它最大成员字节数的整数倍,如果不能整除,则在末尾补充空白字节
在Linux系统下计算结构体的对齐和补齐时,如果成员的字节数超过4,则按照4字节计算对齐和补齐
windows是按实际字节数对齐补齐
二、联合
三、枚举