使用C/C++编译预处理时须要注意的问题
2015-04-02 19:05
429 查看
1、宏定义不是C/C++语句,不须要使用语句结束符“;”,否则它也被看做宏体的一部分。
2、不要在引用宏定义的參数列表中使用增量和减量运算符,否则将导致变量的多次求值。比如:
3、带參数的宏体和各个形參应分别用括号括起来,以免造成意想不到的错误。比如:
4、当不再使用某一个宏时,能够使用#undef来取消其定义,否则简单地删除宏定义会带来很多编译错误。
5、编译伪指令#error用于输出与平台、环境等有关的信息。比如:
当预处理器发现应用程序中未定义宏WIN32或者cplusplus时,把#error后面的字符序列输出到屏幕后即终止,程序不会进入编译阶段。
6、当须要临时放弃一段代码的时候,假设这段代码本身就含有块凝视时,使用块凝视屏蔽它就比較麻烦,此时可使用条件编译伪指令#if来屏蔽这段代码。比如:
注意:因为条件编译由编译预处理器来处理,显然预编译伪指令无法计算有变量參与当中的表达式或sizeof表达式,仅仅能用常量表达式。
7、编译伪指令#pragma用于运行语言实现所定义的动作,比如:
8、构串操作符#仅仅能修饰带參数的宏的形參,它将实參的字符序列(而不是实參代表的值)转换成字符串常量。比如:
注意:不管#s之间有多少个空格展开后都将忽略。
9、合并操作符##将出如今其左右的字符序列合并成一个新的标识符(注意,不是字符串)。比如:
注意:(1)C语言字符串中的两个相连的双引號会被自己主动忽略;(2)使用合并操作符时,产生的标识符必须预先有定义,否则编译器会报“标识符没有定义”的编译错误。
2、不要在引用宏定义的參数列表中使用增量和减量运算符,否则将导致变量的多次求值。比如:
#define SQUARE(x) ((x) * (x)) int n1 = 5; int m1 = SQUARE(n1++); //m1 = 25,n1 = 7 int n2 = 5; int m2 = SQUARE(++n2); //m2 = 49,n2 = 7
3、带參数的宏体和各个形參应分别用括号括起来,以免造成意想不到的错误。比如:
#define SQUARE(x) x * x int m = SQUARE(3 + 5); //将被扩展为m = 3 + 5 * 3 + 5
4、当不再使用某一个宏时,能够使用#undef来取消其定义,否则简单地删除宏定义会带来很多编译错误。
5、编译伪指令#error用于输出与平台、环境等有关的信息。比如:
#if !defined(WIN32) #error ERROR: Only Win32 Platform supported! #endif #ifndef _cplusplus #error ERROR: MFC requires C++ compilation! #endif
当预处理器发现应用程序中未定义宏WIN32或者cplusplus时,把#error后面的字符序列输出到屏幕后即终止,程序不会进入编译阶段。
6、当须要临时放弃一段代码的时候,假设这段代码本身就含有块凝视时,使用块凝视屏蔽它就比較麻烦,此时可使用条件编译伪指令#if来屏蔽这段代码。比如:
#if 0 …//希望屏蔽的代码 #endif
注意:因为条件编译由编译预处理器来处理,显然预编译伪指令无法计算有变量參与当中的表达式或sizeof表达式,仅仅能用常量表达式。
7、编译伪指令#pragma用于运行语言实现所定义的动作,比如:
#pragma pack(push, 8) /*对象成员对齐字节数*/ #pragma pack(pop) #pragma warning(disable:4069) /*不要产生第C4096号编译警告*/
8、构串操作符#仅仅能修饰带參数的宏的形參,它将实參的字符序列(而不是实參代表的值)转换成字符串常量。比如:
#define STRING(s) #s #s #s #define TEXT(s) "class" #s "Infor" int abc = 100; STRING(abc) //展开为abcabcabc TEXT(abc) //展开为classabcInfor
注意:不管#s之间有多少个空格展开后都将忽略。
9、合并操作符##将出如今其左右的字符序列合并成一个新的标识符(注意,不是字符串)。比如:
#include <stdio.h> #define paster( n ) printf( "token"#n" = %d\n", token##n ) int main(void) { int token9 = 100; paster(9); //输出token9 = 100 return 0; }
注意:(1)C语言字符串中的两个相连的双引號会被自己主动忽略;(2)使用合并操作符时,产生的标识符必须预先有定义,否则编译器会报“标识符没有定义”的编译错误。
相关文章推荐
- 使用C/C++编译预处理时需要注意的问题(宏相关问题)
- C++模板继承在g++编译中应注意的问题(if you use `-fpermissive', G++ will accept your code, but allowing the use ...)
- Linux下使用Eclipse编译C/C++代码时遇到问题的说明
- matlab文件编译成库在C++环境下使用遇到的问题记录
- C++中使用转换构造函数和运算符重载时需要注意的问题
- linux下使用c++访问mysql数据库编译问题
- 【问题汇总】在C/C++中使用Android Log导致编译失败的问题
- VS2013使用rtklib中需要注意的一些问题(编译)
- win7 64位下自行编译OpenCV2.4.10+CUDA toolkit 5.5的整个过程以及需要注意的问题(opencv+cuda并行计算元素的使用)
- c/c++ new与malloc的区别及使用时注意的问题
- 使用javac编译java文件和使用javah生成C/C++头文件 遇到找不到类的问题
- 【zz】c++编译,头文件使用问题
- ZYNQ开发板下使用ARM编译C++程序提示缺少库的问题
- c++编译,头文件使用问题
- #if和#ifdef使用问题&预处理命令之条件编译(#ifdef,#else,#endif,#if等)
- c++基础11:变量的命名约定 头文件的问题 程序的预处理编译链接过程
- C++在使用Qt中SLOT宏须要注意的一个小细节
- c++编译,头文件使用问题
- C/C++ 设计模式:关于使用typeid时要注意的问题
- Oracle使用并行建索引须要注意的问题