为什么下面的代码不能编译?

Why following code doesn't compile?

您好,找不到我的代码中的错误。 我还是编程新手。所以请不要对我这么刻薄。

编译器说:

Line:23 error: expected ')' before ';' token

Line:24 error: expected ';' before ')' token

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>

#include <stdbool.h>
#include <time.h>
#include <unistd.h>

#define CENTER(a,b,x,y,g)       g*sqrt(pow((x-a),2.0)+pow((y-b),2.0);

int size=5,location_x=10,location_y=10,s=NULL,l_x, l_y, status=2;

int main(void)
{
    srand(time(NULL));
    float location[l_x][l_y];
    int x[size], y[size], z[size];

    l_x=1+rand()%100;
    l_y=1+rand()%100;

    for (int i=0; i<size; i++){
        location[l_x][l_y] += CENTER(x[i], y[i], location_x, location_y, z[i]);
    }
    return 0;
}

你需要 )g*sqrt(pow((x-a),2.0)+pow((y-b),2.0);

的末尾

使用

#define CENTER(a,b,x,y,g)    g*sqrt(pow((x-a),2.0)+pow((y-b),2.0))
                                                                 ^

并在最后删除 ;

也许是这样:

#define CENTER(a,b,x,y,g)       g*sqrt(pow((x-a),2.0)+pow((y-b),2.0);

...需要一个额外的括号来结束表达式,如下所示:

#define CENTER(a,b,x,y,g)       g*sqrt(pow((x-a),2.0)+pow((y-b),2.0))

您还应该删除结尾的分号。

错误信息是因为您的宏中的括号不平衡:

//opening ->                    1   23             45
#define CENTER(a,b,x,y,g) g*sqrt(pow((x-a),2.0)+pow((y-b),2.0);
//closing ->                             1    2         3    4

并且可以通过简单地在第四个右括号之后放置另一个右括号来修复,假设表达式是:

你真的不想在它的末尾有一个分号,一个更好的例子是(但见下文):

#define CENTER(a,b,x,y,g) g*sqrt(pow((x-a),2.0)+pow((y-b),2.0))

如果您在语句末尾以外的任何地方使用宏,分号会特别烦人,幸运的是,您没有这样做,但将来可能会在某个时候这样做。例如,此构造将因分号而不知不觉地失败:

x = CENTER(1,2,3,4,5)+42;

阴险,因为它编译但不会做你认为会做的事,例如,下面的代码会打印出100:

#include <stdio.h>
#define FN(x) (x);
int main (void) {
    int xyzzy = FN(10) + 90;
    printf ("%d\n", xyzzy);
    return 0;
}

那是因为,经过预处理后,您最终得到:

    int plugh = (10); + 90;

实际上是 两个 有效的 C 语句,第一个设置 xyzzy 为 10,第二个评估(但丢弃)表达式 + 90


但是(这是上面提到的 "see below" 位),我会更进一步说你可能 不应该 在这里使用宏.宏的三个主要用例(从最早的 C 开始)通常可以分为:

  • 条件编译;
  • 内联代码;和
  • 常量。

由于疯狂优化编译器,第二个通常已过时,而第三个不如枚举有用(除非您想传入编译时可配置常量,例如 gcc -DUNITS_PER_BIN=42 ...),我建议条件编译是你现在唯一应该使用宏的地方。

相反,我会简单地使用函数:

inline float center (float a, float b, float x, float y, float g) {
    return g * sqrt (pow ((x - a), 2.0) + pow ((y - b), 2.0);
}

(但尽可能使用更多描述性变量)。

现在我通常甚至不使用 inline,因为编译器通常可以弄清楚,但为了完整起见,我把它放在那里。

这也消除了很多类似函数的宏的问题,例如当您将 var + 7 之类的东西作为您的(未加括号的)g 变量传递时,发现表达式不是'由于运算符优先级,没有给你想要的:

var + 7 * sqrt (pow ((x - a), 2.0) + pow ((y - b), 2.0))

当你真正想要的是:

(var + 7) * sqrt (pow ((x - a), 2.0) + pow ((y - b), 2.0))

要创建常量,您可以使用 #define,但此语句不需要 ; 符号在其计算后面。另外,您在语句末尾缺少 )