宏函数的不需要的(或不稳定的)结果
Unwanted (or erratic) result of macro function
下面输入 2、3、10 的代码旨在给出 12.5 作为结果。([sum(2,3,10)(=15) + largest(2,3,10)( =10)] / 最小(2,3,10)(=2))
但它输出 2.000 作为结果,这是不需要的和错误的。我犯了优先级错误还是我犯了什么样的错误?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define MIN( a, b ) ( ( a < b ) ? (a) : (b) ) // Why are the parantheses imporant?
#define MAX( a, b ) ( ( a < b ) ? (b) : (a) )
#define LARGEST( a, b, c ) ( MAX( a, b ) < c ) ? c : ( MAX( a, b ) )
#define SMALLEST( a, b, c ) ( a < MIN( b, c ) ) ? a : ( MIN( b, c ) )
#define SUM( a, b, c ) ( (a + b + c) )
#define EXPR( a, b, c ) ( (LARGEST( a, b, c ) + SUM( a, b, c ) ) / SMALLEST( a, b, c ) )
int main(){
float a, b, c;
printf("Enter three integers!\n");
scanf(" %f", &a);
scanf(" %f", &b);
scanf(" %f", &c);
printf("The result is %f.\n", EXPR(a, b, c));
return 0;
}
要查看预处理器生成的实际代码只需执行此命令
gcc -E main.c
我们将得到(只是最后一条命令输出的最后一部分)
#include <stdio.h>
int main()
{
float a, b, c;
printf("Enter three integers!\n");
scanf(" %f", &a);
scanf(" %f", &b);
scanf(" %f", &c);
printf("The result is %f.\n", ( (( ( ( a < b ) ? (b) : (a) ) < c ) ? c : ( ( ( a < b ) ? (b) : (a) ) ) + ( (a + b + c) ) ) / ( a < ( ( b < c ) ? (b) : (c) ) ) ? a : ( ( ( b < c ) ? (b) : (c) ) ) ));
return 0;
}
这有点复杂
( (( ( ( a < b ) ? (b) : (a) ) < c ) ? c : ( ( ( a < b ) ? (b) : (a) ) ) + ( (a + b + c) ) ) / ( a < ( ( b < c ) ? (b) : (c) ) ) ? a : ( ( ( b < c ) ? (b) : (c) ) ) )
我的第一个猜测是我在评论中所说的优先
所以让我们在 /
运算符中取左操作数并暂时忽略其余部分以查看问题
(( ( ( a < b ) ? (b) : (a) ) < c ) ? c : ( ( ( a < b ) ? (b) : (a) ) ) + ( (a + b + c) ) )
|-----------------------------------------------|
the sum of the three operator will be added to the statement of the false condition ONLY (which is if a or b is the largest in this case) first and then we will evaluate the ?: because as you know the + is higher than ?: in table precedence
所以让我们把刚刚处理的左边的块(就在上面)称为LeftBlock,以便于接下来的分析
所以结合 /
运算符的右操作数(或整个语句剩下的)我们将得到
LeftBlock / ( a < ( ( b < c ) ? (b) : (c) ) ) ? a : ( ( ( b < c ) ? (b) : (c) ) )
现在 /
的优先级高于 ?:
运算符,因此将首先计算此表达式
LeftBlock / ( a < ( ( b < c ) ? (b) : (c) ) ) ? a : ( ( ( b < c ) ? (b) : (c) ) )
|--------------------------------------------|
this is the condition for the ?: operator instead of only ( a < ( ( b < c ) ? (b) : (c) ) ) which is WRONG
如您所见,缺少括号会导致不希望的结果!!
还有许多其他关于宏的陷阱,您应该避免您可以从这个 link!
中查看其中的一些陷阱
我想我终于解决了这个问题!! :)
因为宏扩展会替换宏文本中的每一次出现,例如考虑这个简单的宏
#define SQR(x) x * x
像这样使用这个宏
double x = SQR(1.0 + 2.0);
将扩展到
double x = 1.0 + 2.0 * 1.0 + 2.0;
产生 5.0
,如果您添加括号,它们也会被插入
#define SQR(x) (x) * (x)
然后它会扩展到
double x = (1.0 + 2.0) * (1.0 + 2.0);
产生 9.0
.
下面输入 2、3、10 的代码旨在给出 12.5 作为结果。([sum(2,3,10)(=15) + largest(2,3,10)( =10)] / 最小(2,3,10)(=2)) 但它输出 2.000 作为结果,这是不需要的和错误的。我犯了优先级错误还是我犯了什么样的错误?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define MIN( a, b ) ( ( a < b ) ? (a) : (b) ) // Why are the parantheses imporant?
#define MAX( a, b ) ( ( a < b ) ? (b) : (a) )
#define LARGEST( a, b, c ) ( MAX( a, b ) < c ) ? c : ( MAX( a, b ) )
#define SMALLEST( a, b, c ) ( a < MIN( b, c ) ) ? a : ( MIN( b, c ) )
#define SUM( a, b, c ) ( (a + b + c) )
#define EXPR( a, b, c ) ( (LARGEST( a, b, c ) + SUM( a, b, c ) ) / SMALLEST( a, b, c ) )
int main(){
float a, b, c;
printf("Enter three integers!\n");
scanf(" %f", &a);
scanf(" %f", &b);
scanf(" %f", &c);
printf("The result is %f.\n", EXPR(a, b, c));
return 0;
}
要查看预处理器生成的实际代码只需执行此命令
gcc -E main.c
我们将得到(只是最后一条命令输出的最后一部分)
#include <stdio.h>
int main()
{
float a, b, c;
printf("Enter three integers!\n");
scanf(" %f", &a);
scanf(" %f", &b);
scanf(" %f", &c);
printf("The result is %f.\n", ( (( ( ( a < b ) ? (b) : (a) ) < c ) ? c : ( ( ( a < b ) ? (b) : (a) ) ) + ( (a + b + c) ) ) / ( a < ( ( b < c ) ? (b) : (c) ) ) ? a : ( ( ( b < c ) ? (b) : (c) ) ) ));
return 0;
}
这有点复杂
( (( ( ( a < b ) ? (b) : (a) ) < c ) ? c : ( ( ( a < b ) ? (b) : (a) ) ) + ( (a + b + c) ) ) / ( a < ( ( b < c ) ? (b) : (c) ) ) ? a : ( ( ( b < c ) ? (b) : (c) ) ) )
我的第一个猜测是我在评论中所说的优先
所以让我们在 /
运算符中取左操作数并暂时忽略其余部分以查看问题
(( ( ( a < b ) ? (b) : (a) ) < c ) ? c : ( ( ( a < b ) ? (b) : (a) ) ) + ( (a + b + c) ) )
|-----------------------------------------------|
the sum of the three operator will be added to the statement of the false condition ONLY (which is if a or b is the largest in this case) first and then we will evaluate the ?: because as you know the + is higher than ?: in table precedence
所以让我们把刚刚处理的左边的块(就在上面)称为LeftBlock,以便于接下来的分析
所以结合 /
运算符的右操作数(或整个语句剩下的)我们将得到
LeftBlock / ( a < ( ( b < c ) ? (b) : (c) ) ) ? a : ( ( ( b < c ) ? (b) : (c) ) )
现在 /
的优先级高于 ?:
运算符,因此将首先计算此表达式
LeftBlock / ( a < ( ( b < c ) ? (b) : (c) ) ) ? a : ( ( ( b < c ) ? (b) : (c) ) )
|--------------------------------------------|
this is the condition for the ?: operator instead of only ( a < ( ( b < c ) ? (b) : (c) ) ) which is WRONG
如您所见,缺少括号会导致不希望的结果!!
还有许多其他关于宏的陷阱,您应该避免您可以从这个 link!
中查看其中的一些陷阱我想我终于解决了这个问题!! :)
因为宏扩展会替换宏文本中的每一次出现,例如考虑这个简单的宏
#define SQR(x) x * x
像这样使用这个宏
double x = SQR(1.0 + 2.0);
将扩展到
double x = 1.0 + 2.0 * 1.0 + 2.0;
产生 5.0
,如果您添加括号,它们也会被插入
#define SQR(x) (x) * (x)
然后它会扩展到
double x = (1.0 + 2.0) * (1.0 + 2.0);
产生 9.0
.