如果我有:
#define MAXLINE 5000
MAXLINE被理解为什么类型?我应该假设它是int
吗?我能以某种方式测试吗?
一般来说,如何确定#define
ed变量的类型?
答案 0 :(得分:42)
它没有类型。这是一个简单的文本替换。在MAXLINE作为令牌出现的任何地方,文本5000都将被删除。
例如:
int a = MAXLINE;
会将值5000放在a
。
虽然
char *MAXLINE2 = "MAXLINE";
不会导致
char *50002 = "5000";
所以,如果你想要进行类型检查,那么宏不可行。您将需要声明静态常量,这样类型检查由编译器完成。
有关static
,const
和#define
之间差异的信息,有很多来源,包括这个问题:Static, define, and const in C
答案 1 :(得分:8)
(非常!)从广义上讲,您的C编译器在执行时将执行3个任务:
对源文件运行预处理传递
在预处理的源文件上运行编译器
在生成的目标文件上运行链接器。
以#
开头的行,如
#define MAXLINE 5000
由预处理器阶段处理。 (简单地说)预处理器将解析文件并对它检测到的任何宏执行文本替换。预处理器中没有类型的概念。
假设您的源文件中包含以下行:
#define MAXLINE 5000
int someVariable = MAXLINE; // line 2
char someString[] = "MAXLINE"; // line 3
预处理器将检测第2行的宏MAXLINE
,并执行文本替换。请注意,第3行"MAXLINE"
不被视为宏,因为它是字符串文字。
预处理器阶段完成后,编译阶段将只看到以下内容:
int someVariable = 5000; // line 2
char someString[] = "MAXLINE"; // line 3
(为了清楚起见,留下了注释,但通常由预处理器删除)
您可以在编译器上使用一个选项来检查预处理器的输出。在gcc中,-E
选项将执行此操作。
请注意,虽然预处理器没有类型概念,但没有理由不在宏中包含类型以保证完整性。 e.g。
#define MAXLINE ((int)5000)
答案 2 :(得分:5)
编译器永远不会看到那行代码,预处理器在实际编译之前运行,并用它们的文字值替换这些宏,请参阅下面的链接以获取更多信息
答案 3 :(得分:3)
它没有类型。它只是在将代码传递给编译器之前预处理器将放入源代码的标记。你可以这样做(荒谬)来声明一个名为x5000
的变量:
#define APPEND(x,y) x ## y
int main() {
int APPEND(x,5000);
x5000 = 3;
}
预处理器在将编译器正确传递给它之前将其转换为:
int main() {
int x5000;
x5000 = 3;
}
因此,仅仅因为您在宏中看到5000
,并不意味着它必须以任何方式成为数字。
答案 4 :(得分:2)
MAXLINE
根本不是变量。实际上,它不是C语法。编译过程的一部分在编译器之前运行预处理器,预处理器采取的一个操作是用MAXLINE
之后的任何内容替换源文件中的#define MAXLINE
标记的实例(问题代码中为5000) )。
除此之外:在代码中使用预处理器的另一种常见方法是使用#include
指令,预处理器只是替换为包含文件的预处理内容。
让我们看一下运行中的编译过程的示例。这是一个文件foo.c
,将在示例中使用:
#define VALUE 4
int main()
{
const int x = VALUE;
return 0;
}
我使用gcc
和cpp
(the C preprocessor)作为示例,但您可以使用任何编译器套件执行此操作,当然还有不同的标志。
首先,让我们用foo.c
编译gcc -o foo.c
。发生了什么?有效;你现在应该有一个可执行文件foo
。
您可以告诉gcc
仅预处理而不进行任何编译。如果您执行gcc -E foo.c
,您将获得标准输出的预处理文件。这是它产生的东西:
# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "foo.c"
int main()
{
const int x = 4;
return 0;
}
请注意,main
的第一行已将VALUE
替换为4
。
您可能想知道前四行是什么。这些被称为线性标记,您可以在Preprocessor Output中阅读更多相关信息。
据我所知,你不能完全跳过gcc
中的预处理,但是有几种方法可以告诉它文件已经被预处理了。但是,即使您这样做,它也会删除文件中存在的宏,因为它们不适合编译器使用。在这种情况下,您可以使用gcc -E -fpreprocessed foo.c
:
.
.
.
.
int main()
{
const int x = VALUE;
return 0;
}
注意:我把点放在顶部;假装那些是空行(我必须把它们放在那里以便通过SO显示这些行)。
此文件显然无法编译(请gcc -fpreprocessed foo.c
查找),因为VALUE
存在于源中,但未在任何地方定义。
答案 5 :(得分:1)
我们称之为宏或预处理器,用于字符串替换源文件内容。阅读:https://en.wikipedia.org/wiki/C_macro
答案 6 :(得分:1)
是的,您可以认为它是int
。
嗯,实际上所有其他答案都是正确的。它不是C,它只是
一个指令,告诉预处理器做一些文本
替换,因此它没有类型。但是,如果你不做任何事情
用它来制作时髦的东西(比如##预处理器技巧),你会的
通常使用MAXLINE
像某种常量和预处理器
将用5000
替换它,这确实是一个显式常量。和
常量确实有类型:5000
是int
。写成的常量
十进制整数,没有后缀(如U或L),将被解释
编译器为int
,long int
或unsigned long int
:第一个
这些类型适合。
但这当然与预备版无关。你可以
将您的问题重写为“5000
的类型是什么?”,没有
#define
。