文章目录
预处理定义
程序设计领域中,预处理一般是指在程序源代码被翻译为目标代码的过程中,生成二进制代码之前的过程。典型地,由预处理器(preprocessor) 对程序源代码文本进行处理,得到的结果再由编译器核心进一步编译。这个过程并不对程序的源代码进行解析,但它把源代码分割或处理成为特定的单位——(用C/C++的术语来说是)预处理记号(preprocessing token)用来支持语言特。
C++都规定程序由源代码被翻译分为若干有序的阶段(phase) ,通常前几个阶段由预处理器实现。预处理中会展开以#起始的行,试图解释为预处理指令(preprocessing directive) ,其中C/C++要求支持的包括#if,#ifdef,#ifndef,#else,#elif,#endif(条件编译)、#define(宏定义)、#include(源文件包含)、#line(行控制)、#error(错误指令)、#pragma(和实现相关的杂注)以及单独的#(空指令)。预处理指令一般被用来使源代码在不同的执行环境中被方便的修改或者编译。
所有#开头的都是预处理
- 文件包含:把头文件中内容拷贝到include的位置
#include <xxx.h> — vs的安装目录.
#include “xxx.h” — 首先在当前目录找,没找到则去vs目录
自定义头文件: 函数声明.结构体声明,全局变量声明.
附加知识: 当前目录: ./danny.txt 可以省略./
上级目录: …/笔记.txt …/…/笔记.txt
相对路径: 相对于某一个文件夹的路径 比如…/笔记.txt
绝对路径: D:\c_day23\xxx.txt- 宏定义
给某一个标志赋一个值或者直接定义一个标志( 做替换作用 ).
格式1: #define 宏名字 值
案例: #define DANNY 17
格式2: 带参数的宏定义.
#define 宏名字(参数,参数) 参数计算
案例: #define ADD(X,Y) X+Y
格式3: #define 标志
案例: #define XIAQI
注意:所有预处理都不需要加分号.因为预处理不是一条语句.
所有宏定义的名字都需要大写(但不是必须的)
宏定义是没有类型的,不占用内存空间
带参宏在定义的时候,必须对每个参数都加括号,并且整体算式加括号
c语言常用的内置宏:(日志文件)
FILE 表示当前文件路径
LINE 当前使用宏的行
DATE 最后一次编译日期
TIME 最后一次编译时间
__cplusplus 这是c++的标志
宏操作符(# ##)
# 把宏的参数变成字符串,把参数加上双引号
## 可以把一个代表标志的参数和其他内容合并成新的标志.
面试题: 宏定义和const常量的区别.
1.宏定义不占用内存空间,const变量占用
2.宏定义是在预处理阶段,而const变量在运行阶段
3.都不可以修改.但宏定义没有类型- 条件编译
如#if,#ifdef,#ifndef,#else,#elif,#endif(条件编译)都是条件编译,在编译之前进行处理。
//代码演示
#include <stdio.h>
#include "test.h"
#define XIAQI
#define DANNY 17
const int DANNY1 = 17;
#define STR(X) #X
#define CONST_STR(X) c_##X
#define ADD(X,Y) ((X)*(Y))
int main()
{
printf("danny = %d\n",DANNY);
printf("ADD = %d\n", ADD(1+1,2+2)); //1+1*2+2 = 5
printf("%s\n当前行%d\n最后一次编译日期:%s\n"
"最后一次编译的时间:%s\n",
__FILE__, __LINE__, __DATE__,__TIME__);
const int CONST_STR(danny) = 123; //定义了一个 c_danny
printf(STR(123));
getchar();
return 0;
}