使用C/C++编译预处理时须要注意的问题

发表于:2015-4-07 09:50

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:zfyouxi    来源:51Testing软件测试网采编

  1、宏定义不是C/C++语句,不须要使用语句结束符“;”,否则它也被看做宏体的一部分。
  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)使用合并操作符时,产生的标识符必须预先有定义,否则编译器会报“标识符没有定义”的编译错误。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号