C语言:预处理

一.宏定义

(1)数值宏定义

const这个关键字修饰的数据是有类型的,而define宏定义的数据是没有类型的。因此在定义一些宏常数的时候用const代替,编译器会给const修饰的只读变量做类型校验,减少错误的可能。

(2)字符串宏常量

除了定义宏常数之外,经常还用来定义字符串,尤其是路径。

#define ENG_PATH_1  E:\English\listen_to_this\listen_to_this_3
#define ENG_PATH_2  " E:\English\listen_to_this\listen_to_this_3"
#define ENG_PATH_1  E:\English\listen_to_this\listen\
_to_this_3

注意:反斜杠作为接续符时,在本行其后面不能有任何字符,空格都不行,所以最后一个反斜杠才是接续符。

(3)用define 宏定义注释符号“?”

例如

#define BSC//
#define BMC/*
#define EMC*/
(D)BSC my single -line comment
(E)BMC my multi -line comment EMC

(D)(E)都是错误的,因为注释先于预处理指令被处理,当前两行被展开成“//…”或“//”时,注释已经处理完毕,此时再出现“//…”或“//”自然产生错误。因此试图用宏开始或者结束一段注释都是不行的。

(4)用define 宏定义表达式

例如:定义一年有多少秒

#define SEC_A_YEAR (60*60*24*365)

这个定义是错误的,因为并没有考虑到16位系统下把这样一个数赋给整型变量的时候可能会发生溢出,一年有多少秒,不可能是负数。

可以修改一下得:但是此时有出现一个问题是这里的括号到底需不需要呢?
#define SEC_A_YEAR (606024*365)UL

再举一个例子

#define SQR(x)  x*x

此时假设x的值为10,SQR(x)被替换后变成10 * 10.没有问题。
假设x的值是一个表达式10+1,SQR(x)被替换后变成10+1*10+1。问题来了,这并不是想要的结果。

#define SQR(x) ( x)*(x)

此时这个代码没有问题吗?不尽然吧!

再举一个例子:

#define SUM(x)  (x)*(x)

假如x的值是一个表达式53,而代码又写为SUM(x)SUM(x),替换后变成(53)+(53)(53)+(5*3),此时得到的结果与想要的结果也不相同。

所以最外层的括号最好别省了

注意:函数宏被调用时是以实参代替形参,而不是“值传送”。

规则1 的宏定义只能扩展为用大括号括起来的初始化常量,小括号括起来的表达式,类型限定符,存储类标识符或者do-while-zero结构。
注意:宏语句的结尾必须省略分号。

规则2 函数宏的调用不能缺少参数,如果此函数宏有参数的话。

规则3 传递给函数宏的参数不能包含看似预处理指令的标记。

规则4 在定义函数宏时,每个参数实例都应该以小括号括起来,除非她们作为#或##的操作数。

例如

#define abs(x)((x)>=0)?(x):(-x))

不能定义为:

#define abs(x)  (((x) >=0)?x :-x)

因为如果这样定义的话z=abs(a-b);将会给出z=((a-b>=0)?a-b:a-b);子表达式-a-b相对于(-a)-b)而不是希望的-(a-b)。

规则5 define的预处理操纵阀只能使用两种标准形式:
defned (identfier)
defined identifer

(5)宏定义的空格
#define SUM (x) (x)+(x) 这并不是定义函数宏SUM(x),编译器会认为 这是定义了一个宏:SUM,其代表的是(x) (x)+(x).其关键问题就在于SUM后面的空格。

二.文件包含

(1)#include <filename>

表示预处理到系统规定的路径中去获得这个文件(即C编译系统提供的并存在指定子目录下的头文件)。

(2)#include "filename"

双引号表示预处理应该在当前目录中查找文件名为filename的文件,若没有找到,则系统指定的路径信息搜索其他目录。

#Include 是将已经存在文件的内容嵌入到当前文件中。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值