宏定义

原创 2016年06月02日 10:44:59

可以使用#define伪指令定义一个宏,宏分为带参数的宏和不带参数的宏。宏定义以#define关键字后面第一个出现的第一个连续字符序列作为宏,剩下的部分作为宏体。宏定义具有文件作用域,不论宏定义出现在文件中的那个地方(如函数体内,类型定义内部,名字空间内部等),在它后面的任何地方都可以引用宏。

宏的特点和注意事项:

(1)宏定义的不是语句,因此不需要使用语句结束符“;”,否则它会被看做宏的一部分。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define WRITE(x,y) (x+y)
int main()
{
	WRITE(2, 3);
	printf("%d\n", WRITE(2, 3));
	system("pause");
	return 0;
}

(2)任何宏在编译预处理阶段都只是进行简单的文本替换,不做类型检查和语法检查,这个工作留个编译器进行。参数替换法生在宏扩展之前。

(3)宏可以嵌套定义。

#define PI 3.14
#define PI_2 (2*PI)

(4)宏不可以调试,因为宏不会进入符号表(符号表是编译器创建的,在编译时宏已经消失了),即使宏替换后出现了语法错误,编译器也会将错误定位在源程序中而不是定位到具体的某个宏定义中。

(5)程序里使用双引号括起来的字符串中即使出现了与宏同名的子串,预处理过程也不进行替换。

(6)定义带参数的宏时,宏名和左括号之间不能出现空格,否则使用时会出现问题,但是编译器不会检查出这种错误。

错误的:

#define TEXT (str)#str

宏引用:

TEXT(hello bit);

扩展为:

(str)#str(hello bit);

正确的:

#define TEXT(str) #str

(7)带参数的宏和各个参数应该分别用括号括起来,以免造成意想不到的错误。

应该写成这样:

#define ADD(x) ((x)+(x))

如果写成:

#define MPLIT(x) x*x

就极有可能因为运算优先级的问题造成错误。语句:

a=MPLIT(3+5);

将被扩展为:

a=3*5+3*5;

很明显出现了错误!

注意:在定义宏的过程中千万不要吝啬括号。

(8)不要在引用宏定义的参数列表中使用自增和自减运算符,否则可能导致变量多次求值,其结果可能与预期不符,因为复合表达式中的求值顺序可能因为编译器的不同而不同。例如:

int n=5;
int w=MPLIT(n++);

其结果可能是25,也可能是30。

(9)带参数的宏并不是函数,因此没有函数调用的开销,但是其每一次扩展都会生成重复的代码,结果使可执行程序的代码体积增大。

(10)当我们不在使用某一个宏时,可以使用#undef来取消其定义,例如:

#undef MPLIT

否则简单的删除宏定义,会带来许多编译的错误。

本文出自 “Stand out or Get out” 博客,请务必保留此出处http://jiazhenzhen.blog.51cto.com/10781724/1712803

版权声明:

相关文章推荐

sourceInsight宏定义

  • 2017-01-11 08:55
  • 251KB
  • 下载

C语言中的宏定义

  • 2015-03-08 00:23
  • 757KB
  • 下载

const常量与define宏定义的区别

原文链接:http://www.examw.com/biancheng/c/199269/ 1) 编译器处理方式不同   define宏是在预处理阶段展开。   const常量是编译运行阶段使用...

宏定义使用技巧2

  • 2012-05-05 09:39
  • 74KB
  • 下载

c++中得内联函数和宏定义

在c++中内联函数是对宏定义一种改造,因为利用内联函数取代宏定义得好处是:  1、可进行类型安全检查或自动类型转换、   例如:在c语言中,常用预处理器语句#define来代替一个函数定义。例如:  ...

宏定义define使用整理

  • 2014-04-01 13:08
  • 71KB
  • 下载

iOS 视图约束常用的宏定义

#pragma mark - Constraints /* *自适应向布局约束的转化关闭 */ #define PREPCONSTRAINTS(VIEW) [VIEW setTranslatesA...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)