19

我正在用C编写一些测试代码。;错误地我在 a之后插入了a #define,这给了我错误。为什么 s 不需要分号#define

进一步来说 :

方法一:工作

const int MAX_STRING = 256;

int main(void) {
    char buffer[MAX_STRING];
}

方法2:不起作用 - 编译错误。

#define MAX_STRING 256;

int main(void) {
    char buffer[MAX_STRING];
}

这些代码的不同行为的原因是什么?这两个 MAX_STRING 都不是常量吗?

4

7 回答 7

42
#define MAX_STRING 256;

方法:

每当您在预处理时找到 MAX_STRING 时,将其替换为256;. 在您的情况下,它将使用方法 2:

#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING 256;

int main(void) {
    char buffer [256;];
}

这不是有效的语法。代替

#define MAX_STRING 256;

#define MAX_STRING 256

您的两个代码之间的区别在于,在第一种方法中,您声明一个等于的常量,256但在您定义的第二个代码中,您在源文件中定义MAX_STRING为代表。256;

#define 指令用于定义预处理器使用的值或宏,以在编译程序源代码之前对其进行操作。因为预处理器定义在编译器作用于源代码之前被替换,所以由#define 引入的任何错误都很难追踪。

语法是:

#define CONST_NAME VALUE

如果;末尾有 a ,则将其视为VALUE.

要了解#defines 究竟是如何工作的,请尝试定义:

#define FOREVER for(;;)
...
    FOREVER {
         /perform something forever.
    }

John Hascall的有趣评论:

大多数编译器都会为您提供一种在预处理器阶段之后查看输出的方法,这有助于调试此类问题。

gcc可以用 flag 来完成-E

于 2016-11-07T08:29:18.453 回答
24

#define预处理器指令,而不是 C 语法定义的语句声明(两者都需要以分号结尾)。每种语法的规则都不同。

于 2012-05-24T09:53:15.913 回答
17

define是一个预处理器指令,是一个简单的替换,它不是一个声明。

顺便说一句,作为替代,它可能包含一些;作为它的一部分:

// Ugly as hell, but valid 
#define END_STATEMENT ;

int a = 1 END_STATEMENT // preprocessed to -> int a = 1;
于 2012-05-24T09:53:34.643 回答
13

两个常数?不。

第一种方法不会产生 C 语言中的常量。const 限定的变量不符合 C 中的常量。您的第一种方法之所以有效,是因为过去的 C99 C编译器支持可变长度数组 (VLA)。在第一种情况下,您buffer是 VLA,特别是因为MAX_STRING不是常数。尝试在文件范围内声明相同的数组,您会收到错误消息,因为文件范围内不允许使用 VLA。

第二种方法可用于为 C 中的常量值分配名称,但您必须正确执行此操作。;in 宏定义不应该在那里。宏通过文本替换工作,您不想将额外的内容替换;到您的数组声明中。定义该宏的正确方法是

#define MAX_STRING 256

在 C 语言中,当涉及到定义正确的命名常量时,您基本上仅限于宏和枚举。不要尝试使用const“常量”,除非您真的知道它可以满足您的目的。

于 2016-11-07T08:29:19.883 回答
11

因为这就是为预编译器指令决定语法的方式。

在 c/c++ 中,只有以 a 结尾的语句是预处理器指令而不是语句;#define

于 2012-05-24T09:53:23.450 回答
11

就语言而言,第二个版本没有定义常量,只是一个文本块的替换规则。一旦预处理器完成了它的工作,编译器就会看到

char buffer [256;];

这在语法上无效。

故事的寓意:更喜欢对const int MAX_STRING = 256;您、编译器和调试器有帮助的方式。

于 2016-11-07T08:28:00.387 回答
1

这个预处理器指令:

#define MAX_STRING 256;

告诉预处理器用- 和分号MAX_STRING替换所有s 。预处理器语句末尾不需要分号。如果你放一个,预处理器实际上认为你用分号表示它。256;

如果您#define对常量的 s 感到困惑,const int可能会更容易理解。

如果您想了解有关如何正确使用这些预处理器指令的更多信息,请尝试查看此网站。

于 2016-11-13T22:06:56.493 回答