请解释此代码的输出:

时间:2017-09-21 16:55:55

标签: c if-statement

#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;
 }

输出:    Hello World!

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

3 个答案:

答案 0 :(得分:3)

来自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!");
}

答案 1 :(得分:0)

这是一个棘手的问题。大概有人认为你可以从中学到一些东西。据推测,这个人还认为教孩子骑自行车的好方法是将自行车的轮胎弄平,然后把大石头放在路上,并随意给孩子一个粗糙的推力,因为它“塑造了性格”如果你可以学习骑自行车尽管有这些障碍,你最终将成为一个非常好的自行车骑手。但我离题了。

无论如何,这里是对该代码中发生的事情的解释。

0xA是十六进制常量。它的值为0A 16 或10(base 10) 052是八进制常量。它的值为52 8 或42(base 10) '\xeb'是十六进制字符常量。它是一个值为EB 16 或235(基数为10)的字符(在ISO-8859-1或Unicode中最终为e,上面有两个点,ë)。
'\012'是一个普通的八进制字符常量。它是一个值为12 8 或10(基数为10)的字符(在ASCII中最终为换行符'\n')。

当你说

if( expr )

在C中,表达式如果非零则表示为“true”,如果为零则表示“false”。不用说,这四个常数都是非零的。

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
        ;
}

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

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

P.S。除了奇怪的和不必要的条件之外,我已经悄悄纠正的代码发布的另一个问题是,它将main声明为void,这是在礼貌的圈子中没有做的其他事情,并且抛出进一步怀疑这个代码来自的书的有效性。

答案 2 :(得分:0)

您发布的代码等同于

#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最初没有明确的布尔类型,因此规则是布尔上下文中的任何非零值计算为“true”,而零的计算结果为“false”。

0xA052'\xeb''\012'中的每一个都是一个非零值的标量表达式(0xA和{{1}分别是十六进制和八进制格式的整数文字,而052'\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!") } 语句生成机器代码,并且应该生成机器代码,好像程序已经如上所述。