对数组中的定义进行健全性检查

Sanity check on definitions from arrays

我正在寻找错误的原因,如果我对使用 #define 的理解是正确的,我想我可能已经找到了它。

据我了解,一旦你定义了一些东西,它就是这样设置的,即使定义中充满了变量的值,它也会在编译时保留值并且不会改变变量后来改了?所以这段代码:

int values[] = {5,6,7,8};
int x = 0;
#define DEF_VALUE values[x]

DEF_VALUE 将是 5,因为 5 是值数组中位置 0 的值。

但如果我这样做:

int values[] = {5,6,7,8};
int x = 0;
#define DEF_VALUE values[x]
x = 2;

DEF_VALUE 仍然是 5,因为那是调用 #define 时 values[x] 的输出,所以稍后将 x 的值更改为 2 不会导致 DEF_VALUE到7(values数组中位置2的值)。

我的逻辑对吗?

如果是这样的话,我想我已经发现了我的错误,因为这段代码的原始程序员依赖于更新 x 来更新代码中稍后用于选择的位置地址的 DEF_VALUE 的值。

#define 在 C 中的工作方式是它创建一个 扩展 ,即 DEF_VALUE 出现的任何地方,编译器将其视为values[x] 已写入。 C 预处理器通过应用这些扩展有效地重写代码,并将重写后的代码提供给编译器。

在这种情况下,改变 x 会改变 DEF_VALUE 最终 评估 的结果,但不会改变它扩展的结果。

在您的第二种情况下,当且仅当 x2 时,它才会扩展为 7。如果此 #define 在另一个范围内使用,则结果未知或出现语法错误,具体取决于存在的变量。

一些测试代码:

void demo() {
  int values[] = {5,6,7,8};
  int x = 0;
  #define DEF_VALUE values[x]
  x = 2;

  printf("%d\n", DEF_VALUE);
}

此处显示 7 符合预期。

一旦预处理器完成这段代码,它就会以这种形式结束:

void demo() {
  int values[] = {5,6,7,8};
  int x = 0;
  x = 2;

  printf("%d\n", values[x]);
}

如果稍后在您的代码中有这个:

void other() {
  printf("%d\n", DEF_VALUE);
}

您收到语法错误。那是因为编译器被告知要使用的代码实际上是:

void other() {
  printf("%d\n", values[x]);
}

由于 valuesx 都不存在于该范围内,因此无法编译。