mysql的预定义语句_预定义宏,C语言预定义的宏详解

对于预定义宏,相信大家并不陌生。为了方便处理一些有用的信息,预处理器定义了一些预处理标识符,也就是预定义宏。预定义宏的名称都是以“__”(两条下划线)开头和结尾的,如果宏名是由两个单词组成,那么中间以“_”(一条下划线)进行连接。并且,宏名称一般都由大写字符组成。

在日常项目编程中,预定义宏尤其对多目标平台代码的编写通常具有重大意义。通过预定义宏,程序员使用“#ifdef”与“#endif”等预处理指令,就可使平台相关代码只在适合于当前平台的代码上编译,从而在同一套代码中完成对多平台的支持。从这个意义上讲,平台信息相关的宏越丰富,代码的多平台支持越准确。

标准 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标准及其指定年月的修订补充,否则该宏为未定义

除标准 C 语言提供的标准宏之外,各种编译器也都提供了自己的自定义预定义宏。可以通过表 2 所示的指令来查看不同编译器对预定义宏的支持情况。

表 2 不同编译器的预定义宏查看指令

编译器

宏指令(c)

宏指令(C++)

Clang/LLVM

clang -dM -E -x c /dev/null

clang++ -dM -E -x C++ /dev/null

GNU GCC/G++

gcc -dM -E -x c /dev/null

g++ -dM -E -x C++ /dev/null

Hewlett-Packard C/aC++

cc -dM -E -x c /clev/null

aCC -dM -E -x C++ /dev/null

IBM XL C/C++

xlc -qshowmacros -E /dev/null

xlc++ -qshowmacros -E /dev/null

Intel ICC7ICPC

icc -dM -E -x c /dev/null

icpc -dM -E -x C++ /dev/null

Oracle Solaris Studio

cc -xduinpmacros -E /dev/null

CC -xduinpmacros -E /clev/null

Portland Group PGCC/PGCPP

pgcc -dM -E

图 3 显示了 GCC 编译器预定义宏的查看结果。虽然各种编译器的预定义宏不尽相同,但是一般都会支持“__DATE__、__FILE__、__LINE__与__TIME__”这 4 种预定义宏。

ad14a3520d356ebd3240f4acfd88d877.png

图 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

#include

#include

#include

#include

#include

#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 所示。

f74fc80ae02cb82746e48c843df71ec4.png

图 4

最后还需要注意的是,如果用户重定义“#define“或取消了“#undef”预定义宏,那么其结果是“未定义”的。因此,在代码编写中,应该尽量避免自定义宏与预定义宏名称相同的情况发生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值