c语言预处理和宏定义详

关于宏和预处理器的有趣的事实

在一个c程序中,程序中所有的#都是由预处理器处理的,这是由编译器调用的特殊程序,在一个程序术语中,预处理器需要一个c程序,同时会产生一个没有#的c程序。
以下是有关C中预处理器的一些有趣的事实
(1) 当我们使用 include  指令时,将包含的头文件(预处理后)的内容复制到当前文件。
角括号 < > 指示预处理程序查看保存所有头文件的标准文件夹。双引号 指示预处理器查看当前文件夹,用“ ”往往是我们自己写的头文件,基本都是和我们当前程序处于同一文件目录下,的如果文件不存在于当前文件夹中,则在所有头文件的标准文件夹中。
(2)当我们对常量使用define时,预处理器产生一个C程序,其中定义的常量被搜索,匹配的令牌被替换为给定的表达式。
//#include<stdio.h>
#define max 100
int main()
{
    printf("max is %d", max);
    return 0;
}
// Output: max is 100
// Note that the max inside "" is not replaced
3)宏可以使用参数的函数,不会检查参数的数据类型。例如,以下宏INCREMENT(x)可用于任何数据类型的x。
#include <stdio.h>
#define INCREMENT(x) x+2
int main()
{
    char *ptr = "HELLO";
    int x = 10;
    printf("%s  ", INCREMENT(ptr));//字符串后移两位
    printf("%d", INCREMENT(x));//x+2
    return 0;
}
// Output: LLO 12

4)在宏扩展之前,宏参数不被评估。例如考虑以下程序

#include<stdio.h>
#define HAHA(a, b) a * b
int main()
{
    int m = HAHA(2+3, 3+5);
    printf("%d", m);
    return 0;
}
结果:16

5)传递给宏的令牌可以使用operator ##称为令牌粘贴运算符进行连接。

#include<stdio.h>
#define MERGE(a, b) a##b
//将a 和 b 拼接
int main()
{
    printf("%d\n", MERGE(12, 13));
    return 0;
}

OUTPUT:1213

6)传递给宏的令牌可以使用#转换为sting文字

#include <stdio.h>
#define get(a) #a
int main()
{
    // HELLO is changed to "HELLO"
    printf("%s", get(HELLO));
}
// Output: HELLO

7)宏可以使用'\'写入多行。最后一行不需要“\”。

#include<stdio.h>
#define Manyline(i, limit) while(i < limit) \
{ \
    printf("hello!"); \
    i++; \
}
int main()
{
    int i = 0;
    Manyline(i,3);
    return 0;
}

8)有争议的宏应该避免,因为它们有时会引起问题。并且内联函数应该是首选的,因为内联函数中有类型检查参数评估。从C99起,C语言也支持内联函数。
例如考虑以下程序。从第一眼看,输出似乎是1,但它产生36作为输出。

#include<stdio.h>
#define CHENGFA(a, b) a*b
int main()
{
    printf("%d", 36/CHENGFA(6,6));
    return 0;
}//没有用内联函数
输出为36    运算时36/6*6

如果我们使用内联函数,我们得到预期的输出。此外,上述第四点给出的程序可以使用内联函数进行更正。

9)预处理器还支持通常用于条件编译的if-else指令。

#include<stdio.h>
int main()
{
#if 3 >= 2
  printf("Trace Message");
#endif
}

10)头文件可能直接或间接包含多于一次,这导致重新声明相同变量/功能的问题。为了避免这个问题,像指令定义IFDEFIFNDEF使用。
11)有一些标准的宏可用于打印程序文件(__FILE__),编译日期(__DATE__),编译时间(__TIME__)和行代码(__LINE__)

#include <stdio.h>   int main() {    printf("Current File :%s\n", __FILE__ );    printf("Current Date :%s\n", __DATE__ );    printf("Current Time :%s\n", __TIME__ );    printf("Line Number :%d\n", __LINE__ );    return 0; }

output:

/*Current File :de1.c
Current Date :May 17 2017
Current Time :21:32:54
Line Number :8*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

戴着眼镜看不清

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

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

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

打赏作者

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

抵扣说明:

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

余额充值