我在 C 中编写了一些测试代码。我错误地在;
之后插入了#define
,这给了我错误。为什么#define
s不需要分号?
更具体地说:
方法1:有效
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都不是常量吗?
答案 0 :(得分:38)
#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
如果最后有;
,则将其视为VALUE
的一部分。
要了解#define
的确切运作方式,请尝试定义:
#define FOREVER for(;;)
...
FOREVER {
/perform something forever.
}
John Hascall的有趣评论:
大多数编译器会为您提供一种在预处理器阶段之后查看输出的方法,这可以帮助调试此类问题。
在gcc
中,可以使用标记-E
完成。
答案 1 :(得分:22)
#define
是一个preprocessor directive,而不是C语法定义的语句或声明(两者都必须以分号)。每个语法的规则都不同。
答案 2 :(得分:17)
define
是预处理程序指令,是一个简单的替换,它不是声明。
BTW,作为替代品,它可能包含一些;
作为其中的一部分:
// Ugly as hell, but valid
#define END_STATEMENT ;
int a = 1 END_STATEMENT // preprocessed to -> int a = 1;
答案 3 :(得分:13)
这两个常数?没有。
第一种方法不会在C语言中生成常量。 Const限定变量不符合C中的常量。第一种方法仅适用于 past-C99 C 编译器支持可变长度数组(VLA)。您的buffer
在第一种情况下是VLA,特别是因为MAX_STRING
不是常量。尝试在文件范围内声明相同的数组,并且您将收到错误,因为文件范围内不允许使用VLA。
第二种方法可用于将名称分配给C中的常量值,但您必须正确执行。宏定义中的;
不应该存在。宏通过文本替换工作,并且您不想将额外的;
替换为数组声明。定义该宏的正确方法是
#define MAX_STRING 256
在C语言中,当涉及到定义正确的命名常量时,基本上只限于宏和枚举。不要尝试使用const
&#34;常数&#34;,除非您确实知道它可以用于您的目的。
答案 4 :(得分:11)
就语言而言,第二个版本没有定义常量,只是一个文本块的替换规则。一旦预处理器完成了它的工作,编译器就会看到
.as-console-wrapper { max-height: 100% !important; top: 0; }
在语法上无效。
故事的寓意:更喜欢char buffer [256;];
方式,因为它可以帮助您,编译器和调试器。
答案 5 :(得分:10)
因为这是 预编译器指令 的语法决定方式。
只有 语句 以c / c ++中的;
结尾, #define
是一个预处理器指令,不是声明 。
答案 6 :(得分:1)
此预处理程序指令:
#define MAX_STRING 256;
告诉预处理器用MAX_STRING
替换所有256;
- 并用分号替换。预处理程序语句最后不需要分号。如果放一个,预处理器实际上认为你的意思是分号。
如果您对常量#define
感到困惑,const int
可能会更容易理解。
如果您想了解有关如何正确使用这些预处理程序指令的更多信息,请尝试查看this website.