预定义宏,C语言预定义的宏详解
发布时间:2020-12-15 17:33:06 所属栏目:百科 来源:网络整理
导读:对于预定义宏,相信大家并不陌生。为了方便处理一些有用的信息,预处理器定义了一些预处理标识符,也就是预定义宏。预定义宏的名称都是以“__”(两条下划线)开头和结尾的,如果宏名是由两个单词组成,那么中间以“_”(一条下划线)进行连接。并且,宏名称
对于预定义宏,相信大家并不陌生。为了方便处理一些有用的信息,预处理器定义了一些预处理标识符,也就是预定义宏。预定义宏的名称都是以“__”(两条下划线)开头和结尾的,如果宏名是由两个单词组成,那么中间以“_”(一条下划线)进行连接。并且,宏名称一般都由大写字符组成。 在日常项目编程中,预定义宏尤其对多目标平台代码的编写通常具有重大意义。通过预定义宏,程序员使用“#ifdef”与“#endif”等预处理指令,就可使平台相关代码只在适合于当前平台的代码上编译,从而在同一套代码中完成对多平台的支持。从这个意义上讲,平台信息相关的宏越丰富,代码的多平台支持越准确。 标准 C 语言提供的一些标准预定义宏如表 1 所示。
除标准 C 语言提供的标准宏之外,各种编译器也都提供了自己的自定义预定义宏。可以通过表 2 所示的指令来查看不同编译器对预定义宏的支持情况。
图 3 显示了 GCC 编译器预定义宏的查看结果。虽然各种编译器的预定义宏不尽相同,但是一般都会支持“__DATE__、__FILE__、__LINE__与__TIME__”这 4 种预定义宏。 ![]() 图 3 查看 GCC 预定义宏 对于这些预定义宏的应用,基本上随处可见,下面举例介绍。 利用“__DATE__”和“__TIME__”宏可以用来确定程序编译的时间。如下面的示例代码所示: int main (void) { printf("Copyright (c) Powered by www.develhome.comn"); printf("Compiled on %s at %sn",__DATE__,__TIME__); return 0; }利用“__STDC__”与“__STDC_VERSION__”宏可以编写那些需要兼容标准 C 和非标准 C 编译器的程序,如下面的示例代码所示: #ifdef __STDC__ /* Some version of standard C */ #if defined(__STDC__VERSION__)&&__STDC_VERSION__>=199901L /* C99 */ #elif defined(__STDC_VERSION__)&&__STDC_VERSION__>=199409L /* C89 and amendment 1 */ #else /* C89 but not amendment 1*/ #endif #else /* __STDC__not defined */ /*Not Standard C*/ #endif利用__FILE__、__LINE__与__FUNCTION__(或者__func__)预定义宏的组合,在调试程序的时候可以很简单地在程序运行期进行异常跟踪。如下面的示例代码所示: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #define MESSAGE(message,assertion) do{ if(!(assertion)){ printf("line %d in %s(%s)",__LINE__,__FILE__,__FUNCTION__); if(message){ printf(":%s",message); } printf("n"); abort(); } }while(0) int OpenFile(const char *filename) { int fd; MESSAGE("文件名称不能够为空",filename); MESSAGE("文件不存在",0==access(filename,F_OK)); fd = open(filename,O_RDONLY); close(fd); return 0; } int main(int argc,char **argv) { MESSAGE("命令参数不能够为空",argc==2); OpenFile(argv[1]); return 0; }其中,__FILE__、__LINE__与__FUNCTION__(或者__func__)预定义宏分别表示文件名、行数与函数名,这样就可以帮助我们精确地定位出现异常的文件、行数与函数名。运行结果如图 4 所示。 ![]() 图 4 最后还需要注意的是,如果用户重定义“#define“或取消了“#undef”预定义宏,那么其结果是“未定义”的。因此,在代码编写中,应该尽量避免自定义宏与预定义宏名称相同的情况发生。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |