int main()
{
i/*nt*/a = 10;
return 0;
}
如果我有以上代码并想要统计标记,那么它会是14个标记还是13个标记?
在变量名中编写注释是否有效?您可以假设int i
,int a
,int ia
是全局定义的。
int main()
{
i/*nt*/a = 10;
return 0;
}
如果我有以上代码并想要统计标记,那么它会是14个标记还是13个标记?
在变量名中编写注释是否有效?您可以假设int i
,int a
,int ia
是全局定义的。
程序翻译的第三阶段会移除注释1:每个注释将被一个空格字符替换,所以注释/*nt*/
绝不是一个记号。
如果没有将int
、main
、i
、a
或return
定义为预处理宏,解析程序将产生14个记号(而非13个):
int
main
(
)
{
i
a
=
10
;
return
0
;
}
除非使用typedef
语句将i定义为一种类型,否则存在语法错误,因为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 代码大赛
从词汇角度来看,注释与空格相同。
有关词法元素的第6.4节第3段在C标准中说明:
...... 预处理令牌可以由空格分隔;这包括注释(稍后描述)或空白字符(空格、水平选项卡、换行符、垂直选项卡和换页符),或两者兼而有之。......
更具体地说,注释会被转换为一个空格。这在5.1.1.2节第3段中指定:
源文件被分解为预处理令牌和一系列空白字符序列(包括注释)。源文件不得以部分预处理令牌或部分注释结束。每个注释替换为一个空格字符。保留换行符。除换行符以外的每个非空白空格字符序列是否保留或替换为一个空格字符由实现定义。
举例来说,如果你通过预处理器处理你的代码,你会得到:
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;
}
cpp -traditional
实现的那样,它会被扩展为ia = 10;
。 - Nate Eldredge