5复习:
预处理命令
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
头文件卫士:
#ifndef FILENAME_H
#defien 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",确定自己没有写错名字,也导入对应的头文件,大概率就是头文件相互包含
6、Makefile
Makefile是一个由一系列编译指令组成的编译脚本,可以进行自动化编译
能写出最简单的Makefile即可
----------------------------------
一、结构
结构是一种程序员自己设计的数据类型,用于描述一个事物的各项特征数据,由若干个不同的基础类型组成
设计:
struct 结构类型名 -> 连在一起叫类型名
{
类型 成员名1;
类型 成员名2;
...
};
定义结构变量:
struct 结构类型名 结构变量名;
注意: struct在c语言中,定义类型变量时不能省略
定义结构变量并初始化:
struct 结构类型名 结构变量名 = {v1,v2,v3...};
初始化顺序一定要与成员顺序一致
struct 结构类型名 结构变量名 = {.成员名2=v2,.成员名1=v1,...};
只初始化某些成员,顺序无需一致
注意:同类型的结构变量可以直接给另一个结构变量初始化
注意:这种赋值方式只能在定义时使用
访问成员:
结构变量名.成员名; 普通结构变量时
由于结构变量的字节数一般都比较大,普通的值传递效率会非常低,因此传递结构变量的地址,也就是传递结构指针变量
此时想要通过结构指针变量访问成员时借助 -> ,如果不需要修改指针变量的成员值,可以使用const保护
结构指针变量名->成员名;
练习1: 设计一个教师结构体类型,类型中要有成员:姓名、性别、工号、工龄,定义一个教师结构变量,使用scanf输入每个成员的值并显示
typedefc重定义结构类型名:
typedef struct 结构类型名 结构类型名;
typedef struct 结构类型名
{
}结构类型名;
之后定义结构变量,可以不加struct
如何计算结构体的字节数:
结构成员顺序会影响它的总字节数,如果能够在设计结构体时合理地安排成员顺序,可以大大地节约内存
内存对齐:
假设第一个成员从0地址开始,存储每个成员的地址编号必须能被该成员的类型字节数整除,如果不能整除则填充空白字节
内存补齐:
结构体的总字节数,必须是它最大成员字节数的整数倍,不满足则在末尾补充空白字节
在Linux系统下计算结构体的对齐和补齐时,如果成员的字节数超过4,则按照4字节计算对齐和补齐
windows是按实际字节数对齐补齐