使用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 ...
随机推荐
- 在配置文件(.settings、.config)中存储自定义对象
原文:在配置文件(.settings..config)中存储自定义对象 引言 我前面曾写过一篇<使用配置文件(.settings..config)存储应用程序配置>,我在其中指出“sett ...
- Windows Phone开发(27):隔离存储A
原文:Windows Phone开发(27):隔离存储A 在很多资料或书籍上都翻译为"独立存储",不过,我想了一下,决定将IsolatedStorage翻译为"隔离存储& ...
- ftk学习记(消息框篇)
[ 声明:版权全部,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 上一篇说到了输入框.闲话不多说,首先看结果显示, 大家看看效果是不是和我们之前说的一样.今天, ...
- 工作经常使用的SQL整理,实战篇(三)
原文:工作经常使用的SQL整理,实战篇(三) 工作经常使用的SQL整理,实战篇,地址一览: 工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实 ...
- Effective C++:规定20: 宁pass-by-reference-to-const更换pass-by-value
(一) 假设传递参数当函数被调用pass-by-value,然后函数的参数是基于实际参数的副本最初值,调用,也得到该函数返回的结束值复印件. 请看下面的代码: class Person { publi ...
- fedora linux平台下搭建lighttpd+php+sqlite
(一)lighttpd 1. 安装 yum install lighttpd 安装完毕后,系统中应该多了一个用户lighttpd和组lighttpd.这个用户,默认是不同意登陆的. 我们改动/etc/ ...
- 使用2DToolkit报错“ OverflowException: Value is too large”
今天使用2DToolkit做图集和动画时报错“ OverflowException: Value is too large”,大侠们说是字符串转整型时超过了Int的大小范围,所以报错.后来我一位同事高 ...
- UBUNTU12.04下安装配置体验gnome3
年. ubuntu12.04默认采用unity界面,但是自己更加喜欢gnome3的操作方式. 安装gnome3: sudo apt-get install gnome-shell 其实安装成功后,注 ...
- 阿里游戏大数据sesson2_RF&GBRT(上)
----------一个小的游戏体验,对于不太熟悉Xlab RF和GBRT同学们都叫参考,不喜勿喷,大神绕道,米姆达. . .. .---------- 6月初的时候LR 做到4.9后一直上不去,看群 ...
- ** poj Y2K Accounting Bug 2586
Y2K Accounting Bug Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10117 Accepted: 50 ...