测试编译器是否允许注释嵌套的程序
2014-10-26 01:05
295 查看
问题:某些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;
}
如果编译器不支持注释嵌套,输出结果为:
*/ */
/* " /* " */ " */ " /* " /* " */ " */ "会变成:“*/” “*/”,画底线部分会被注释掉。
如果编译器支持注释嵌套,输出结果为:
/* " /* " */ " */
/* " /* " */ " */ " /* " /* " */ " */ "会变成:" /* " /* " */ " */ ",画底线部分会被注释掉。
对允许嵌套注释的编译器,还是对不允许嵌套注释的编译器,该程序都
能正常通过编译(无错误消息出现), 但是这两种情况下程序执行的结果
却不相同。
提示: 在用双引号括起的字符串中, 注释符 /* 属于字符串的一部分,而
在注释中出现的双引号“ ”又属于注释的一部分。
出至——《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;
}
如果编译器不支持注释嵌套,输出结果为:
*/ */
/* " /* " */ " */ " /* " /* " */ " */ "会变成:“*/” “*/”,画底线部分会被注释掉。
如果编译器支持注释嵌套,输出结果为:
/* " /* " */ " */
/* " /* " */ " */ " /* " /* " */ " */ "会变成:" /* " /* " */ " */ ",画底线部分会被注释掉。
相关文章推荐
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL
- 无论程序是否安装,都使setup.exe直接进入安装状态,不出现反安装;以及由此延伸出的同一安装程序允许在同一机器上安装多套软件的探讨
- C# WinForm 判断程序是否已经在运行,且只允许运行一个实例,附源码
- C陷阱与缺陷:如何判断编译器是否支持嵌套注释?
- C# WinForm 判断程序是否已经在运行,且只允许运行一个实例,附源码
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)
- winform 判断程序是否已经运行,提示“只允许运行一个程序”
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL
- 练习1-23:编写一个删除C语言程序中所有的注释语句。要正确处理带引号的字符串与字符常量。在C语言程序中,注释不允许嵌套
- 利用栈写一个程序, 检验文本中的圆括号、方括号、花括号是否正确嵌套.
- 007、判断手机操作系统是否允许运行程序
- 【1-23】编写一个删除C语言程序中所有的注释语句。要正确处理带引号的字符串与字符常量。再c语言中,注释不允许嵌套。
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL
- 判断手机操作系统版本是否允许运行程序
- WinForm判断程序是否已经在运行,且只允许运行一个实例
- 測试编译器是否同意凝视嵌套的程序
- ASP程序中同一个用户不允许同时登陆两次
- ·程序人生·征文活动:《无响应,是否重启人生》