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


144

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

在变量名内写注释是否有效?你可以假设int iint aint ia是全局定义。


13
至少在GNUcpp -traditional实施的ANSI前的“传统” C语言中,它将扩展为ia = 10;
Nate Eldredge

37
有什么有趣的问题-为什么以前从未发生过?
StephenBoesch

178
@javadba:因为明智的人不会考虑做这样的事情?
jamesqf

5
如果您确实想这样做,可以转到Fortran。字符串外部的空格在第一个解析阶段中被删除。
mpez0

3
我本打算将标题编辑为“ ....变量名内...”,但随后意识到您可能确实是在“之间”。(我要进行编辑,因为原始标题的答案是“为什么,显然是!”重要的部分是“没有空格”。)标题“注释(在无空格的情况下)是否用C分隔标记?” 表达您的实际问题?
彼得-恢复莫妮卡

Answers:


198

在程序翻译1的第3阶段中删除了注释每个注释都替换为一个空格字符。因此,此评论/*nt*/绝对不是令牌。

如果没有intmainiareturn定义为预处理的宏,解析程序生成14个令牌(未13):

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

除非i使用typedef语句将其定义为类型,否则会存在语法错误,因为i a它与C语法中的规则不匹配。

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

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

但是上述宏定义并未定义类似于函数的宏,而是定义了STAT扩展为的常规宏( a ) - 1

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

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

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


1)此行为是在ANSI-C或C89中指定的。一些古老的编译器的行为略有不同,导致令牌粘贴,但是这些特性仅在历史上有意义。

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

3)这种圣诞树的表示方式并不是要在实际程序中使用,它说明了如何滥用C的输入处理功能。更多精心制作的技巧赢得了国际混淆C代码竞赛


我想知道为什么标准要求在其他情况下行尾连续的反斜杠字符不能与其他换行符分隔,因为在其他情况下尾随空格或缺少空格在语义上是有意义的,并且某些文本文件格式可能不会能够区分以空格结尾的行和没有空格的行?
超级猫

@supercat:我同意。这也将涵盖来自使用CR LF序列作为行尾的旧系统的文件的情况,从而导致在Unix系统上导致编译错误,而该系统无法识别\r\n。开头的转义换行符。然而,在某些情况下这会适得其反:注释中可能包含\字符,后跟空格,特别是为了避免行粘贴:const char *path = "C:\\"; // the default path is C:\ 
chqrlie

该标准不要求文本文件能够在行尾支持空白字符。写这样的注释The path is "C:\"似乎比使代码的含义取决于尾随换行符要好。
超级猫

1
从技术上讲,该标准没有这样的要求,因为只要记录了这种行为,就可以将经常被忽略的翻译阶段1每一行剥离尾随空白。
zwol

4
这个答案有很长的路要走,只是为了证明没有愚蠢的问题。做得好。
凌晨

65

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

C标准中有关词汇元素的6.4p3节规定:

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

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

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

为了说明这一点,如果通过预处理器传递代码,则会得到:

因此,注释(如空格)可用于分隔标记。

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




1

只需检查一下代码的形式

将经过预处理。只需在编译器gcc -E myscript.c中添加“ -E”标志,您将得到结果:

显然,您可以得出结论,这是一个错误。


-9

是的,你可以这样做。注释将被编译器跳过。它们不会影响变量。就是一样,只是别忘了结束评论标签。


5
“不会影响变量。这将是相同的”一样的东西,i a还是ia
HolyBlackCat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.