【问题标题】:How does the below program output `C89` when compiled in C89 mode and `C99` when compiled in C99 mode?以下程序在 C89 模式下编译时如何输出“C89”,在 C99 模式下编译时如何输出“C99”?
【发布时间】: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”...

标签: c printf comments c99 c89


【解决方案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 是一回事。 stackoverflow.com/questions/17206568/…
      • 它们的意思是一样的,但不是同一个字符串。坚持我最初的问题。
      • @Pimgd 上述代码的目的不是为了满足一些人为的任务来打印给定格式的字符串。目的是演示IOCCC 之外的真实应用程序如何打印程序编译时使用的 C 版本。 C90 比“C89”或“ANSI-C”更正确。
      猜你喜欢
      • 1970-01-01
      • 2011-01-17
      • 2013-03-30
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 1970-01-01
      相关资源
      最近更新 更多