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

标签 c lexical-analysis

int main()
{
     i/*nt*/a = 10;
     return 0;
}
如果我有上面的代码并且我想计算 token ,它是14个 token 还是13个 token ?
在变量名中写注释是否有效?您可以假设 int i , int a , int ia是全局定义的。

最佳答案

注释在程序翻译 1 的第 3 阶段被删除:每个注释被一个空格字符替换。所以评论/*nt*/绝对不是 token 。
如果没有 int , main , i , areturn定义为预处理宏,解析程序产生 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 .
变量名,就像任何其他标记一样,可以被转义的换行符分割。转义的换行符是序列或 \紧随其后的是换行符。这些序列在程序翻译的第 2 阶段从源代码中删除。它们的主要目的是在多行上打破长宏定义。
下面是产生相同 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 的输入处理能力。更精致的花样赢了The International Obfuscated C Code Contest

关于我们可以在变量名中写注释吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63609077/

相关文章:

c - 比较和交换的工作原理

C歧义问题

c - 按标签拆分 html

c - 内核设备驱动程序 "dereferencing ' void *' 指针

operators - OCaml 中的扫描和负整数文字

c - File* 和 Char* 相同还是有区别?

python - 解析 Python 函数调用以获取参数位置

Python - 词法分析和分词

compiler-construction - 词法分析器的目的是什么?

parsing - 与 Alex 和 Happy 一起管理职位信息