关于C语言中的预定义

本文介绍了C语言中的预定义宏,通过解析VC中的mbctype.H头文件,展示了预定义宏在MBCS字符转换中的应用。文章涵盖了_MSC_VER等编译器版本宏,以及_ismbbkalnum、_ismbbkana等MBCS字符分类函数,帮助读者深入了解C语言的预定义特性。

今天无意中学习到了很多东西,其实以前也了解,但是没怎么当回事,今天重新学了一边,感觉收获颇丰,总结一下吧。

 

起源于我打开了VC中的mbctype.H这个头文件,一段宏转换代码,如果你能一次全看懂,OK,你的C语言功力是相当深厚了,下面的文字也可以跳过了,可以说这个文件是相当经典的预定义的范例了,下面注释如下。

 

/***
*mbctype.h - MBCS character conversion macros
*
*       Copyright (c) Microsoft Corporation.  All rights reserved.
*
*Purpose:
*       Defines macros for MBCS character classification/conversion.
*
*       [Public]
*
****/

#if     _MSC_VER > 1000 

/*判断编译器的版本

  MS VC++ 9.0 _MSC_VER = 1500

  MS VC++ 8.0 _MSC_VER = 1400

  MS VC++ 7.1 _MSC_VER = 1310

  MS VC++ 7.0 _MSC_VER = 1300

  MS VC++ 6.0 _MSC_VER = 1200

  MS VC++ 5.0 _MSC_VER = 1100

  其中MS VC++ 9.0就是Visual C++ 2008,MS VC++ 8.0就是Visual C++ 2005。

也就是说4.0以上的才支持下面这个命令

*/
#pragma once</

### 预定义宏的概念与作用 在C语言中,预定义宏是由编译器预先定义的一组宏,它们通常用于提供与编译环境相关的信息,例如文件名、行号、编译时间等。这些宏在编译预处理阶段展开,并且在程序运行之前就已经被处理完毕。例如,`__LINE__` 表示当前代码的行号,`__FILE__` 表示当前源文件的名称,`__DATE__` 和 `__TIME__` 分别表示编译时的日期和时间[^2]。以下是一个使用预定义宏的示例: ```c #include <stdio.h> int main() { printf("当前文件名: %s\n", __FILE__); printf("当前行号: %d\n", __LINE__); printf("编译日期: %s\n", __DATE__); printf("编译时间: %s\n", __TIME__); return 0; } ``` 上述代码在运行时会输出当前文件的名称、行号、编译日期和时间,这些信息对于调试和日志记录非常有用。 ### 预定义宏的典型应用场景 预定义宏不仅用于调试和日志记录,还可以用于条件编译。例如,`__STDC__` 宏在程序使用标准C编译时被定义为1,否则未定义。这使得程序可以根据编译器是否支持标准C来选择性地启用某些功能: ```c #ifdef __STDC__ printf("使用标准C编译\n"); #else printf("未使用标准C编译\n"); #endif ``` 此外,现代C标准(如C99、C11)中引入了更多预定义宏,例如 `_Pragma` 关键字,它允许在宏中使用 `#pragma` 指令,从而实现更复杂的编译器控制功能。 ### 预定义关键字与宏定义的区别 虽然预定义宏是由编译器自动定义的,但用户也可以通过 `#define` 指令定义自己的宏。宏定义是C/C++语言预处理功能的一部分,它允许程序员用一个简单的标识符替换一段复杂的代码或常量。例如,定义一个表示圆周率的宏: ```c #define PI 3.14 ``` 在代码中使用 `PI` 时,预处理器会将其替换为 `3.14`。这种宏定义在数组定义中也非常有用,例如: ```c #define ARRAY_SIZE 10 int arr[ARRAY_SIZE]; ``` 这种方式使得数组大小可以通过修改宏定义来调整,而不需要手动修改每一处数组声明。需要注意的是,宏定义不是真正的常量,而是简单的文本替换,因此在某些编译器中可能不支持使用 `const` 修饰的变量作为数组大小,而必须使用宏定义[^4]。 ### 预定义宏与关键字的扩展性 C语言预定义宏和关键字在现代标准中得到了扩展。例如,C99和C11标准引入了 `_Pragma` 关键字,它允许在宏中使用 `#pragma` 指令,从而实现更灵活的编译器行为控制。这种扩展使得宏定义不仅仅局限于简单的常量替换,还可以用于控制编译器的行为,例如优化级别或警告信息的启用与禁用。 ```c #define PRAGMA_WARN_DISABLE _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") PRAGMA_WARN_DISABLE ``` 上述代码使用 `_Pragma` 来禁用未使用变量的警告信息,从而避免编译时的冗余输出。 ### 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值