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

标签 c macros

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

编译器说:

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;
}

最佳答案

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

//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

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

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

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


但是(这是上面提到的“见下文”部分),我会更进一步说您可能不应该在这里使用宏。宏的三个主要用例(从最早的 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))

关于c - 为什么下面的代码不能编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29693460/

相关文章:

c++ - 错误 : macro names must be identifiers

c - fgets 为 popen 返回的 FILE 返回错误

c - 三元运算符使用问题

c - 如何在 Mac 终端中运行源代码?

macros - 符号宏如何处理让阴影?

c++ - 创建 "shortcuts"类宏定义

c - 在 C 中使用 fgets 进行输入

c - C 如何计算 sin() 和其他数学函数?

scala - Scala 中的类型细化但不使用细化

ios - 目标 Interface Builder 的预处理器宏不适用于 OS X?