C语言中预定义了一些有用的宏,如表10.4.1所示。这些宏主要用来提供当前编译的信息。宏__LINE__和宏__STDC__是整型常量,其他3个宏是字符串常量。
表10.4.1 C语言中的预定义宏
对于预定义宏,我们需要知道以下几点。
(1)__DATE__宏和__TIME__宏指明程序编译的时间。
例如,假设程序以下面的语句开始:
printf("Compiled on %s at %s", __DATE__, __TIME__);
每次程序开始执行,程序都会显示下面一行:
Compiled on Jul 13 2021 at 17:56:32
这样的信息可以帮助区分同一个程序的不同版本。
(2)可以使用__LINE__宏和__FILE__宏来找到错误。
考虑下面这个检测被零除的除法的发生位置问题。当一个C程序因为被零除而中止时,通常没有信息指明哪条除法运算导致了错误。下面的宏可以帮助我们查明错误的来源:
#define CHECK_ZERO(divisor) if (divisor == 0) printf("*** Attempt to divide byzero on line %d of file %s ***", __LINE__, __FILE__)
CHECK_ZERO宏应该在除法运算前被调用,即
CHECK_ZERO(j); k = i/j;
如果j是0,那么会显示如下形式的信息:
*** Attempt to divide byzero on line 9 of file F00.c ***
类似这样的用来检测错误的宏非常有用。实际上,C语言库提供了一个通用的、用于错误检测的宏,即宏assert。又如,
#line 838 "Zend/zend_language_scanner.c"
#line预处理用于改变当前的行号(__LINE__)和文件名(__FILE__)。例如,上面的代码将当前的行号改变为838,文件名为Zend/zend_language_scanner.c,其作用体现在编译器的编写中。我们知道编译器编译C源程序时会产生一些中间文件,通过这条指令,可以保证文件名是固定的,有利于进行调试分析。
摘自《跟“龙哥”学C语言编程》