所以我有一个与宏函数定义相同的函数,它们输出相同的值。为了证实这一点,我这样做了:
int a(int vertex, int offset) {
int value = vertex*numberOfoffsets + offset;
if (value != b(vertex, offset)) printf("error\n");
return value;
}
这是宏:
#define b(vertex, offset) (vertex*numberOfoffsets + offset) //EDIT: I had mta instead of b here (on the stackoverflow post)
请注意,numberOfOffsets
也是一个宏,它返回6。
我使用a(vertex,offset)
运行算法,一切都按预期工作,没有打印error\n
,这意味着两个函数都返回相同的值。
但是当我使用b(vertex,offset)
而不是a(vertex,offset)
运行算法时,会出现错误的答案(尽管算法不会中断。
关于宏,我有什么遗漏吗?他们不只是替换文字吗?我真的不明白这种行为。
编辑:抱歉,我忘了更改功能名称,b现在正确(这是定义功能)EDIT2:添加括号可以解决问题,因此它应该是:
#define b(vertex, offset) (((vertex)*(numberOfoffsets)) + (offset))
但是其他用户建议我使用内联函数,所以现在是:
static __inline__
int b(int vertex, int offset) {
return vertex*numberOfoffsets + offset;
}
答案 0 :(得分:4)
通常,您应该在宏定义中使用过多的括号,例如:
#define b(vertex, offset) ((vertex) * 6 + (offset))
否则,运算符优先级可以将结果更改为意外的内容。例如,使用
调用宏int x = 4;
int y = b(x+1, 3);
应与y = 5 * 6 + 3 = 33
相同。但是,如果没有括号,结果为
y = 4 + 1*6 + 3 = 13
。
评论中指出的@jxh与宏和函数之间还有另一个区别。
当调用带有int
参数的函数且参数不是int
类型的函数时,编译器将隐式地将参数转换为int
。但是使用宏,没有进行这样的转换。
例如,代码
#define b(vertex, offset) ((vertex) * 6 + (offset))
int a(int vertex, int offset)
{
return vertex * 6 + offset;
}
int main(void)
{
double vertex = 3.3;
double offset = 7.4;
int resultA = a(vertex, offset);
int resultB = b(vertex, offset);
printf("%d %d\n", resultA, resultB);
}
将打印25 27
。这是因为编译器在调用函数之前将vertex
转换为3并将offset
转换为7
。但宏使用double
值进行数学计算,并且通过赋值给int
将答案转换为resultB
。
你是否需要对此做任何事情都值得商榷。但是,要使宏完全等效于函数,可以将其写为
#define b(vertex, offset) ((int)((int)(vertex) * 6 + (int)(offset)))