以下程序在 C89 模式下编译时如何输出“C89”,在 C99 模式下编译时如何输出“C99”?

     2023-02-21     240

关键词:

【中文标题】以下程序在 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__ &gt;= 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 中,“旧式”函数定义中函数名的范围是啥?

...围是什么?【发布时间】:2014-11-0717:37:48【问题描述】:以下C89是否合法?voidf(a)chara[sizeof&f];我的想法是肯定的,因为在任何块范围之外声明的 查看详情

在发布模式下编译时不会发出 QNetworkAccessManager 完成信号(VS 2005)

】在发布模式下编译时不会发出QNetworkAccessManager完成信号(VS2005)【英文标题】:QNetworkAccessManagerfinishedsignalisnotemittedwhencompiledinreleasemode(VS2005)【发布时间】:2011-01-2523:27:44【问题描述】:我有一个阅读网页的课程。在VisualStudio... 查看详情

UInt64 和“在检查模式下编译时操作溢出” - CS0220

】UInt64和“在检查模式下编译时操作溢出”-CS0220【英文标题】:UInt64and"Theoperationoverflowsatcompiletimeincheckedmode"-CS0220【发布时间】:2012-04-2709:00:25【问题描述】:这感觉像是一个愚蠢的问题,但我似乎看不到答案。我有一... 查看详情

使用 malloc (C89) 在 main() 之外初始化结构 [重复]

】使用malloc(C89)在main()之外初始化结构[重复]【英文标题】:Initializingastructoutsideofmain()usingmalloc(C89)[duplicate]【发布时间】:2017-05-1714:24:02【问题描述】:我正在尝试在C中实现一个双向链表,我需要使用一个初始化函数,同时保持... 查看详情

c89和c99中/运算符和%运算符为负数时的区别

运算式-8/5=-1.6,在C89中取值为-1或-2,C99的出现,CPU对除法的结果向零取整,上述运算式结果为-1。在C89和C99中都要确保(a/b)*b+a%b=a已知在C89中-8/5运算结果为-1或-2,根据公式,-8%5运算结果为-3或2在C99中-8/5结果位-1,那么-8%5j结果为... 查看详情

c89和c99标准有什么不同?

...,经过这么多年,依然是一门很热的编程语言。在TIOBE编程语言排行榜中,这几年C语言基本排名第一、第二,可以说问问的坐在前排。今天给大家分享一下C89和C99的区别。C标准历史C语言的发展至今超过了50年 查看详情

如果两种类型不相同,则导致 C89 中的编译错误

】如果两种类型不相同,则导致C89中的编译错误【英文标题】:CausecompilationerrorinC89iftwotypesarenotthesame【发布时间】:2013-02-0521:35:22【问题描述】:仅使用C89的特性,给定typedef[unspecifiedtokensequence]T1;typedef[anotherunspecifiedtokensequence]T... 查看详情

c89和c99标准有什么不同?

...,经过这么多年,依然是一门很热的编程语言。在TIOBE编程语言排行榜中,这几年C语言基本排名第一、第二,可以说问问的坐在前排。今天给大家分享一下C89和C99的区别。C标准历史C语言的发展至今超过了50年࿰... 查看详情

C89 和 C99 标准中可执行文件大小的差异 [关闭]

】C89和C99标准中可执行文件大小的差异[关闭]【英文标题】:DifferenceinExecutableSizeinC89andC99standards[closed]【发布时间】:2013-05-0717:32:33【问题描述】:我使用GCC制作了一个可执行文件$gccQ1.c-save-temps-std=c89-oQ1$sizeQ1textdatabssdechexfilename1... 查看详情

在 UWP 应用程序中使用 SafeFileHandle

...主要是在您按下保存按钮后退出应用程序时)。我尝试了以下代码,它在调试模式下按预期工作,但是当我尝试在发布模式下编译时,出现以下错误:C 查看详情

特定的初始化

...的数组的下标或结构体的成员名,并且GNUC也把这作为C89模式下的一个扩展。这个扩展没有在GNUC++中实现。为了指定一个数组下标,在元素值的前面写上“[index]=”。比如: inta[6]={[4]=29,[2]=15};相当于:&n 查看详情

c99中的restrict和c89的volatilekeyword

1、restrict它仅仅能够用于限定指针。告知编译器该指针是訪问一个数据对象的唯一且初始的方式。即不存在其他进行改动操作的途径。主要作用是能够让编译器进行一些优化,生成更高效的目标代码。看个样例:intfoo(int*a,int*b){ ... 查看详情

ASP.NET:如何在 DEBUG 模式下编译?

...“compilation”具有debug="false"时,通常的ASP.NET网站/Web应用程序打开到DEBUG模式。但我不清楚它是如何工作的。让我们考虑示例:我有&lt;compilati 查看详情

nvcc 在调试模式下编译失败:需要单个文件

...一切正常。在调试模式下,我在编译第一个.cu文件时收到以下错误消息:nvcc:致 查看详情

这个程序如何在调试模式下运行? [关闭]

...述】:我对今天看到的东西感到困惑在Linux终端中给出了以下命令:g++hw.cpp./a.out./a.outdebug第二条命令执行程序,输出“Hello,World”第三条命令似乎在调试模式下运行程序,并使相同的程序输出“将输出发送到终 查看详情

struct包装:如何在开头添加struct成员?

...图通过组合在所有节点结构之间共享公共属性。因此我有以下代码:enumfoo_typeFOO_TYPE_A,FOO_TYPE_B;structfooenumfoo_typet 查看详情

c中的除法,商和余数的大小符号如何确定(代码片段)

对于C中的除法,商和余数的大小、符号是如何确定的呢?在C89中,只规定了如果两个数为正整数,那么余数的符号为正,并且商的值是接近真实值的最大整数。比如5/2,那么商就是2,余数就是1。但是,C89里面对于被除数和除数... 查看详情

无法在 Win32 发布模式下编译 Qt 应用程序

】无法在Win32发布模式下编译Qt应用程序【英文标题】:CannotcompileQtapplicationinWin32releasemode【发布时间】:2014-03-0620:44:49【问题描述】:我有VS2012和QT插件。我可以在releasex64模式下编译,但是当我将设置更改为Win32并编译时,出现... 查看详情