使用C/C++编译预处理时须要注意的问题
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)使用合并操作符时,产生的标识符必须预先有定义,否则编译器会报“标识符没有定义”的编译错误。
使用C/C++编译预处理时须要注意的问题的更多相关文章
- Verilog学习笔记基本语法篇(十二)········ 编译预处理
h Verilog HDL语言和C语言一样也提供编译预处理的功能.在Verilog中为了和一般的语句相区别,这些预处理语句以符号"`"开头,注意,这个字符位于主键盘的左上角,其对应 ...
- C预编译, 预处理, C/C++头文件, 编译控制,
在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...
- c语言编译预处理和条件编译执行过程的理解
在C语言的程序中可包括各种以符号#开头的编译指令,这些指令称为预处理命令.预处理命令属于C语言编译器,而不是C语言的组成部分.通过预处理命令可扩展C语言程序设计的环境. 一.预处理的工作方式 1.1. ...
- 如何在编译内核时添加缺少的固件(随着intel wireless 5100 AGN的 iwlwifi 案例)
我不知道你在笔记本使用 Linux 在内核编译无线wifi 不能用.我的书"关联 Y450"一个足够的旧书,随着无线网卡: $ lspci | grep Wireless 06:0 ...
- C++的编译预处理
C++中,在编译器对源程序进行编译之前,首先要由预处理对程序文本进行预处理.预处理器提供了一组预编译处理指令和预处理操作符.预处理指令实际上不是C++语言的一部分,它只是用来扩充C++程序设计的环境. ...
- C语言条件编译及编译预处理阶段(转)
一.C语言由源代码生成的各阶段如下: C源程序->编译预处理->编译->优化程序->汇编程序->链接程序->可执行文件 其中 编译预处理阶段,读取c源程序,对其中的 ...
- VerilogHDL编译预处理
编译预处理语句 编译预处理是VerilogHDL编译系统的一个组成部分,指编译系统会对一些特殊命令进行预处理,然后将预处理结果和源程序一起在进行通常的编译处理.以”`” (反引号)开始的某些标识符是编 ...
- 【转】C语言条件编译及编译预处理阶段
原文: http://www.cnblogs.com/rusty/archive/2011/03/27/1996806.html 1. 宏定义(宏代换,宏替换,宏: 宏定义是C语言提供的3中预处理功能 ...
- C++——多文件结构和编译预处理命令
[toc] 一.多文件结构 1.一个工程可以划分为多个源文件 类声明文件(.h文件) 类实现文件(.cpp文件) 类的使用文件(main函数所在的.cpp文件) 2.利用工程来组合各个文件 //Poi ...
随机推荐
- android旋转动画和平移动画具体解释,补充说一下假设制作gif动画放到csdn博客上
先上效果图: 我这里用的是GifCam来制作的gif动画,能够在http://download.csdn.net/detail/baidu_nod/7628461下载, 制作过程是先起一个模拟器,然后 ...
- UIApplicationsharedApplication的常用使用方法
下面是这个类的一些功能: 1.设置icon上的数字图标 //设置主界面icon上的数字图标,在2.0中引进, 缺省为0 [UIApplicationsharedApplication].applica ...
- hdu4336压缩率大方的状态DP
Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- 深入浅出KnockoutJS
深入浅出KnockoutJS 写在前面,本文资料大多来源网上,属于自己的学习笔记整理. 其中主要内容来自learn.knockoutjs.com,源码解析部分资料来自司徒正美博文<knockou ...
- eclipse 重构(转)
Eclipse中的重构类型 如果你看一下Eclipse的重构菜单,可以看到四部分.第一部分是撤销和重做.其他的三部分包含Eclipse提供的三种类型的重构. 第一种类型的重构改变代码的物 ...
- C++0x新特性
我是在一个帖子上摘抄的大神语录...感谢supermegaboy大神,给了详尽的解释 下文是一篇转载的Wikipedia的译文,从语言和库双方面概述了C++0x. 右值引用与转移语义 在标准C++语言 ...
- ZOJ--3631--Watashi's BG【枚举】
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4777 题意:有n天,告诉你每天的花费,别人给你一笔资金m,你自己也有一部 ...
- hadoop调度程序时出现“Error opening job jar”错误
提示出现的问题: Exception in thread "main" java.io.IOException: Error opening job jar: /home/depl ...
- Red Gate系列之五 .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程
原文:Red Gate系列之五 .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程 Red Gate ...
- Java 并发专题 : CyclicBarrier 打造一个安全的门禁系统
继续并发专题~ 这次介绍CyclicBarrier:看一眼API的注释: /** * A synchronization aid that allows a set of threads to all ...