为什么我在编译此代码时遇到错误以及如何解决它们?

时间:2017-02-22 06:44:38

标签: c compilation macros rounding

我正在尝试编写的程序包括一个宏,用于将实数舍入到最接近的整数,以及一个使用该宏来舍入实数数组的函数。

以下是该计划:

#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:

为什么我会收到这些错误,如何解决?

5 个答案:

答案 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))

我所做的更改包括:

  1. 将其作为表达。这涉及用括号替换花括号。这样你几乎可以在任何可以使用函数的地方使用宏。如果我离开花括号,它本来就是一个复合语句。

  2. 在括号中包含参数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,也可能跟踪;