宏定义发生在预编译阶段,简单的说本质就是文本替换。使用时,有以下注意事项:
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`的不当使用可能会引入一系列的问题和陷阱,本文将深入探讨这些陷阱及其解决方法。 #### 宏定义陷阱 ##### 1. 括号的重要性 当定义一个宏时,如果不正确地使用括号,可能会导致意想不到的结果。...
在C语言中,宏定义是使用预处理器指令#define实现的一种编译前文本替换机制。它在编译之前处理源代码,使得可以定义常量、实现内联函数以及防止头文件被重复包含等多种功能。下面详细说明标题和描述中提到的知识点。...
C/C++ 中 #ifndef 和 #define 的用法 #ifndef 和 #define 是 C 语言中的两个重要命令,它们在实际编程中扮演着重要角色。#ifndef 命令用来判断一个宏是否已经定义,而 #define 命令则用来定义一个宏。下面我们将...
在编程领域,`const`、`#define`与`inline`是三个常用的关键字或预处理器指令,它们各自具有独特的作用和使用场景,掌握它们的区别和正确应用是提升代码质量和效率的重要手段。 #### 1. `const`关键字 `const`...
### #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...
例如,`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` 这三个预处理指令之前,我们需要先了解预处理指令的基本概念。 **预处理指令** 是 C/C++ 编程语言中...
C语言中宏定义#define用法总结 在 C 语言中,宏定义(#define)是一种非常重要的预处理器指令,它可以让我们在编译前对代码进行修改和扩展。本文将对宏定义的用法进行总结,包括简单的宏定义、带参数的宏、宏的特殊...
在编程世界中,预编译器是程序开发过程中的一个重要环节,它负责处理源代码中的特定指令,如`#include`和`#define`。这些指令在实际编译之前进行处理,以帮助简化和优化源代码。让我们深入探讨一下`#include`和`#...
使用 #define 指令可以定义一个简单的常量,例如: ```c #define MAXTIME 1000 ``` 这样,在程序中使用 `MAXTIME` 时,将被替换为 `1000`。 ### 2. define 的“函数定义” define 还可以像函数那样接受一些参数...
### #define宏定义的一些用法总结 #### 一、引言 在C及C++编程中,`#define`是一个非常强大的预处理器指令,用于创建宏。宏可以在编译前阶段替代代码片段,提高代码的复用性与可维护性。本文将详细探讨`#define`的...
在单片机编程中,尤其是在使用C51语言进行编程时,为了能够有效地访问不同存储空间的数据,通常会使用一系列宏定义来辅助开发工作。本文将围绕宏定义`#define XBYTE ((unsigned char volatile xdata *) 0)`展开,...
在编写代码时,应尽量遵循良好的编程实践,例如使用`const`代替无类型的`#define`常量,使用函数代替宏来实现复杂的逻辑,以及正确处理头文件的包含以避免重复定义。理解并正确使用`#define`,能提高代码的可读性...
### #ifndef 与 #define 的区别及用法详解 #### 一、概述 ...通过上述讨论可以看出,正确地使用 `#ifndef` 和 `#define` 可以有效地避免重复定义的问题,同时利用条件编译可以使代码更加灵活和高效。
### C++/C宏定义(define)中#与##的含义及应用 #### 一、引言 在C++和C语言中,预处理器指令`#define`被广泛用于定义宏,这些宏可以包含简单的替换文本,也可以进行复杂的条件判断和参数处理。本文将详细介绍宏...
一般来说,如果我们需要定义一个常量或宏语句,应该使用 #define,而如果我们需要定义一个关键字或冗长的类型的别名,应该使用 typedef。 最后,让我们来看一下一些示例。例如:`typedef (int*) pINT;` 和 `#define...
在总结const和#define的区别时,我们应该清楚地认识到,虽然它们都可以用来定义常量,但它们在性能、类型安全和使用方式等方面都有显著的不同。正确地掌握和使用这些区别,对于编写高质量的C语言代码是十分必要的。
这种替换发生在编译之前的预处理阶段,因此,使用#define 定义的宏或常量不会占用任何运行时内存空间。 #define 的基本语法是:#define 标识符 替换文本。在定义标识符时,通常不需要在替换文本的末尾添加分号。这...
### 宏#define命令练习知识点详解 #### 一、宏#define命令基本概念 宏定义是C语言中的一个预处理指令,其格式为`#define 标识符 值`或`#define 标识符(参数列表) 替换文本`。通过宏定义可以为程序中的常量、表达式...