c语言预处理和宏定义详

来源:互联网 发布:易视云手机客户端软件 编辑:程序博客网 时间:2024/05/22 17:10

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

在一个c程序中,程序中所有的#都是由预处理器处理的,这是由编译器调用的特殊程序,在一个程序术语中,预处理器需要一个c程序,同时会产生一个没有#的c程序。
以下是有关C中预处理器的一些有趣的事实
(1)当我们使用include 指令时,将包含的头文件(预处理后)的内容复制到当前文件。
角括号<>指示预处理程序查看保存所有头文件的标准文件夹。双引号指示预处理器查看当前文件夹,用“ ”往往是我们自己写的头文件,基本都是和我们当前程序处于同一文件目录下,的如果文件不存在于当前文件夹中,则在所有头文件的标准文件夹中。
(2)当我们对常量使用define时,预处理器产生一个C程序,其中定义的常量被搜索,匹配的令牌被替换为给定的表达式。
//#include<stdio.h>#define max 100int 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+2int 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 * bint 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) #aint 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*bint 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*/