为什么以下代码无法编译?

Kas*_*nko 2 c macros

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

编译器说:

行:23错误:预期')'之前';' 代币

行:24错误:预期';' 在')'令牌之前

#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;
}
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 10

错误消息是因为宏上的括号不平衡:

//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
Run Code Online (Sandbox Code Playgroud)

并且可以通过简单地在第四个结束后放置另一个右括号来修复,假设表达式是:
   在此输入图像描述

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

#define CENTER(a,b,x,y,g) g*sqrt(pow((x-a),2.0)+pow((y-b),2.0))
Run Code Online (Sandbox Code Playgroud)

如果你在声明结尾之外的任何地方使用宏,那么分号尤其令人讨厌,幸运的是,你没有这样做,但在未来的某个时候可能会很好.例如,这个结构将使用分号隐藏失败:

x = CENTER(1,2,3,4,5)+42;
Run Code Online (Sandbox Code Playgroud)

因为它会编译,但不会按照你的想法做到,所以它是阴险的,例如,以下代码将不会打印出来100:

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

那是因为,在预处理之后,你最终得到:

    int plugh = (10); + 90;
Run Code Online (Sandbox Code Playgroud)

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


然而(这是上面提到的"见下文"位),我会进一步说你可能根本不应该在这里使用宏.宏的三个主要用例(从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);
}
Run Code Online (Sandbox Code Playgroud)

(但如果可能的话,有更多的描述性变量).

我现在通常甚至不使用,inline因为编译器通常可以解决它,但我已经把它放在那里以保持完整性.

这也消除了许多类似函数的宏的问题,例如当你传递类似var + 7你的(未表白)g变量的东西时,发现表达式并没有因为运算符优先级而给你想要的东西:

var + 7 * sqrt (pow ((x - a), 2.0) + pow ((y - b), 2.0))
Run Code Online (Sandbox Code Playgroud)

当你真正想要的是:

(var + 7) * sqrt (pow ((x - a), 2.0) + pow ((y - b), 2.0))
Run Code Online (Sandbox Code Playgroud)