第三章 预处理
知识点一:预处理指令
预处理名称 | 意义 |
#define | 宏定义 |
#undef | 撤销已定义过的宏名 |
#if #endif | #if 的一般含义是:如果#if后面的常量表达式为true ,则编译它与#endif之间的代码,否则跳过这些代码
|
#else | #else 命令的功能有点像C语言中的else,#else建立另一选择(在#if失败的情况下) |
#elif | #elif命令意义与 else if相同,它形成一个if else -if阶梯状语句,可进行多种编译选择 |
#ifdef
#ifndef | 用#ifdef与#ifndef命令分别表示“如果有定义”与“如果无定义”,是条件编译的另一种方法 |
#error | 编译程序时,只要遇到#error就会生成一个编译错误的提示消息,并停止编译 |
#pragma | 可以设定编译程序完成一些特定的动作 |
知识点二:宏定义
1.注意:(1)宏名一般用大写
(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义
(3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
(4)宏定义末尾不加分号;
(5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
(6)可以用#undef命令终止宏定义的作用域
(7)宏定义可以嵌套
(8)字符串" "中永远不包含宏
(9)宏定义不分配内存,变量定义分配内存。
(10)宏定义不存在类型问题,它的参数也是无类型的。
2.字符串宏常量
宏经常用来定义字符串,尤其是路径:
(a) #define ENG_PATH_1 E:\English\listen_to_this\listen_to_this3
(b) #define ENG_PATH_2 " E:\English\listen_to_this\listen_to_this3 "
到底哪一个正确呢?如果路径太长,一行写下来比较别扭怎么办?用反斜杠接续符:
(c)#define ENG_PATH_3 E:\English\listen_to_this\
listen_to_this3
从上面3处有没有看见什么问题?这里用了4个反斜杠,到底哪个是接续符?回去看看接续符反斜杠。反斜杠作为接续符时,在本行其后面再有任何字符,空格都不行。所以,只有最后一个反斜杠才是接续符。但是请注意:有的系统里规定路径要用双反斜杠“\\”,比如:
#define ENG_PATH_4 E:\\English\\listen_to_this\\listen_to_this3
3.用define宏定义表达式
下面来点有技术含量的: 定义一年有多少秒:
#define SEC_A_YEAR 60*60*24*365
这个定义没错吧?很遗憾,错!!其实也并不是考你宏定义,而是看你有没有在16位系统下把这样一个数赋值给整型变量的时候可能会发生溢出!
正确应该是:#define SEC_A_YEAR (60*60*24*365)UL
4.#undef
#undef 是用来撤销宏定义,用法如下:
#define PI 3.141592654
....
//code
#undef PI
//下面的代码就不能用 PI了,它已经被撤销了宏定义
也就是说宏定义的生命周期从#define 开始到 #undef结束。含简单,请思考一下这个问题
#define X 3
#define Y X*2
#undef X
#define X 2
int z=Y; z 的值是多少?
答因为宏定义不是表达式,只是简单的字符替换。#define Y X*2 这句执行后,Y就是X*2,而不是6。最后int z=Y;相当于int z=X*2;而最新的X是2,所以这句又相当于:int z=3*2;