我们可以在变量名中写注释吗?
Can we write comments within variable names?
int main()
{
i/*nt*/a = 10;
return 0;
}
如果我有上面的代码,我想计算令牌数,是14个还是13个令牌?
在变量名中写注释有效吗?您可以假设 int i
、int a
、int ia
是全局定义的。
结果就像你写的一样:
i a = 10;
不是:
ia = 10;
从词法上看,一条注释和white是一样的space。
关于词汇元素的 C standard 第 6.4p3 节指出:
... Preprocessing tokens can be separated by white space;
this consists of comments (described later), or white-space
characters (space, horizontal tab, new-line,vertical tab, and
form-feed), or both. ...
更具体地说,一条评论被翻译成一条 space。这在第 5.1.1.2p3 节中指定:
The source file is decomposed into preprocessing tokens and
sequences of white-space characters (including comments). A
source file shall not end in a partial preprocessing token or in
a partial comment. Each comment is replaced by one space character.
New-line characters are retained. Whether each nonempty sequence
of white-space characters other than new-line is retained or replaced
by one space character is implementation-defined.
为了说明这一点,如果您通过预处理器传递代码,您将得到:
int main()
{
i a = 10;
return 0;
}
因此评论,如白色space,用于分隔标记。
这意味着代码将包含 14 个标记,而不是 13 个。
参见翻译(a.k.a. 编译)Phase 3,第 2 步:“每条评论由一个 space 个字符替换”。
所以,从概念上讲,i/*nt*/a
在那个时候变成了 i a
。
注释在程序翻译的第 3 阶段被删除1:每个注释被一个 space 字符替换。所以评论 /*nt*/
绝对不是令牌。
如果int
、none、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/**//////////////////////////////////////
但是上面的宏定义并没有定义一个function-like宏而是一个扩展为( a ) - 1
.
的常规宏STAT
变量名,就像任何其他标记一样,可以用转义的换行符分隔。转义换行符是序列或 \
紧跟换行符。这些序列在程序翻译的第 2 阶段从源代码中删除。它们的主要目的是打破多行的长宏定义。
下面是一个代码片段3,它产生相同的 14 个标记:
\
i\
nt\
ma\
in()
{\
i/\
*nt\
*/a \
= 10;
r\
et\
urn\
0;}
注意代码着色器是如何遗漏切片和切块的关键字和评论的:)
1) 此行为在 ANSI-C aka C89 中指定。一些古老的编译器在导致标记粘贴时有微妙的不同行为,但这些特性仅具有历史意义。
2) 利用程序翻译阶段 6 中相邻字符串常量连接这一事实,您几乎可以在字符串常量中插入注释:printf("Hello "/* my name is Luca */"world!\n");
3) 这种 圣诞树 表示风格并不意味着要在实际程序中使用,它说明了如何滥用 C 的输入处理能力。更精巧的花样赢了The International Obfuscated C Code Contest
看看你的代码是什么形式
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;
}
很明显,你可以断定这里有错误。
int main()
{
i/*nt*/a = 10;
return 0;
}
如果我有上面的代码,我想计算令牌数,是14个还是13个令牌?
在变量名中写注释有效吗?您可以假设 int i
、int a
、int ia
是全局定义的。
结果就像你写的一样:
i a = 10;
不是:
ia = 10;
从词法上看,一条注释和white是一样的space。
关于词汇元素的 C standard 第 6.4p3 节指出:
... Preprocessing tokens can be separated by white space; this consists of comments (described later), or white-space characters (space, horizontal tab, new-line,vertical tab, and form-feed), or both. ...
更具体地说,一条评论被翻译成一条 space。这在第 5.1.1.2p3 节中指定:
The source file is decomposed into preprocessing tokens and sequences of white-space characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment. Each comment is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined.
为了说明这一点,如果您通过预处理器传递代码,您将得到:
int main()
{
i a = 10;
return 0;
}
因此评论,如白色space,用于分隔标记。
这意味着代码将包含 14 个标记,而不是 13 个。
参见翻译(a.k.a. 编译)Phase 3,第 2 步:“每条评论由一个 space 个字符替换”。
所以,从概念上讲,i/*nt*/a
在那个时候变成了 i a
。
注释在程序翻译的第 3 阶段被删除1:每个注释被一个 space 字符替换。所以评论 /*nt*/
绝对不是令牌。
如果int
、none、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/**//////////////////////////////////////
但是上面的宏定义并没有定义一个function-like宏而是一个扩展为( a ) - 1
.
STAT
变量名,就像任何其他标记一样,可以用转义的换行符分隔。转义换行符是序列或 \
紧跟换行符。这些序列在程序翻译的第 2 阶段从源代码中删除。它们的主要目的是打破多行的长宏定义。
下面是一个代码片段3,它产生相同的 14 个标记:
\
i\
nt\
ma\
in()
{\
i/\
*nt\
*/a \
= 10;
r\
et\
urn\
0;}
注意代码着色器是如何遗漏切片和切块的关键字和评论的:)
1) 此行为在 ANSI-C aka C89 中指定。一些古老的编译器在导致标记粘贴时有微妙的不同行为,但这些特性仅具有历史意义。
2) 利用程序翻译阶段 6 中相邻字符串常量连接这一事实,您几乎可以在字符串常量中插入注释:printf("Hello "/* my name is Luca */"world!\n");
3) 这种 圣诞树 表示风格并不意味着要在实际程序中使用,它说明了如何滥用 C 的输入处理能力。更精巧的花样赢了The International Obfuscated C Code Contest
看看你的代码是什么形式
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;
}
很明显,你可以断定这里有错误。