int main()
{
i/*nt*/a = 10;
return 0;
}
如果我有上面的代码,我想计算代币,是14个还是13个代币?
在变量名中写入注释是否有效?您可以假设
int i
、int a
、int ia
是全局定义的。
注释在程序翻译的第 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代码大赛
C 标准...预处理标记可以用
空格分隔; 这由注释(稍后描述)或空白组成 字符(空格、水平制表符、换行符、垂直制表符和 换页),或两者兼而有之。 ...
更具体地说,一条评论被翻译成一个空格。 这在第 5.1.1.2p3 节中指定:
源文件被分解为预处理标记和 空白字符序列(包括注释)。 一个 源文件不得以部分预处理标记或以 部分评论。
每条评论均替换为一个空格字符。保留换行符。 每个非空序列是否 保留或替换除换行符之外的空白字符 一个空格字符是实现定义的。
为了说明这一点,如果您将代码传递给预处理器,您将得到:
int main()
{
i a = 10;
return 0;
}
因此,注释(例如空格)可以用来分隔标记。
这意味着代码将包含 14 个令牌,而不是 13 个。
i a = 10;
不是:
ia = 10;
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;
}
显然,你可以得出结论,有一个错误。