【C语言】预处理器

【C语言】预处理器

1.简介

C 语言编译器在编译程序之前,会先使用预处理器(preprocessor)处理代码。

预处理器首先会清理代码,进行删除注释、多行语句合成一个逻辑行等工作。然后,执行#开头的预处理指令。

预处理指令可以出现在程序的任何地方,但是习惯上,往往放在代码的开头部分。

每个预处理指令都以#开头,放在一行的行首,指令前面可以有空白字符(比如空格或制表符)。#和指令的其余部分之间也可以有空格,但是为了兼容老的编译器,一般不留空格。

所有预处理指令都是一行的,除非在行尾使用反斜杠,将其折行。指令结尾处不需要分号。

2.#define宏定义

2.1基本用法

1.#define是最常见的预处理指令,用来将指定的词替换成另一个词。它的参数分成两个部分,第一个参数就是要被替换的部分,其余参数是替换后的内容。每条替换规则,称为一个宏(macro)。

#define MAX 100

上面示例中,#define指定将源码里面的MAX,全部替换成100MAX就称为一个宏。

宏的名称不允许有空格,而且必须遵守 C 语言的变量命名规则,只能使用字母、数字与下划线(_),且首字符不能是数字。

2.宏是原样替换,指定什么内容,就一模一样替换成什么内容。

#define HELLO "Hello, world"

// 相当于 printf("%s", "Hello, world");
printf("%s", HELLO);

上面示例中,宏HELLO会被原样替换成"Hello, world"

#define指令可以出现在源码文件的任何地方,从指令出现的地方到文件末尾都有效。习惯上,会将#define放在源码文件的头部。它的主要好处是,会使得程序的可读性更好,也更容易修改。

3.#define指令从#开始,一直到换行符为止。如果整条指令过长,可以在折行处使用反斜杠,延续到下一行。

#define OW "C programming language is invented \
in 1970s."

上面示例中,第一行结尾的反斜杠将#define指令拆成两行。

4.#define允许多重替换,即一个宏可以包含另一个宏。

#define TWO 2
#define FOUR TWO*TWO

上面示例中,FOUR会被替换成2*2

5.注意,如果宏出现在字符串里面(即出现在双引号中),或者是其他标识符的一部分,就会失效,并不会发生替换。

#define TWO 2

// 输出 TWO
printf("TWO\n");

// 输出 22
const TWOs = 22;
printf("%d\n", TWOs);

上面示例中,双引号里面的TWO,以及标识符TWOs,都不会被替换。

6.同名的宏可以重复定义,只要定义是相同的,就没有问题。如果定义不同,就会报错。

// 正确
#define FOO hello
#define FOO hello

// 报错
#define BAR hello
#define BAR world

上面示例中,宏FOO没有变化,所以可以重复定义,宏BAR发生了变化,就报错了。

2.2带参数的宏

基本用法

1.多个参数

宏的强大之处在于,它的名称后面可以使用括号,指定接受一个或多个参数。

#define SQUARE(X) X*X

上面示例中,宏SQUARE可以接受一个参数X,替换成X*X

注意,宏的名称与左边圆括号之间,不能有空格。

这个宏的用法如下。

// 替换成 z = 2*2;
z = SQUARE(2);

注意有坑!!

这种写法很像函数,但又不是函数,而是完全原样的替换,会跟函数有不一样的行为。

#define SQUARE(X) X*X

// 输出19
printf("%d\n", SQUARE(3 + 4));

上面示例中,SQUARE(3 + 4)如果是函数,输出的应该是49(7*7);宏是原样替换,所以替换成3 + 4*3 + 4,最后输出19。

可以看到,原样替换可能导致意料之外的行为。

**解决办法:**就是在定义宏的时候,尽量多使用圆括号,这样可以避免很多意外。

#define SQUARE(X) ((X) * (X))

上面示例中,SQUARE(X)替换后的形式,有两层圆括号,就可以避免很多错误的发生。

2.空参数

宏的参数也可以是空的。

#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘猫.exe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值