预定义宏,C语言预定义的宏详解
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 所示。

图 4- 其中,\__FILE__、__LINE__与\__FUNCTION__(或者\__func__)预定义宏分别表示文件名、行数与函数名,这样就可以帮助我们精确地定位出现异常的文件、行数与函数名。运行结果如图 4 所示。
预定义宏,C语言预定义的宏详解的更多相关文章
- visual c++中预定义的宏
一.主要目标 (由于visual studio通常包含很多开发环境,通常将其中c/c++的ide称为visual c++ 20xx) 整理下visual c++ 2010下预定义的宏.做一下备忘和了解 ...
- VS2013 预定义的宏
Visual Studio 2013 预定义的宏 https://msdn.microsoft.com/zh-cn/library/b0084kay(v=vs.120).aspx 列出预定义的 ANS ...
- C标准中一些预定义的宏
C标准中指定了一些预定义的宏,对于编程经常会用到.下面这个表中就是一些常常用到的预定义宏. 宏(双下滑线) 意义 __DATE__ 进行预处理的日期(“Mmm dd yyyy”形式的字符串文字) __ ...
- C标准中一些预定义的宏,如__FILE__,__func__等
C标准中一些预定义的宏 C标准中指定了一些预定义的宏,对于编程经常会用到.下面这个表中就是一些常常用到的预定义宏. 宏 意义 __DATE__ 进行预处理的日期(“Mmm dd yyyy”形式的字符串 ...
- 2019-8-31-dotnet-新项目格式与对应框架预定义的宏
title author date CreateTime categories dotnet 新项目格式与对应框架预定义的宏 lindexi 2019-08-31 16:55:58 +0800 201 ...
- dotnet 新项目格式与对应框架预定义的宏
在 sdk style 的项目格式支持使用多框架开发,此时需要在代码里面通过宏判断,在编译的时候执行不同的代码.本文告诉大家在框架里面对应的预定义的条件编译符有哪些 在让一个 csproj 项目指定多 ...
- gcc中预定义的宏__GNUC__
转载:gcc中预定义的宏__GNUC__ - Cccarl - 博客园 (cnblogs.com) 今天在看Linux系统编程这本书的代码的时候看到了__GNUC__,不太清楚这个宏所以去查了一下,以 ...
- ARM编译器中预定义的宏
arm系列目前支持三大主流的工具链,realview的armcc,iar ewarm的iccarm,gnu的gcc,编译器在编译的时候会预定义一些宏,这些宏在工程中起到不可或缺的作用. 例如 /* d ...
- Go语言Slice作为函数参数详解
Go语言Slice作为函数参数详解 前言 首先要明确Go语言中实质只有值传递,引用传递和指针传递是相对于参数类型来说. 个人认为上诉的结论不对,把引用类型看做对指针的封装,一般封装为结构体,结构体是值 ...
随机推荐
- PHP文件操作(二)-文件的读取
1.fread() //读取打开的文件 fread(file,length) file:必选项,规定要读取的打开的文件 length:必选项,规定要读取的最大字节数. <?php $fil ...
- phpStudy启动失败时的解决方法 提示缺vc9运行库
问题描述: 问题产生原因分析: php5.3.5.4和apache都是用vc9编译,电脑必须安装vc9运行库才能运行. php5.5.5.6是vc11编译,如用php5.5.5.6必须安装vc11运行 ...
- 前端自动化之nvm安装
nvm ——node环境版本控制工具. 1.解压安装包 2.打开setting文件,修改文件内容 root: D:\node\nvm path: D:\node\nodejs arch: proxy: ...
- requirejs——define——普通模块
一.普通模块可能包含的内容: 一个模块对应着一个js文件,由于模块可能包含着以下三种内容:模块名.依赖模块.返回给其他模块使用的参数:因此js文件根据包含内容的不同而写法不同. 一.传统的js脚本文件 ...
- 循序渐进Python3(十三) --1-- django之form表单
在上一次的代码上做出进一步修改,使之能在页面上显示报错信息. views.py from django.shortcuts import render, HttpResponse from djang ...
- PyInstaller打包成exe可执行文件
PyInstaller 安装pyinstaller 对于那些网络比较稳定,能够流畅使用pip源地址的用户,直接下面的命令就可以搞定: pip install pyinstaller 通常我们会下载源码 ...
- Hadoop Serialization -- hadoop序列化详解 (2)
回顾: 回顾序列化,其实原书的结构很清晰,我截图给出书中的章节结构: 序列化最主要的,最底层的是实现writable接口,wiritable规定读和写的游戏规则 (void write(DataOut ...
- 使用axis2进行WebService的开发
使用axis2进行WebService的开发 Apache Axis2 是 Apache Axis SOAP 项目的后继项目.此项目是 Web 服务核心引擎的重要改进,目标是成为 Web 服务和面向服 ...
- spark 中文编码处理
日志的格式是GBK编码的,而hadoop上的编码是用UTF-8写死的,导致最终输出乱码. 研究了下Java的编码问题. 网上其实对spark输入文件是GBK编码有现成的解决方案,具体代码如下 impo ...
- Spring总结一:Srping快速入门
Sping是什么: Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring是于2003 年兴起的一个轻量级的J ...