`
rys5851968
  • 浏览: 155797 次
社区版块
存档分类
最新评论

关于宏#define使用陷阱总结

 
阅读更多

宏定义发生在预编译阶段,简单的说本质就是文本替换。使用时,有以下注意事项:

1,用宏定义表达式时,要使用完备的括号

如一下三个例子:

#define ADD(a,b) a+b

#define ADD(a, b) (a + b)

#define ADD(a, b) (a) +(b)

这三种定义,全部都是不符合要求的。陷阱如下:

在计算ADD(a,b)*ADD(c,d)时,显然第一种出问题了。

#define MULTIPLE(a, b) (a*b) 在计算(a+b)*c时,调用MULTIPLE(a+b,c)得到的结果错误。

因此一定要使用完备的括号,如下示例:

#define ADD(a,b) ((a) + (b))

2,使用宏定义,不允许参数发生变化,这也就是带参数的宏定义和函数的区别:

如下测试源码:

#include <stdio.h>
#define sqrt(a) ((a)*(a))
int fsqrt(int a)
{
	return a*a;
}
int main()
{
	
	int a = 10, b = 10;
	int r1, r2;
	 r1 = sqrt(a++);
	 r2 = fsqrt(b++);
	printf("a = %d, b = %d, r1 = %d, r2 = %d\n", a, b, r1, r2);
	return 0;
}


最终的结果是a = 12; b = 11; r1 = 100; r2 = 100; 以上结果在vc6.0下获得。之所以a变成12,是因为在替换的时候,a++被执行了两次。要避免这种行为,就要使宏参数不发生变化。

如:a++; r1 = sqrt(a), 一切就ok了!

3,使用大括号将宏定义包含的多条表达式括起来。

如下示例:

#include <stdio.h>
#define INITIAL(a, b)\
	a = 0;\
	b = 0;
int main()
{
	
	int a[5], b[5] ;
	int i;
	for(i=0; i<5; i++)
	INITIAL(a[i], b[i]);

	printf("a = %d, b = %d\n", a[0], b[0]);
	return 0;
}


结果打印a是正常的,但打印b却是未初始化的结果。因为简单的文本替换,不能保证多条表达式都放到for循环体内。(这里,如果单独初始化一个变量,没有for循环时没有问题的。)上述的宏定义应改为:

#define INITIAL(a, b)\
	{\
    a = 0;\
	b = 0;\
	}


注意这个“\”号哦,表示下面的一行和当前行在预编译时被认为在同一行。

最后,再简单对比下#define和 typedef的区别,#define发生在预编译阶段, typedef发生在编译阶段,可参考http://topic.csdn.net/t/20030810/14/2129718.html。更多细节上的区别,稍后再谈。

不对之处,大家多指正。

分享到:
评论

相关推荐

    #define 问题 用法陷阱

    然而,`#define`的不当使用可能会引入一系列的问题和陷阱,本文将深入探讨这些陷阱及其解决方法。 #### 宏定义陷阱 ##### 1. 括号的重要性 当定义一个宏时,如果不正确地使用括号,可能会导致意想不到的结果。...

    #define的使用技巧

    在C语言中,宏定义是使用预处理器指令#define实现的一种编译前文本替换机制。它在编译之前处理源代码,使得可以定义常量、实现内联函数以及防止头文件被重复包含等多种功能。下面详细说明标题和描述中提到的知识点。...

    【C/C++】#ifndef,#define用法

    C/C++ 中 #ifndef 和 #define 的用法 #ifndef 和 #define 是 C 语言中的两个重要命令,它们在实际编程中扮演着重要角色。#ifndef 命令用来判断一个宏是否已经定义,而 #define 命令则用来定义一个宏。下面我们将...

    const #define inline

    在编程领域,`const`、`#define`与`inline`是三个常用的关键字或预处理器指令,它们各自具有独特的作用和使用场景,掌握它们的区别和正确应用是提升代码质量和效率的重要手段。 #### 1. `const`关键字 `const`...

    #define和typedef的使用

    ### #define 的使用及其特性 #### 一、无参宏定义 无参宏定义是最基本的一种宏定义形式,主要用于简化代码书写或者定义常量。其一般形式为:`#define 宏名 字符串`。 - **举例**: ```c #define PI 3.1415926 `...

    简单实现贪吃蛇游戏源代码

    #define MAXLEN 201 #define LEN 1 #define SPEED1 50 #define SPEED2 100 #define SPEED3 200 #define FOOD1_S1 5 #define FOOD1_S2 10 #define FOOD1_S3 15 #define FOOD2_S1 10 #define FOOD2_S2 20 #define FOOD...

    宏(#define)定义函数妙用

    例如,`SUM(a + b, c + d)` 使用宏 `#define SUM(x, y) x + y` 会被错误地展开为 `a + b + c + d`,而不是 `(a + b) + (c + d)`。为了避免这种情况,通常需要在宏定义中加入额外的括号。 此外,宏定义不支持重载,...

    #ifndef #define #endif的用法

    ### #ifndef #define #endif 的使用详解 #### 一、预处理指令简介 在深入讨论 `#ifndef`, `#define`, `#endif` 这三个预处理指令之前,我们需要先了解预处理指令的基本概念。 **预处理指令** 是 C/C++ 编程语言中...

    宏定义#define用法总结

    C语言中宏定义#define用法总结 在 C 语言中,宏定义(#define)是一种非常重要的预处理器指令,它可以让我们在编译前对代码进行修改和扩展。本文将对宏定义的用法进行总结,包括简单的宏定义、带参数的宏、宏的特殊...

    预编译器——#include和#define的实现

    在编程世界中,预编译器是程序开发过程中的一个重要环节,它负责处理源代码中的特定指令,如`#include`和`#define`。这些指令在实际编译之前进行处理,以帮助简化和优化源代码。让我们深入探讨一下`#include`和`#...

    #define——用法大全

    使用 #define 指令可以定义一个简单的常量,例如: ```c #define MAXTIME 1000 ``` 这样,在程序中使用 `MAXTIME` 时,将被替换为 `1000`。 ### 2. define 的“函数定义” define 还可以像函数那样接受一些参数...

    #define 宏定义的一些用法总结

    ### #define宏定义的一些用法总结 #### 一、引言 在C及C++编程中,`#define`是一个非常强大的预处理器指令,用于创建宏。宏可以在编译前阶段替代代码片段,提高代码的复用性与可维护性。本文将详细探讨`#define`的...

    单片机-#define XBYTE ((unsigned char volatile xdata *) 0)

    在单片机编程中,尤其是在使用C51语言进行编程时,为了能够有效地访问不同存储空间的数据,通常会使用一系列宏定义来辅助开发工作。本文将围绕宏定义`#define XBYTE ((unsigned char volatile xdata *) 0)`展开,...

    #define用法集锦.doc

    在编写代码时,应尽量遵循良好的编程实践,例如使用`const`代替无类型的`#define`常量,使用函数代替宏来实现复杂的逻辑,以及正确处理头文件的包含以避免重复定义。理解并正确使用`#define`,能提高代码的可读性...

    #indef 与#define 区别于用法

    ### #ifndef 与 #define 的区别及用法详解 #### 一、概述 ...通过上述讨论可以看出,正确地使用 `#ifndef` 和 `#define` 可以有效地避免重复定义的问题,同时利用条件编译可以使代码更加灵活和高效。

    C++/C 宏定义(define)中# ## 的含义

    ### C++/C宏定义(define)中#与##的含义及应用 #### 一、引言 在C++和C语言中,预处理器指令`#define`被广泛用于定义宏,这些宏可以包含简单的替换文本,也可以进行复杂的条件判断和参数处理。本文将详细介绍宏...

    #define VS typedef

    一般来说,如果我们需要定义一个常量或宏语句,应该使用 #define,而如果我们需要定义一个关键字或冗长的类型的别名,应该使用 typedef。 最后,让我们来看一下一些示例。例如:`typedef (int*) pINT;` 和 `#define...

    C语言中const与#define的区别

    在总结const和#define的区别时,我们应该清楚地认识到,虽然它们都可以用来定义常量,但它们在性能、类型安全和使用方式等方面都有显著的不同。正确地掌握和使用这些区别,对于编写高质量的C语言代码是十分必要的。

    136.#define 定义常量.pdf

    这种替换发生在编译之前的预处理阶段,因此,使用#define 定义的宏或常量不会占用任何运行时内存空间。 #define 的基本语法是:#define 标识符 替换文本。在定义标识符时,通常不需要在替换文本的末尾添加分号。这...

    define应用

    ### 宏#define命令练习知识点详解 #### 一、宏#define命令基本概念 宏定义是C语言中的一个预处理指令,其格式为`#define 标识符 值`或`#define 标识符(参数列表) 替换文本`。通过宏定义可以为程序中的常量、表达式...

Global site tag (gtag.js) - Google Analytics