预处理

来源:互联网 发布:知轩藏书 编辑:程序博客网 时间:2024/05/27 09:48

预处理器在一般看来,用得最多的还是宏,这里总结一下预处理器的用法。

#include <stdio.h>#define MACRO_OF_MINE#ifdef MACRO_OF_MINE#else#endif

几个比较实用的用于调试的宏,由C语言自带

__LINE____FILE__用于显示当前行号和当前文件名
__DATE____TIME__用于显示当前的日期和时间
__func__(C99) 用于显示当前所在外层函数的名字
上述所说的五种宏直接当成值来使用即可。

**__STDC__**

如果你想检验你现在使用的编译器是否遵循ISO标准,用它,如果是他的值为1。

printf("%d\n", __STDC__);

输出: 1

如果你想进一步确定编译器使用的标准版本是C99还是C89可以使用__STDC__VERSION__,C99(199901)

printf("%d\n", __STDC_VERSION__);

输出: 199901

由于我们并不明白,在某些情况下宏是否被定义了,(NULL宏是一个例外,它可以被重复定义),所以我们可以使用一些预处理保护机制来防止错误发生

  #ifndef MY_MACRO  #define MY_MACRO 10000  #endif

如果定义了MY_MACRO那就不执行下面的语句,如果没定义那就执行。

在宏的使用中有两个有用的操作符,姑且叫它操作符#, ##

对于# 我们可以认为#操作符的作用是将宏参数转化为字符串。

#define HCMP(x, y) printf(#x" is equal to" #y" ? %d\n", (x) == (y))...int x = 100, y = 200;HCMP(x, y);

展开以后

printf("x is equal to y ? %d\n", (100) == (200));

对于##
它实现的是将本操作符两边的参数合并成为一个完整的标记,但需要注意的是,由于预处理器只负责展开,所以程序员必须自己保证这种标记的合法性,这里涉及到一些写法问题,都列出来

  #define MERGE(x, y) have_define_ ## (x + y)  #define MERGE(x, y) have_define_##(x + y)  ...  result = MERGE(1, 3);

无论哪种都无伤大雅,效果一样。上述代码展开以后是什么呢?

  result = have_define_1 + 3;

对于宏,在使用时一定要注意,宏只能展开当前层的宏,如果你嵌套使用宏,即将宏当作宏的参数,那么将导致宏无法完全展开,即作为参数的宏只能传递名字给外部宏。

C和C++混合编程的情况

经常能在源代码中看见 extern “C” 这样的身影,这是做什么的?
这是为了混合编程而设计的,常出现在 C++的源代码中,目的是为了让 C++能够成功的调用 C 的标准或非标准函数。

#if defined(__cplusplus) || defined(_cplusplus)        extern "C" {#endif        /**主体代码**/#if defined(__cplusplus) || defined(_cplusplus)        }#endif

这样就能在C++中调用C的代码了。

在 C 中调用 C++ 的函数需要注意,不能使用重载功能,否则会失败,原因详见C++对于重载函数的实现。也可以称为 mangle

#error token-sequence其主要的作用是在编译的时候输出编译错误信息token-sequence,从方便程序员检查程序中出现的错误。

# pragma token-sequence此指令的作用是触发所定义的动作。如果token-sequence存在,则触发相应的动作,否则忽略。此指令一般为编译系统所使用。

0 0
原创粉丝点击