首页 > 代码库 > 测试编译器是否允许注释嵌套的程序

测试编译器是否允许注释嵌套的程序

问题:某些C编译器允许嵌套注释。请写一个测试程序,要求:无论是

对允许嵌套注释的编译器,还是对不允许嵌套注释的编译器,该程序都

能正常通过编译(无错误消息出现), 但是这两种情况下程序执行的结果

却不相同。

 提示: 在用双引号括起的字符串中, 注释符 /* 属于字符串的一部分,而

在注释中出现的双引号“ ”又属于注释的一部分。

                                           出至——《C陷阱与缺陷》练习1-1

解答:

 如果只是测试编译器是否允许注释嵌套,那么由提示很容易写出程序:

程序一:

#include<iostream>

int main()
{

 std::cout << /* " /*  */ " */    “*/" << std::endl;

 return 0;

}

如果编译器允许注释嵌套,那么程序会编译成功,程序执行结果为: */

字符串“*/"前面的部分/* ”/* */“ */会直接被其最外层的注释对给注释掉。

如果编译器不允许注释嵌套,那么程序编译时时会报错,因为

/* ”/* */” */  ” */“会变成 字符串"*/"和 */“,编译器无法识别*/”,所以会报错。

如果将程序写成这样:

程序二:

#include<stdio.h>

int main()

{

 std::cout << /* " /* */ " */ " <<std::endl;

 return 0;

}

如果编译器允许注释嵌套,那么程序会在编译时报错,因为此时

/* " /* */ " */ " 会变成 ",编译器无法识别。

如果编译器不允许注释嵌套,那么程序会编译成功,程序运行结果为:*/

第一个/*会与遇到的第一个*/形成注释对,将两者之间的内容 "/*注释掉,

只留下字符串"*/"


程序一与程序二都无法满足同时通过两种编译器的条件,究其原因,是因为

/*与*/或者遵循就近匹配,此时编译器支持注释嵌套,或者遵循优先匹配,此时

*/与最需要匹配的/*进行匹配,此时编译器不支持注释嵌套。而且双引号"与"遵循

就近匹配原则。这就导致当程序通过一个编译器时,就无法通过另一个编译器,

总是会在程序无法通过编译器时产生符号冗余。

 所以最根本的问题就是想办法消除程序中的符号冗余,想了好几种方法,都未成功,

最后想到用数学中的对称思维,既然一个这样的式子产生一个符号冗余,那再添加一个

式子,产生另一个符号冗余,两个冗余的符号组合在一起,就会形成一个新的注释对

或者一个字符串,这样就可以使得程序同时通过两种编译器。

程序如下:

程序三:

#include<stdio.h>

int main()

{

 std::cout <<  /* " /* " */ " */ " /* " /* " */ " */ "<< std::endl;

 return 0;

}

如果编译器不支持注释嵌套,输出结果为:

  */ */

/* " /* " */ " */ " /* " /* " */ " */ "会变成:“*/” “*/”,画底线部分会被注释掉。

如果编译器支持注释嵌套,输出结果为:

 /* " /* " */ " */

/* " /* " */ " */ " /* " /* " */ " */ "会变成:" /* " /* " */ " */ ",画底线部分会被注释掉。




测试编译器是否允许注释嵌套的程序