一起来看看C语言的预处理注意点

C 预处理器

C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。

指令 描述
#define 定义宏
#include 包含一个源代码文件
#undef 取消已定义的宏
#ifdef 如果宏已经定义,则返回真
#ifndef 如果宏没有定义,则返回真
#if 如果给定条件为真,则编译下面代码
#else #if的替代方案
#elif 如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif 结束一个 #if……#else 条件编译块
#error 当遇到标准错误时,输出错误消息
#pragma 使用标准化方法,向编译器发布特殊的命令到编译器中

1.取消已定义宏

demo.h文件代码如下

#ifndef     __DEMO_H_
#define    __DEMO_H_


#define PAI 3.14


#endif // __DEMO_H_
#include 
#include "demo.h"

/* 在 #include 与 main 函数中间区域使用#undef来取消以定义的宏,然后重新定义宏 */

#undef PAI
#define PAI 33.14


int main()
{
    printf("PAI = %G\n", PAI);
}

/*
输出结果
PAI = 33.14
*/

2.使用#ifdef来调试

#ifdef DEBUG

/* 你的调试代码 */

#endif // DEBUG

如果定义了 DEBUG,则执行处理语句。在编译时,如果您向 gcc 编译器传递了 -DDEBUG 开关量,这个指令就非常有用。它定义了 DEBUG,您可以在编译期间随时开启或关闭调试。

常用预定义宏

描述
__DATE__ 当前日期,一个以 “MMM DD YYYY” 格式表示的字符常量。
__TIME__ 当前时间,一个以 “HH:MM:SS” 格式表示的字符常量。
__FILE__ 这会包含当前文件名,一个字符串常量。
__LINE__ 这会包含当前行号,一个十进制常量。

预处理器运算符 

1.宏延续运算符

\一个宏通常写在一个单行上。但是如果宏太长,一个单行容纳不下,则使用宏延续运算符\

#include 


#define PAI  \
                3.1415926

int main()
{
    printf("%.8f\n", PAI);
}

2.字符串常量化运算符#

在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符#。在宏中使用的该运算符有一个特定的参数或参数列表。就是把宏的参数变成字符串。

#include 


#define PAI 3.1415926
//字符串常量化
#define CONVERT_TO_STR1(arg) "字符串常量化:" #arg
//字符串常量化
#define CONVERT_TO_STR2(arg) CONVERT_TO_STR1(arg)

int main()
{
    printf("%s\n", CONVERT_TO_STR1(ABC));
    printf("%s\n", CONVERT_TO_STR1(PAI));
    printf("%s\n", CONVERT_TO_STR2(PAI));
}

/*
输出结果
字符串常量化:ABC
字符串常量化:PAI
字符串常量化:3.1415926
*/

这里有几点需要提一下。

1.宏定义中,当有多个字符串需要连接时,以空格来隔开每一个字符串即可。

2.当需要把一个宏字符串常量化时,需要按照先定义一个宏函数1,然后再定义一个宏函数2,然后宏函数2调用宏函数1即可,例如CONVERT_TO_STR2调用CONVERT_TO_STR1

3.标记粘贴运算符##

宏定义内的标记粘贴运算符(##)会合并两个参数。它允许在宏定义中两个独立的标记被合并为一个标记。

#include 


#define PRINTF1(arg) printf("var" #arg "  = %d\n" , var##arg)

int main()
{
    int var1 = 20;
    PRINTF1(1);
}


/*
输出结果
var1  = 20
*/

参数化的宏

使用注意点

用宏定义时,含参数时,参数本身要加(),此外,对参数的操作整体也要加()。

#define MAX(a,b) ((a)>(b)?(a):(b))

使用宏函数的时候不要使用++/--运算符

#include 


#define MIN(A,B) ((A)<(B)?(A):(B))

int main()
{
    char *p="ghi";
    char a;
    a=MIN(*p++,'f');//不要使用自增/自减运算符
    printf("%c\n",a);
}


/*
输出结果
f
*/

另,宏定义实现指定大小的交换:

#define SWAP(a, b, size)    \
    unsigned int __size = (size);    \
    char *__a = (a), *__b = (b);    \
    do    \
    {    \
        char __tmp = *__a;    \
        *__a++ = *__b;    \
        *__b++ = __tmp;    \
    } while (--__size > 0);

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容! 

你可能感兴趣的