Can we write comments within variable names?

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

If I have the above code and I want to count the tokens, will it be 14 or 13 tokens?

Is it valid to write a comment within a variable name? You can assume that the int i, int a, int ia are globally defined.

17924 次浏览

结果就好像你写了:

i a = 10;

不:

ia = 10;

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

C 标准中关于词法元素的6.4 p3部分指出:

... 预处理令牌可以由 留白分隔; 这由注释(稍后描述)或 < em > 空白组成 字符 (空格、水平选项卡、新行、垂直选项卡和 或者两者兼而有之。 ..。

更具体地说,注释被翻译成一个空格,这在5.1.1.2 p3节中有详细说明:

源文件被分解为预处理令牌和 空白字符序列(包括注释) 源文件不应以部分预处理令牌或 部分注释 保留新行字符。是否每个非空序列 保留或替换新行以外的空白字符 按一个空格字符是实现定义的。

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

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


}

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

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

参见翻译(又名编译) 第三阶段,步骤2: “每条注释由一个空格字符替换”

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

注释在程序转换 1: 每个注释由一个空格字符替换。的第3阶段被删除,因此注释 /*nt*/绝对不是令牌。

如果没有 intmainiareturn被定义为预处理宏,解析程序会产生 14令牌(而不是13) :

int main ( ) { i a = 10 ; main0 main1 ; main3

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

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

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

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

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

与任何其他标记一样,变量名可以通过转义换行来拆分。转义换行是立即跟在换行后面的序列或 \。在程序翻译的第二阶段,这些序列从源代码中移除。它们的主要用途是在多行上打破冗长的宏定义。

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

\
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语言混乱代码大赛

检查一下你的代码是什么形式的

     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;
}

很明显,你可以得出这是个错误的结论。