1、预定义宏

  • 对于预定义宏,相信大家并不陌生。为了方便处理一些有用的信息,预处理器定义了一些预处理标识符,也就是预定义宏。预定义宏的名称都是以“__”(两条下划线)开头和结尾的,如果宏名是由两个单词组成,那么中间以“_”(一条下划线)进行连接。并且,宏名称一般都由大写字符组成。
  • 在日常项目编程中,预定义宏尤其对多目标平台代码的编写通常具有重大意义。
  • 通过预定义宏,程序员使用“#ifdef”与“#endif”等预处理指令,就可使平台相关代码只在适合于当前平台的代码上编译,从而在同一套代码中完成对多平台的支持。从这个意义上讲,平台信息相关的宏越丰富,代码的多平台支持越准确。

2、C标准预定义宏

  • 标准 C 语言提供的一些标准预定义宏如表 1 所示。

表 1 常用的标准预定义宏
描 述
_DATE_ 丐前源文件的编泽口期,用 “Mmm dd yyy”形式的字符串常量表示
_FILE_ 当前源文件的名称,用字符串常量表示
_LINE_ 当前源义件中的行号,用十进制整数常量表示,它可以随#line指令改变
_TIME_ 当前源文件的最新编译吋间,用“hh:mm:ss”形式的宁符串常量表示
STDC 如果今前编泽器符合ISO标准,那么该宏的值为1,否则未定义
_STDC_VERSION_ 如果当前编译器符合C89,那么它被定义为199409L;如果符合C99,那么它被定义为199901L:在其他情况下,该宏为宋定义
_STDC_HOSTED_ (C99)如果当前是宿主系统,则该宏的值为1;如果当前是独立系统,则该宏的值为0
_STDC_IEC_559 (C99)如果浮点数的实现符合IEC 60559标准时,则该宏的值为1,否则为未定义
_STDC_IEC_559_COMPLEX_ (C99)如果复数运算实现符合IEC60559标准时,则该宏的伉为1,否则为未定义
STDC_ISO_10646 (C99 )定义为长整型常量,yyyymmL表示wchai_t值遵循ISO 10646标准及其指定年月的修订补充,否则该宏为未定义

3、预定义宏的使用

  • 3.1 确定程序编译的时间

    • 利用“_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;
    }
  • 3.2 兼容编译器的程序

    • 利用“_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
  • 3.3 异常跟踪

    • 利用_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 所示。

    ![](https://img2018.cnblogs.com/blog/1213778/201812/1213778-20181220213218820-859526665.jpg)

    图 4

    - 其中,\__FILE__、__LINE__与\__FUNCTION__(或者\__func__)预定义宏分别表示文件名、行数与函数名,这样就可以帮助我们精确地定位出现异常的文件、行数与函数名。运行结果如图 4 所示。

最新文章

  1. android下面使用SurfaceView+ mediaPlayer播放视频
  2. 原生JS实现轮播+学前端的感受(防止走火入魔)
  3. MySQL 数据库实现远程连接
  4. knockout 学习实例3 html
  5. 新建URL,cookie技术
  6. python文件取MD5
  7. Apache, Nginx获得nginx代理后的真实用户Ip
  8. bzoj1015 星球大战
  9. JavaScript寻踪OOP之路
  10. IT 基础设施
  11. 我的插件のinput文本框实现宽度自适应
  12. 测试RegExp对象的属性
  13. sde需要注意的几个常见问题
  14. textarea的不可拉伸和不可编辑
  15. spring(一)--spring/springmvc/spring+hibernate(mybatis)配置文件
  16. jdk各个版本的新特性(jdk1.7,1.8,1.9)
  17. 创建ajax的步骤
  18. 最近对latin-1这个字符集产生了不少好感
  19. oracle获取执行计划及优缺点 详解
  20. 【bat/cmd】脚本开发

热门文章

  1. 第十六章 Java内存模型(待续)
  2. mssql server修改数据库文件位置 此种方法暂未测试成功
  3. HIVE UDF
  4. leetcode524
  5. [luogu3391] 【模板】文艺平衡树(fhq-treap反转区间)
  6. linux系统上部署一个web项目
  7. Codeforces 1153D 树形DP
  8. Python学习笔记_一个Tkinter示例,使用FileDialog
  9. 我搭建大数据Hadoop完全分布式环境遇到的坑---hadoop: command not found
  10. c语言实践 数字特征值