我正在阅读有关令牌并计算程序中令牌的数量。
以前,我在某处读到预处理器命令不算作令牌。 但是,当我在Geeksforgeeks上阅读有关令牌的信息时,它会在“特殊符号”部分中给出:
预处理器(#):预处理器是一个宏处理器,编译器会在自动编译之前自动使用它来转换程序。
所以我很困惑,在程序中,如果我们写#define
是令牌吗?
例如:
#include<stdio.h>
#define max 100
int main()
{
printf("max is %d", max);
return 0;
}
此示例中有多少个令牌??
答案 0 :(得分:6)
链接的文章充满了基本错误,因此不应依赖。
解析C或C ++的过程定义为一系列转换: 1
if
是该语言固有的IF标记,而仅仅是预处理器的IDENT标记。您的示例程序
#include<stdio.h>
#define max 100
int main()
{
printf("max is %d", max);
return 0;
}
在转换3之后,将是这一系列的23个预处理令牌:
PUNCT:# IDENT:include INCLUDE-ARG:<stdio.h>
PUNCT:# IDENT:define IDENT:max PP-NUMBER:100
IDENT:int IDENT:main PUNCT:( PUNCT:)
PUNCT:{
IDENT:printf PUNCT:( STRING:"max is %d" PUNCT:, IDENT:max PUNCT:) PUNCT:;
IDENT:return PP-NUMBER:0 PUNCT:;
PUNCT:}
该指令在此阶段仍然存在。请注意,#include
和#define
分别是两个令牌:#
和指令名称是分开的。有些人喜欢在第1列中写上所有带有井号的复杂#if
嵌套,但指令名称缩进。
在转换5之后,这些指令不见了,我们有了这一系列的16 + n个令牌:
[ ... some large volume of tokens produced from the contents of stdio.h ... ]
INT IDENT:main LPAREN RPAREN
LBRACE
IDENT:printf LPAREN STRING:"max is %d" COMMA DECIMAL-INTEGER:100 RPAREN SEMICOLON
RETURN DECIMAL-INTEGER:0 SEMICOLON
RBRACE
然而'n'却是来自stdio.h的许多令牌。
预处理指令(#include
,#define
,#if
等) 总是从令牌流中删除,并可能被其他内容替换,因此您转换6之后永远不会有直接来自指令行文本的标记。但是,通常会有每个指令的效果产生的标记,例如stdio.h
的内容,并用DECIMAL-INTEGER:100
代替IDENT:max
。
最后,C和C ++几乎几乎执行了这一系列操作,但并不完全相同,并且规范在形式上是独立的。只要您仅使用预处理器执行简单的操作,通常就可以依靠预处理操作来在两种语言中表现相同,这是当今的最佳做法。
1 有时您会看到人们谈论翻译阶段,这是C和C ++标准正式描述这一系列操作的方式。我的清单不是翻译阶段的清单。它包含一些单独的项目要点,这些要点按标准归为一个阶段,并省略了与该讨论无关的几个步骤。