一、预处理命令:所有的预处理命令 都 以 # 开头
例: #include <stdio.h> //预处理命令
C提供的预处理功能主要有以下3种:
- 宏定义
- 文件包含
- 条件编译
二、编译
例:gcc hello.c //编译
实际的编译过程:
1、预处理:
将程序中的预处理命令,执行完,将代码处理成 纯的C语言代码
例如:gcc -E hello.c -o hello.i
2、编译:
将预处理完的文件,进行语法,词法分析,检查问题
生成 一份 汇编代码
例如:gcc -S hello.i -o hello.s
3、汇编:
将 前面的汇编代码,最终翻译成机器代码
例如:gcc -c hello.s -o hello.o
4、链接:
将用到的第三方代码 链接(拼接)成为 最终可执行程序
例如:gcc hello.o -o hello
三、宏定义
1、#define 标识符 字符串
#define 宏名 宏值
作用:
用宏名代替 一串文本信息
注意:- 宏名 --本质还是一个标识符
- 宏名 建议 大写
- 宏名 --符号常量
用了一个 符号(宏名) 代替 常量值 - 宏工作的本质
文本原样替换
但是:
代码中出现在 “” //字符串中的 宏名 ,不会被替换 - 用途
可以用宏名 来代替一些常量
符号常量
好处,可以做到一改全改
可以提高代码可读性
#define ARRAY_SIZE 10
int array[ARRAY_SIZE]
eg:
#define N 10
练习:计算一下 圆的周长和面积
从键盘输入一个半径
2、带参宏:
#define 宏名(参数表) 宏值
1.带参宏 ,可以 给一些参数
形式 特别像函数调用
宏函数
2.带参宏 和 函数有本质的区别
a.函数的参数 是带类型的
b.带参宏 参数,没有类型 --就是文本
c.函数什么时候可以用?
程序运行之后
d.带参宏
在预处理阶段
就处理完了
3.带参宏 工作过程
本质上还是文本原样替换
参数是一一对应的
4.带参宏副作用
建议,
能加括号都加括号
可能会改变,我们建议都加括号
5.所有宏定义
是以 换行 ‘\n’作为结束符
练习:
1、两个数相乘
错误示范:
#define MUL(a,b) ab
MUL(1+2,3+4) 1+23+4
正确示范:
#define MUL(a,b) ((a)*(b))
2、实现一个宏,找出两个数的最大值
四、文件包含:
#include <文件名> //默认到系统的标准路径下寻找要包含的头文件
#include “文件名” //双引号 默认先到当前位置下 寻找要包含的头文件,如果找到,则包含进来
// 如果没找到,才到系统的标准路径下寻找
#include <stdio.h>
说明: - include 这个预处理命令执行之后,
用文件中的内容 ,替换这个 命令所在位置 - 将来使用
<> //如果是系统的相关头文件 — 用 <>
“” //如果是自己写的 一般用 “”
五、条件编译:
1:(1)#if 0
程序行;
#endif
(2)#ifdef 标识符
程序段1
#else
程序段2
#endif
语义:
判断 标识符 是否定义了?
如果定义了 —真
选择 程序段1
如果没定义 —假
选择 程序段2
(3)#ifdef 标识符
程序段1
#endif
满足条件的时候 ,添加 程序段1
不满足条件时候,啥都没有
(4)#ifndef 标识符
程序段1
#else
程序段2
#endif
语义:
没有定义 标识符 则选择程序段1
有定义 标识符 则选择程序段2
(5)#if 表达式
程序段1
#else
程序段2
#endif
(6)#if 表达式
程序段
#endif
2:用途:
可以用来实现 多文件编程
3:注意:
(1)printf //系统里面的函数 需要#include <stdio.h>
实现好的功能 .c 独立的c程序提供 或者 打包成库文件
.c //写好了功能的点c文件
.c 对应 有一个 .h (头文件)
.c — 就是实现功能的具体代码 —函数
.h — 头文件 --放的是 自身需要用到 宏 类型说明 函数声明 //变量的定义 不能放头文件
(2)int a = 10; //a一定得开空间
extern int a; //声明a在其他变量中有定义了,无需自己再定义
(3)说明:
头文件包含
注意 — 一定要写
#ifndef 头文件名 //要大写 前后 下划线
#define 头文件名
#endif
(4)快捷键命令:
vsp //竖着分屏
sp
窗口之间切换:
ctrl + 两下w
编译:
所有 .c 一起编译
gcc main.c isLeapYear.c getAllDays.c …//这些需要一起编译