我正在尝试编写的程序包括一个宏,用于将实数舍入到最接近的整数,以及一个使用该宏来舍入实数数组的函数。
以下是该计划:
#include <stdio.h>
#define SIZE 256
#define round(N) { return (N >=0)? (int)(N+0.5) : (int)(N-0.5) ; }
void round_array(int a[])
{
int i;
for(i=0; i <SIZE; i++)
{
a[i] = round(a[i]);
}
}
int main()
{
return 0;
}
编译时,我遇到了这些错误:
round.c: In function ���round_array���:
round.c:4:18: error: expected expression before ���{��� token
#define round(N) { return (N >=0)? (int)(N+0.5) : (int)(N-0.5) ; }
^
round.c:11:15: note: in expansion of macro ���round���
a[i] = round(a[i]);
^
round.c: At top level:
为什么我会收到这些错误,如何解决?
答案 0 :(得分:2)
因为在预处理之后,您的代码看起来类似于:
a[i] = { return (a[i] >=0)? (int)(a[i]+0.5) : (int)(a[i]-0.5) ; }
如果您想坚持使用宏,请将其声明为:
#define round(N) ((N) >=0)? (int)((N)+0.5) : (int)((N)-0.5)
但由于int / float混合,这仍然不是很正确。然而,这已经是一个不同的主题。
答案 1 :(得分:1)
就像它在评论中告诉你的那样,宏不是函数。它们是令牌替代机制。因此,您不会像使用函数那样从它们返回。
#define round(N) (((N) >=0)? (int)((N)+0.5) : (int)((N)-0.5))
我所做的更改包括:
将其作为表达。这涉及用括号替换花括号。这样你几乎可以在任何可以使用函数的地方使用宏。如果我离开花括号,它本来就是一个复合语句。
在括号中包含参数N,以确保操作符优先顺序不会回来并咬我们。
答案 2 :(得分:1)
宏替换基本上就是它听起来的样子,它用宏的主体取代了宏,非常字面。
所以当你有
时a[i] = round(a[i]);
它将被
取代a[i] = { return (a[i] >=0)? (int)(a[i]+0.5) : (int)(a[i]-0.5) ; };
这是无效的语法。作业的右侧必须是表达式而不是声明。
一个简单的解决方案是将round
从宏转变为实际函数。一个更简单的解决方案是认识到int
值(a[i]
是int
)没有分数,所以没有什么可以舍入。
如果您想使用浮点值,正确的解决方案是使用标准round
函数,而不是自己编写。
答案 3 :(得分:1)
如果你坚持自己写这个,你应该用更安全,更清洁的功能取代icky宏:
inline int int_round (double d)
{
return (int) ( d >= 0 ? d+0.5 : d-0.5 );
}
这应该产生完全相同的机器代码。
答案 4 :(得分:0)
您不需要return
关键字,它不是一个功能。摆脱它。
引用C11
,章节§6.8.6.4
return
语句终止当前函数的执行并将控制权返回给 它的来电者。 [...]
不您的MACRO定义的目的。包含return
关键字是不受欢迎的,并且语法无效。
你可能想要的是像
这样的语法 (N >=0)? (int)(N+0.5) : (int)(N-0.5)
或更好的东西
( (N) >=0)? (int)((N)+0.5) : (int)((N)-0.5)
没有return
,也可能跟踪;
。