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

问题描述 投票:0回答:5
int main()
{
     i/*nt*/a = 10;
     return 0;
}

如果我有上面的代码,我想计算代币,是14个还是13个代币?

在变量名中写入注释是否有效?您可以假设

int i
int a
int ia
是全局定义的。

c lexical-analysis
5个回答
208
投票

注释在程序翻译的第 3 阶段被删除1每个注释都被一个空格字符替换。因此注释

/*nt*/
绝对不是一个标记。

如果

int
main
i
a
return
均未定义为预处理宏,则解析程序会生成 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/**//////////////////////////////////////
但是上面的宏定义并没有定义类似函数的宏,而是定义了一个扩展为

STAT

的常规宏
( a ) - 1

与任何其他标记一样,变量名称可以通过转义换行符进行分割。转义换行符是紧跟换行符的序列或

\

。这些序列会在程序翻译的第二阶段从源代码中删除。它们的主要目的是打破多行上的长宏定义。

下面是一个代码片段

3,它生成相同的 14 个令牌:

\ i\ nt\ ma\ in() {\ i/\ *nt\ */a \ = 10; r\ et\ urn\ 0;}
注意代码着色器如何错过了切片和切块的关键字和注释:)


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

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


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


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

C 标准

第 6.4p3 节有关词汇元素的规定:

...预处理标记可以用
空格

分隔; 这由注释(稍后描述)或空白组成 字符(空格、水平制表符、换行符、垂直制表符和 换页),或两者兼而有之。 ...

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

源文件被分解为预处理标记和 空白字符序列(包括注释)。 一个 源文件不得以部分预处理标记或以 部分评论。
每条评论均替换为一个空格字符。

保留换行符。 每个非空序列是否 保留或替换除换行符之外的空白字符 一个空格字符是实现定义的。

为了说明这一点,如果您将代码传递给预处理器,您将得到:

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

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

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


25
投票

i a = 10;

不是:

ia = 10;



12
投票
第 3 阶段

,第 2 步:“每个注释都替换为一个空格字符” 因此,从概念上讲,

i/*nt*/a

在这一点上变成了

i a
    


1
投票

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

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

e.sharaborin@landau:~$ gcc -E myscript.c # 1 "myscript.c" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 32 "<command-line>" 2 # 1 "myscript.c" int main() { int i a = 10; return 0; }

显然,你可以得出结论,有一个错误。

© www.soinside.com 2019 - 2024. All rights reserved.