预定义宏,C语言预定义的宏详解
C语言 详解 预定
2023-06-13 09:11:54 时间
对于预定义宏,相信大家并不陌生。为了方便处理一些有用的信息,预处理器定义了一些预处理标识符,也就是预定义宏。预定义宏的名称都是以 __ (两条下划线)开头和结尾的,如果宏名是由两个单词组成,那么中间以 _ (一条下划线)进行连接。并且,宏名称一般都由大写字符组成。
如果当前编译器符合C89,那么它被定义为199409L;如果符合C99,那么它被定义为199901L:在其他情况下,该宏为宋定义
(C99 )定义为长整型常量,yyyymmL表示wchai_t值遵循ISO 10646标准及其指定年月的修订补充,否则该宏为未定义
图 3 查看 GCC 预定义宏
最后还需要注意的是,如果用户重定义 #define 或取消了 #undef 预定义宏,那么其结果是 未定义 的。因此,在代码编写中,应该尽量避免自定义宏与预定义宏名称相同的情况发生。
在日常项目编程中,预定义宏尤其对多目标平台代码的编写通常具有重大意义。通过预定义宏,程序员使用 #ifdef 与 #endif 等预处理指令,就可使平台相关代码只在适合于当前平台的代码上编译,从而在同一套代码中完成对多平台的支持。从这个意义上讲,平台信息相关的宏越丰富,代码的多平台支持越准确。
标准 C 语言提供的一些标准预定义宏如表 1 所示。
如果当前编译器符合C89,那么它被定义为199409L;如果符合C99,那么它被定义为199901L:在其他情况下,该宏为宋定义
(C99 )定义为长整型常量,yyyymmL表示wchai_t值遵循ISO 10646标准及其指定年月的修订补充,否则该宏为未定义
除标准 C 语言提供的标准宏之外,各种编译器也都提供了自己的自定义预定义宏。可以通过表 2 所示的指令来查看不同编译器对预定义宏的支持情况。
图 3 显示了 GCC 编译器预定义宏的查看结果。虽然各种编译器的预定义宏不尽相同,但是一般都会支持 __DATE__、__FILE__、__LINE__与__TIME__ 这 4 种预定义宏。
图 3 查看 GCC 预定义宏
对于这些预定义宏的应用,基本上随处可见,下面举例介绍。
利用 __DATE__ 和 __TIME__ 宏可以用来确定程序编译的时间。如下面的示例代码所示:
int main (void) printf( Copyright (c) Powered by www.develhome.com/n printf( Compiled on %s at %s/n , __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 所示。
最后还需要注意的是,如果用户重定义 #define 或取消了 #undef 预定义宏,那么其结果是 未定义 的。因此,在代码编写中,应该尽量避免自定义宏与预定义宏名称相同的情况发生。
21146.html
cGCC相关文章
- C语言switch语句的用法详解_c语言switch语句例题
- 蓝桥杯 2n皇后问题(精简)C语言
- 顺序表C语言实现
- C语言实验作业III-迷宫(广度优先搜索)
- 预处理指令用法详解(C语言)
- C语言_简单了解一下typedef详解程序员
- [C语言] 数据结构-预备知识跨函数使用内存详解编程语言
- [编程] C语言循环结构计算π的值详解编程语言
- C语言_初步了解一下指针详解编程语言
- #define用法,C语言#define详解
- 结构体数组及其定义和使用,C语言结构体数组详解
- 逻辑运算符及其优先级,C语言逻辑运算符及其优先级详解
- =与==的区别,C语言=与==的区别详解
- puts和fputs函数及其区别,C语言puts和fputs函数详解
- C语言求最小公倍数(详解版)
- C语言实现SQL Server数据库连接(c连接sqlserver数据库)
- 通过C语言操作SQL Server数据库的方法(c操作sqlserver)
- 在macOS环境下开发C语言:Tips和工具推荐(macos开发c)
- C语言掌控Oracle数据库的管理之道(c 管理oracle)
- 深入探索C语言操作Oracle的插入语句(c oracle插入语句)
- 基于C语言中段错误的问题详解
- C语言程序设计50例(经典收藏)
- C语言实现排序算法之归并排序详解
- C语言实现计算树的深度的方法