我们可以在变量名中写注释吗?

Vin*_*ita 146 c lexical-analysis

int main()
{
     i/*nt*/a = 10;
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我有上面的代码并且我想计算令牌,它是14个令牌还是13个令牌?

在变量名中写注释是否有效?您可以假设int i, int a,int ia是全局定义的。

chq*_*lie 199

注释在程序翻译1 的第 3 阶段被删除:每个注释被一个空格字符替换。所以评论/*nt*/绝对不是令牌。

如果intmainiareturn中没有一个被定义为预处理宏,解析程序会产生14 个标记(不是 13 个):

int main ( ) { i a = 10 ; return 0 ; }

除非i被定义为带有typedef语句的类型,否则会出现语法错误,因为i a不匹配 C 语法中的规则。

所以你不能变量名中写注释,注释将标识符分成 2 个单独的标记。对于任何预处理和 C 语言标记2都是如此。

但是请注意,您可以在不常见的位置插入注释,例如在一元运算符及其操作数之间或在#和 预处理指令及其参数之间:

/**/#/**/include/**/<stdio.h>/**///////////////////////
/**/#/**/define/**/STAT/**/(/**/a/**/)/**/-/**/1/**////
/**/#/**/ifdef/**/STAT/**//////////////////////////////
/**/int/**/main/**/(/**/)/**/{/**//////////////////////
/**/int/**/a/**/=/**/+/**/1/**/;/**////////////////////
/**/printf/**/(/**/"Hello "/**/"world!\n"/**/)/**/;/**/
/**/return/**/STAT/**/;/**/////////////////////////////
/**/}/**///////////////////////////////////////////////
/**/#/**/endif/**//////////////////////////////////////
Run Code Online (Sandbox Code Playgroud)

但是上面的宏定义并没有定义一个类似函数的宏,而是一个STAT扩展为( a ) - 1.

变量名,就像任何其他标记一样,可以被转义的换行符分割。转义的换行符是序列或\紧随其后的换行符。这些序列在程序翻译的第 2 阶段从源代码中删除。它们的主要目的是在多行上打破长宏定义。

下面是生成相同 14 个令牌的代码片段3

\
i\
nt\
 ma\
in()
{\
i/\
*nt\
*/a \
= 10;
r\
et\
urn\
 0;}

Run Code Online (Sandbox Code Playgroud)

请注意代码着色器如何错过了切片和切块的关键字和注释:)


1) 这种行为是在 ANSI-C 又名 C89 中指定的。一些古老的编译器具有导致标记粘贴的微妙不同的行为,但这些特性仅具有历史意义。

2) 您几乎可以利用在程序翻译的第 6 阶段连接相邻字符串常量这一事实,在字符串常量中插入注释: printf("Hello "/* my name is Luca */"world!\n");

3) 这种圣诞树的呈现风格并不打算在实际程序中使用,它说明了如何滥用 C 的输入处理能力。更精细的技巧赢得了国际混淆 C 代码竞赛


dbu*_*ush 65

从词汇的角度来看,注释与空格相同。

C 标准的第 6.4p3 节关于词法元素指出:

...预处理令牌可以用空格分隔;这由注释(稍后描述)或空白字符(空格、水平制表符、换行符、垂直制表符和换页符)或两者组成。...

更具体地说,评论被翻译成一个空格。这在第 5.1.1.2p3 节中指定:

源文件被分解为预处理标记和空白字符序列(包括注释)。源文件不应以部分预处理标记或部分注释结尾。 每个注释都由一个空格字符替换。 保留换行符。除了换行符之外的每个非空空格字符序列是保留还是替换为一个空格字符是实现定义的。

为了说明这一点,如果您通过预处理器传递您的代码,您将获得:

  int main()
  {
       i a = 10;
       return 0;

  }
Run Code Online (Sandbox Code Playgroud)

所以注释,就像空格一样,用于分隔标记。

这意味着代码将包含 14 个令牌,而不是 13 个。


Ken*_*Y-N 25

结果就像你写的一样:

i a = 10;
Run Code Online (Sandbox Code Playgroud)

不是:

ia = 10;
Run Code Online (Sandbox Code Playgroud)


JaM*_*MiT 12

请参阅翻译(又名编译)第 3 阶段,第 2 步:“每个注释都被一个空格字符替换”

所以,从概念上讲,在这一点上i/*nt*/a就变成i a了。