以下程序在 C89 模式下编译时如何输出“C89”,在 C99 模式下编译时如何输出“C99”?
Posted
技术标签:
【中文标题】以下程序在 C89 模式下编译时如何输出“C89”,在 C99 模式下编译时如何输出“C99”?【英文标题】:How does the below program output `C89` when compiled in C89 mode and `C99` when compiled in C99 mode? 【发布时间】:2015-09-15 21:40:18 【问题描述】:我从网上找到了这个 C 程序:
#include <stdio.h>
int main()
printf("C%d\n",(int)(90-(-4.5//**/
-4.5)));
return 0;
这个程序的有趣之处在于,当它在 C89 模式下编译和运行时,它会打印出C89
,而当它在 C99 模式下编译和运行时,它会打印出C99
。但我无法弄清楚这个程序是如何工作的。
您能解释一下printf
的第二个参数在上述程序中是如何工作的吗?
【问题讨论】:
提示:C++ 风格的//
注释是在 C99 中引入的。
不错的技巧 - 但它失败了 gcc
。如果没有std=c99
,您将收到警告,如果您忽略它,gcc
将仍然将//
解释为评论的开头(啊——您必须使用-pedantic
作为好吧。我默认开启。)
@Jongware 好吧,我在 gcc 4.9.2 中得到了 C89
和明确的 std=c89
。
以防有人在寻找测试 C99 支持的方法时发现此问题;请使用 #if __STDC_VERSION__ >= 199901L
之类的东西,而不是 //
评论技巧。 =)
它还为 C11 打印“C99”...
【参考方案1】:
C99 允许 //
样式的 cmets,C89 不允许。所以,翻译:
C99:
printf("C%d\n",(int)(90-(-4.5 /*Some comment stuff*/
-4.5)));
// Outputs: 99
C89:
printf("C%d\n",(int)(90-(-4.5/
-4.5)));
/* so we get 90-1 or 89 */
【讨论】:
【参考方案2】:行注释//
从 C99 开始引入。因此,您的代码在 C89 中与此相同
#include <stdio.h>
int main()
printf("C%d\n",(int)(90-(-4.5/
-4.5)));
return 0;
/* 90 - (-4.5 / -4.5) = 89 */
在 C99 中等于这个
#include <stdio.h>
int main()
printf("C%d\n",(int)(90-(-4.5
-4.5)));
return 0;
/* 90 - (-4.5 - 4.5) = 99*/
【讨论】:
【参考方案3】:因为//
cmets只存在于C99及以后的标准中,所以代码相当于如下:
#include <stdio.h>
int main (void)
int vers;
#if __STDC_VERSION__ >= 201112L
vers = 99; // oops
#elif __STDC_VERSION__ >= 199901L
vers = 99;
#else
vers = 90;
#endif
printf("C%d", vers);
return 0;
正确的代码是:
#include <stdio.h>
int main (void)
int vers;
#if __STDC_VERSION__ >= 201112L
vers = 11;
#elif __STDC_VERSION__ >= 199901L
vers = 99;
#else
vers = 90;
#endif
printf("C%d", vers);
return 0;
【讨论】:
你的答案中出现了一个错误,当它应该打印 89 时你如何得到 90? @Pimgd C89 和 C90 是一回事。 ***.com/questions/17206568/… 它们的意思是一样的,但不是同一个字符串。坚持我最初的问题。 @Pimgd 上述代码的目的不是为了满足一些人为的任务来打印给定格式的字符串。目的是演示IOCCC 之外的真实应用程序如何打印程序编译时使用的 C 版本。 C90 比“C89”或“ANSI-C”更正确。以上是关于以下程序在 C89 模式下编译时如何输出“C89”,在 C99 模式下编译时如何输出“C99”?的主要内容,如果未能解决你的问题,请参考以下文章
在发布模式下编译时不会发出 QNetworkAccessManager 完成信号(VS 2005)