#
表示编译预处理命令
在程序编译时,把指定的文件模块包含在内,经过链接形成可执行文件后,include就不再存在,所以include不是c语句
<>在设置好的include文件夹中寻找文件
“”如果在当前工作文件夹中找不到,就到系统include文件夹中查找文件
宏字符串中间可以有空格,以回车符作为结束
宏定义作用:
- 增加程序灵活性
- 为程序书写带来方便
宏嵌套定义#define LONG_STRING "iflasdfhlkajdslfkjalskdjflajdsfj \
jfalkdsjfkajsdfljlasdjf."
// 表示该行未结束
printf(LONG_STRING)
#define PI 3.1415926
#define S PIrr
如果只想把源程序中的一部分语句生成目标代码,可以使用条件编译
#define FLAG 1
#if FLAG
程序段1
#else
程序段2
#endif
if条件只能是宏名,无法处理表达式
全局变量只能在某个文件模块中定义一次,否则单独编译时不出错,当链接时就会出现一个全局变量多次定义的错误!
如果其他文件模块要使用这个global variable,需要通过外部变量的声明。这样子,当程序链接时就会统一指向全局变量的定义的那个模块。
反之,如果不声明就使用,会出现“未定义”的错误
外部变量声明格式:extern 类型名 变量名;
include头文件==把头文件里的声明复制粘贴到了main.c中
同名.c也引用
避免重复编译
只会编译一次
双下划线代表系统变量
多文件编程
blog
初学c语言函数调用时,习惯将功能函数放在主函数下方,在主函数上面进行函数声明。
多文件编程:.c文件内装有函数本体,.h文件内放入函数声明,以供其他函数调用。
头文件不应该包含定义
1.创建两个.c文件,function1.c和function2.c 2.分别在两个.c文件内定义需要的函数 3.创建两个.h文件,文件名与两个.c文件一致,即function1.h和function2.h 4.在两个.h文件中分别包含各自所需的库文件,声明在.c中定义的函数 5.在main.c文件中包含两个.h文件,在main函数中直接调用两个自定义函数
又例如,当开发更加复杂的项目(如学生管理系统)时,我们可以将库函数调用、宏定义、结构体定义、全局变量定义等整个项目都需要使用的内容放在一个头文件中,在需要使用的文件内包含该文件。
< > 与 “ “
include
代表编译时直接在软件设置的指定路径中寻找里面是否有stdio.h的库文件。如果有,直接加载;如果没有,报错(无法找到库文件)。
include “function1.h”
代表编译时先寻找你正在编辑的源代码文件所在的文件夹里面有没有function1.h的库文件。如果有,优先加载这个文件(指定路径下如果也有function1.h,它就被无视了),如果没有,才会在指定路径中寻找是否有function1.h的库文件。如果有,直接加载;如果没有,报错(无法找到库文件)。
避免重复定义和重复包含
WHY
1.在编译c程序时候,编译器会将你源程序中#include的头文件完整的展开,如果你在同一个.c下多次包含相同的头文件,会导致编译器在后面的编译步骤多次编译该头文件,使整个项目编译速度变的缓慢,后期的维护修改变得困难。
2.头文件重复包含可能会使程序在编译链接的时候因变量重复定义而崩溃。
HOW
//条件编译
//test.h
#ifndef _TEST_H_
#define _TEST_H_ //一般是文件名的大写
//文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,
//………………………………
//………………………………
//………………………………
#endif
- 由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式
条件编译
blog
条件编译是指预处理器根据条件编译指令,有条件地选择源程序代码中的一部分代码作为输出,送给编译器进行编译。
条件编译指令 | 说 明 |
---|---|
#if | 如果条件为真,则执行相应操作 |
#elif | 如果前面条件为假,而该条件为真,则执行相应操作 |
#else | 如果前面条件均为假,则执行相应操作 |
#endif | 结束相应的条件编译指令 |
#ifdef | 如果该宏已定义,则执行相应操作 |
#ifndef | 如果该宏没有定义,则执行相应操作 |