【问题标题】:Please explain the output to this code: [closed]请解释此代码的输出:[关闭]
【发布时间】:2017-09-21 16:55:55
【问题描述】:
#include<stdio.h>
void main()
{
   if(0xA)
   if(052)              
   if('\xeb')
   if('\012')              //what do the above 3 statements mean?
   printf("Hello World!")
   else;
   else;
   else;
   else;
 }

输出: 世界你好!

那么这里,052、\xeb和\012是什么意思呢? 以及多个 else 语句的意义是什么?

【问题讨论】:

  • 这段代码毫无意义——任何不是 0 的值都被认为是真的,所以那些 if 语句实际上都是相同的
  • 您是否丢失了调试器?
  • 请打开一本好的C书,学习一下语言。另外,上面的代码很垃圾。
  • 既然你问的是这个程序,我假设你没有写它。我可以建议你问作者他的意思吗?或者,如果你找不到作者,你能告诉我们你是在哪里找到这个程序的吗?
  • @N.Vakharia:立即把那本书扔进垃圾桶。如果这是一本备考书,那么它唯一让你准备的就是失败。

标签: c if-statement


【解决方案1】:

来自 C 标准(6.8.4.1 if 语句)

2 在这两种形式中,如果 表达式比较不等于 0。在 else 形式中,第二个 如果表达式比较等于 0,则执行子语句。如果 第一个子语句通过标签到达,第二个子语句是 未执行。

所以作为 if 语句中的每个表达式

   if(0xA)
   if(052)              
   if('\xeb')
   if('\012')

不等于0,然后调用函数printf(前提是分号存在)

printf("Hello World!");

被执行。

所以 if 语句没有多大意义。

0xA 是一个十六进制整数常量,等于十进制 10

052 是八进制整数常量,等于十进制 42

'\xeb' 是一个指定为十六进制转义序列的字符常量

'\012' 是指定为八进制转义序列的字符常量

考虑到根据 C 标准,不带参数的函数 main 应声明为

int main( void )

因此,由于 if 语句的每个表达式都不等于 0,那么程序实际上等价于以下程序

#include<stdio.h>

int main( void )
{
    printf("Hello World!");
}

【讨论】:

    【解决方案2】:

    这是一个技巧问题。大概有人认为你可以从中学到一些东西。想必这个人也觉得教孩子骑自行车的一个好办法就是把自行车的轮胎压扁,在路上放上大石块,然后随意给孩子粗暴的推到一边,因为这样“塑造性格” ,如果你能克服这些障碍学会骑自行车,你最终会成为一个真正优秀的自行车骑手。但我离题了。

    不管怎样,这里是对该代码中发生的事情的解释。

    0xA 是一个十六进制常量。它的值是 0A16,或 10(以 10 为底)。
    052 是八进制常数。它的值是 528 或 42(以 10 为底)。
    '\xeb' 是一个十六进制字符常量。它是一个值为 EB16 或 235(以 10 为基数)的字符(在 ISO-8859-1 或 Unicode 中最终是一个带有两个点的 e,ë)。
    '\012' 是一个普通的八进制字符常量。它是一个值为 128 或 10(以 10 为基数)的字符(在 ASCII 中最终是换行符,'\n')。

    当你说

    if( expr )
    

    在 C 中,如果表达式非零,则该表达式被视为“真”,如果为零,则该表达式被视为“假”。不用说,这四个常数都是非零的。

    C 中if 语句的完整语法是

    if( expr )
        statement-or-block
    

    if( expr )
        statement-or-block
    else
        statement-or-block
    

    其中statement-or-block 是单个语句,或者是包含在大括号{ } 中的多个语句的“块”(序列)。

    C 中一个很少使用的语法是“空语句”。如果你什么都没有,后跟一个分号,那是一个空语句,它确实......什么都没有。

    在礼貌的圈子中,缩进代码以描绘其结构被认为是强制性的。因此,呈现此代码的正常方式是:

    #include <stdio.h>
    
    int main()
    {
        if(0xA)
            if(052)              
                if('\xeb')
                    if('\012')
                        printf("Hello World!")
                    else
                        ;
                else
                    ;
            else
                ;
        else
            ;
    }
    

    同样,所有四个表达式的计算结果都立即为“真”。所以,在英语中,这段代码说“如果为真,那么如果为真,那么如果为真,那么如果为真,则打印'Hello world!',否则什么也不做,否则什么都不做,否则什么都不做,否则什么都不做。”

    这样说听起来很愚蠢,我知道。事实上,它在 C 中和在英语中一样愚蠢。

    附:除了奇怪和不必要的条件之外,发布的代码的另一个问题是,我已经悄悄地纠正了它,它将main 声明为void,这是礼貌圈子中没有做过的其他事情,并对此代码来自的书的有效性。

    【讨论】:

      【解决方案3】:

      您发布的代码相当于

      #include<stdio.h>
      
      int main( void ) // void main() is not a standard signature
      {
         if(0xA)
         {
           if(052)  
           {            
             if('\xeb')
             {
               if('\012')          
               {    
                 printf("Hello World!")
               }
               else
               {
               }
             }
             else
             {
             }
           }
           else
           {
           }
         }
         else
         {
         }
      }
      

      如果花括号中只有一条语句,则可以省略花括号:

      if ( a )
      {
        do_something();
      }
      

      可以写成

      if ( a )
        do_something();
      

      尽管我和其他人建议不要这样做,除非在特定情况下。

      if 语句本身算作一条语句,所以可以写

      if ( a )
      {
        if ( b )
          do_something();
      }
      

      作为

      if ( a )
        if ( b )
          do_something();
      

      当然,编译器并不关心缩进,所以

      if ( a )
      if ( b )
      do_something();
      

      意思是一样的——但是,正如您所发现的,以这种方式编写的代码有点难以理解。

      ifwhilefor 的测试条件可以是任何标量类型(整数、浮点或指针值)。 C 最初没有不同的布尔类型,因此规则是布尔上下文中的任何非零值计算为“真”,而零计算为“假”。

      0xA052'\xeb''\012' 中的每一个都是具有非零值的标量表达式(0xA052 分别是十六进制和八进制格式的整数文字,而'\xeb''\012' 是转义序列,表示十六进制和八进制格式的字符值),所以所有if 语句的主体都被执行。

      你有四个嵌套的if 语句,只有最里面的一个在做任何有趣的事情。 else 子句是空的,可以完全省略:

      #include<stdio.h>
      
      int main( void ) 
      {
         if(0xA)
         {
           if(052)  
           {            
             if('\xeb')
             {
               if('\012')          
               {    
                 printf("Hello World!")
               }
             }
          }
      }
      

      而且,正如我上面所说,花括号也可以省略:

      #include<stdio.h>
      
      int main( void ) 
      {
         if(0xA)
           if(052)  
             if('\xeb')
               if('\012')          
                 printf("Hello World!")
      }
      

      所有这些都归结为

      int main( void ) 
      {
        printf("Hello World!")
      }
      

      一个相当聪明的编译器根本不会为if 语句生成机器代码,并且应该生成机器代码就好像程序已经按照上面的方式编写了。

      【讨论】:

        猜你喜欢
        • 2019-12-30
        • 2014-09-24
        • 2015-07-13
        • 2015-05-11
        • 2016-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多