#define SQ(y) (y)*(y)
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=SQ(a+1);
printf("sq=%d\n",sq);
}
上例中第一行为宏定义,形参为y。程序第七行宏调用中实参为a+1,是一个表达式,在宏展开时,用a+1代换y,再用(y)*(y) 代换SQ,得到如下语句:
sq=(a+1)*(a+1);
这与函数的调用是不同的,函数调用时要把实参表达式的值求出来再赋予形参。而宏代换中对实参表达式不作计算直接地照原样代换。
#define SQ(y) y*y
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=SQ(a+1);
printf("sq=%d\n",sq);
}
运行结果为:
input a number:3
sq=7
同样输入3,但结果却是不一样的。问题在哪里呢? 这是由于代换只作符号代换而不作其它处理而造成的。宏代换后将得到以下语句:
sq=a+1*a+1;
由于a为3故sq的值为7。
#define SQ(y) (y)*(y)
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=160/SQ(a+1);
printf("sq=%d\n",sq);
}
本程序与前例相比,只把宏调用语句改为:
sq=160/SQ(a+1);
运行本程序如输入值仍为3时,希望结果为10。但实际运行的结果如下:
input a number:3
sq=160
为什么会得这样的结果呢?分析宏调用语句,在宏代换之后变为:
sq=160/(a+1)*(a+1);
a为3时,由于“/”和“*”运算符优先级和结合性相同,则先作160/(3+1)得40,再作40*(3+1)最后得160。为了得到正确答案应在宏定义中的整个字符串外加括号,程序修改如下:
#define SQ(y) ((y)*(y))
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=160/SQ(a+1);
printf("sq=%d\n",sq);
}
或者
#define SQ(y) ((y)*(y))
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=160/(SQ(a+1));
printf("sq=%d\n",sq);
}
分享到:
相关推荐
让我们通过一个具体的例子来详细了解带参数宏定义的工作原理。 ##### 示例1:计算一个数的平方 ```c #define SQ(y) (y)*(y) int main() { int a = 5; int sq = SQ(a); printf("The square of %d is %d\n", a, ...
- **带括号的参数**:为避免宏展开过程中出现意外,建议为宏参数加上括号,例如: ```c++ #define LOG(format,...) printf(format, __VA_ARGS__) LOG("%s%d", str, count); ``` 这里使用了变长参数`__VA_ARGS_...
从提供的压缩包文件名称来看,有四个`.c`文件(宏定义带参数的1.c、宏定义带参数的.c、宏定义带参数的2.c、宏定义带参数的3.c),这些文件很可能包含了不同的宏定义示例或者对上述`MAX`宏的使用。通过查看这些文件,...
标题"带参数的宏定义.zip"和描述"带参数的宏定义"表明这个压缩包文件包含了关于如何使用带有参数的宏定义的相关资料。虽然没有具体的标签,但我们可以从文件名推测,这可能是一些项目文件(如.sln,.sdf)和编译过程...
如果括号没有正确匹配,编译器将会报错,导致程序无法正常运行。 1. **代码块与控制结构**: 在C++中,大括号`{}`用于定义代码块,例如函数体、循环体或条件语句。每个开启的大括号都需要一个关闭的大括号来结束...
接下来,我们将通过具体的例子来探讨带参数宏定义在实际使用中可能会遇到的分号问题。 ##### 示例一 考虑下面这个宏定义的例子: ```c #define LED(a) if(a)\ GPIO_ResetBits(GPIOC,GPIO_Pin_13)\ else\ ...
Macro argument syntax error -------------------宏参数语法错误 Macro expansion too long ----------------------宏的扩展以后太长 Mismatched number of parameters in definition ---------------------定义...
1. **尽可能地将参数括起来**:这可以帮助确保参数作为一个整体进行处理,防止意外的运算顺序。 2. **避免使用复杂的宏表达式**:宏定义应该尽量简洁,避免包含复杂的逻辑,以免引发难以预料的行为。 3. **优先使用...
- `check`:此函数接收一个字符串`exp`作为参数,并检查其中括号是否匹配。具体步骤如下: - 遍历字符串中的每个字符。 - 如果遇到左括号,则将其压入栈中。 - 如果遇到右括号,则从栈中弹出最近的一个左括号,...
宏定义主要分为两大类:**无参数宏定义** 和 **带参数宏定义**。 ##### 2.1 无参数宏定义 无参数宏定义是最基本的宏定义形式,它的格式如下: ```cpp #define 标识符 字符序列 ``` 这里,“`#define`”后面紧跟的是...
3. **可变参数宏**:C99标准引入了支持可变参数的宏,这使得宏可以接受不定数量的参数。 - 示例: ```c++ #define PRINT(...) printf(__VA_ARGS__) PRINT("%d %s", 1, "Hello"); ``` - 这里使用`__VA_ARGS__`...
使用宏时,用户可能会提供带有括号的参数,这可能会导致错误。例如: ```c #define SQUARE(x) (x) * (x) int a = (-1); int result = SQUARE(a); // 结果为1而不是-1 ``` 为了避免这种情况,可以在宏定义中...
- 带参数宏在使用时需要注意参数的正确传递。 **示例**: ```c int main() { int x = 10, y = 20; int maxVal = MAX(x, y); printf("Max value is %d\n", maxVal); return 0; } ``` 在这个例子中,通过`MAX`...
- **实参含表达式**:如果宏调用中的实参包含表达式,最好使用圆括号括起来或者在宏定义时将形参括起来,避免出错。 - **宏名与左括号之间的空格问题**:宏名后面紧跟左括号,中间不能有空格。 - **多行宏定义**:...
宏定义主要有两种类型:不带参数的宏定义和带参数的宏定义。 不带参数的宏定义通过`#define`关键字来创建,形式如下: ```c #define 标识符 字符串 ``` 这里的标识符是宏名,通常使用大写字母表示。当宏名在程序...
宏定义分为无参数宏定义和带参数宏定义两种。 8.1.1 无参数宏定义 无参数宏定义的基本形式是 `#define` 后跟一个标识符和一个字符串或常量。例如,`#define PI 3.1415926`,这定义了一个名为PI的宏,代表π的近似值...
4. **可变参数宏**:`__VA_ARGS__`是预定义的宏,用于接收可变数量的参数,如`LOG(format, ...)`例子,它允许类似于函数的宏调用,如`LOG("%s %d", str, count)`。 5. **递归宏**:当一个宏在自己的定义中调用自身...
本文将深入探讨函数参数和宏参数的区别及其在使用中的特点。 首先,我们来看函数参数。在C语言中,函数参数分为形式参数(形参)和实际参数(实参)。形参是函数定义时声明的变量,它们在函数体内可用,但超出函数...
宏定义使用`#define`关键字,它可以分为两类:不带参数的宏定义和带参数的宏定义。 1. 不带参数的宏定义: 不带参数的宏定义格式为`#define 标识符 字符串`。例如,定义`PI`为圆周率的近似值,`#define PI 3....
这里需要注意的是,在宏定义中使用圆括号来确保表达式的正确解析,因为在宏展开时不考虑运算符优先级。 #### 五、计算最大值和最小值 使用条件运算符可以很容易地定义求最大值和最小值的宏: ```c #define MAX(x,...