代码之家  ›  专栏  ›  技术社区  ›  Sadique

同时执行if和else块

  •  6
  • Sadique  · 技术社区  · 16 年前

    在C或C++中

    if ( x )
        statement1;
    else
        statement2;
    

    为了什么价值 x 两个语句都将被执行吗?

    我知道我们可以执行 if-else 就像这样:

    if(1){
        goto ELSE;
    }
    else{
        ELSE:
    }
    

    有没有什么方法,比如价值观? (我认为这是不可能的。问是因为有人在争论!)

    13 回复  |  直到 7 年前
        1
  •  15
  •   Konrad Rudolph    16 年前

    对于x的值,两个语句都将被执行?

    没有这样的值:值的计算结果为 true (什么事!=0),或其计算结果为 false (0)。不存在其他可能的值。

    我知道我们可以像这样一起执行:如果(1)转到其他位置;其他位置其他位置:

    这是可行的,但这并不取决于 if 条件。

        2
  •  24
  •   SigTerm    16 年前

    对于x的值,两个语句都将被执行??

    仅在这种情况下(在类Unix系统上):

     pid_t  pid;
     pid = fork();
     if (pid == 0){
        //some code
     }
     else {
        //some code
     }
    

    在这种情况下,两个分支总是同时调用(好吧,或多或少是同时调用),但在不同的过程中。

    我知道我们可以这样一起执行:

    这是:

    if(1){
        goto ELSE;
    }
    else{
        ELSE:
    }
    

    是错误的构造。你需要用这样的方法来代替:

    if ( condition) {
        //some code here
        ...
    }
    ... //some other code here
    

    如果总是调用一个分支,那么就不需要“else”。

        3
  •  4
  •   Johannes Schaub - litb    16 年前

    如果你不介意一些未定义的行为,你可以在C++中这样做:

    struct J {
      jmp_buf b;
    };
    
    struct backer {
      backer(int v):did(v) { }
    
      backer(backer const& o):j(o.j),did(o.did) { 
        o.did = true; 
      }
    
      ~backer() {
        if(!did) {
          longjmp(j.b, 1);
        }
      }
    
      operator bool() {
        return !did;
      }
    
      J j;
      mutable bool did;
    };
    
    int main() {
      if(backer b = setjmp(b.j.b)) {
        std::cout << "a";
      } else {
        std::cout << "b";
      }
    }
    

    这对GCC和Clang很好。它通过呼叫 setjmp 在缓冲区上 b.j.b . 该缓冲区被包装在一个类中,因为它可以是一个数组,并且只有当数组包装在一个类中时,才能复制数组。 backer 的构造函数 塞特姆 的返回值并初始化 did 有了它。在 靠山 的析构函数,测试该标志是否为false(第一次返回 塞特姆 )它跳回来,让 塞特姆 返回一个非零值。的析构函数 靠山 当其中一个分支完成时调用。

    编译器可以自由复制 靠山 初始化时构造的对象 b . 如果发生这种情况,它的复制构造函数将关心设置 做 到 true ,确保即使编译器没有优化 靠山 初始化时复制。

    因此程序打印 ab .

        4
  •  2
  •   josefx    16 年前

    在递归函数中,两个分支都可以执行:

    void recursive(bool first)
    {
        if(first)
        {
            recursive(false);
        }
        else
        {
            //END
        }
    }
    

    用调用它

    recursive(true)
    

    将执行if分支,后跟else分支

        5
  •  2
  •   Mark Rushakoff    16 年前

    首先,这不是一个愚蠢的问题。)

    为了理解为什么您不能用任何特殊的技巧来完成这一点,我们需要逐步使用由if语句生成的程序集(尤其是使用gcc 4.2.1的Intel处理器的程序集——不同的体系结构将导致不同的程序集)。

    以这个简单的C程序为例:

    #include <stdio.h>
    
    int main()
    {
        int i;
        scanf("%d", &i);
        if (i == 8)
        {
            return 100;
        }
        else
        {
            return 3;
        }
    }
    

    如果用户输入非零整数,则返回100;否则返回3。实际情况在这里并不重要,因为我们只对为生成的程序集感兴趣 main :

            ; ...
            call    _scanf
            movl    -4(%rbp), %eax
            cmpl    $8, %eax
            jne     L2
            movl    $100, -20(%rbp)
            jmp     L4
    L2:
            movl    $3, -20(%rbp)
    L4:
            movl    -20(%rbp), %eax
            leave
            ret
    

    我假设您不知道组装——但别担心,这个例子并不难跟上。这里发生的是我们 call scanf 我们 compare 它的结果( i )8。

    接下来,有一个 J 如果有 N OT E 标签L2的QUAL指令。这意味着如果 我 等于8,执行以下指令:

    • 移动3 rbp
    • 移动 RBP 进入之内 eax
    • 离开(从而从程序返回值3)。

    然而,如果 我 是 不 等于8,然后当我们击中 jne 指令,我们不跳。相反,我们:

    • 移动100 RBP
    • J U mp 无条件地贴在标签L4上
    • 移动 RBP 进入之内 埃克斯 最后从程序中返回100。

    在这里生成程序集后,实际上只有两个可能的分支。您不能随意重新排序代码。

    那么,是否可以执行两个分支(当它们不同时执行时) return 陈述)?是的,前提是编译器无法正确生成分支代码。但在生产级编译器上永远不会发生这种情况。

        6
  •  0
  •   Antal Spector-Zabusky    16 年前

    没有诡计,不,这是不可能的。考虑该表达式的含义:

    if (cond) {
      ifTrue;
    } else {
      ifFalse;
    }
    

    这表示要执行 ifTrue 如果 cond 为真(非零值/ true )和执行 ifFalse 如果 康德 是假的(零) false )自从 康德 不能同时为真和假,不能同时执行两者 如果是真的 和 iffalSE 没有特殊情况,例如 goto .

        7
  •  0
  •   Mat    16 年前

    您可以使用整数作为测试变量,并使用>、<、>=、<=、<=、,检查其值。==

        int x = 0;
    
        if ( x >= 0 ) {
            statement 1;
        }
        if ( x <= 0 ) {
            statement 2;
        }
    

    在本例中,两个语句都只在x为0时执行。否则就只有一个了。

        8
  •  0
  •   Johannes Schaub - litb    9 年前

    如果这是一个技巧问题,你可以回答

    if( ({ statement2; 1; }) ) 
      statement1;
    else
      statement2;
    

    使用gcc语句表达式:)对于表达式语句,有逗号运算符

    if(expr2, 1) 
      expr1;
    else
      expr2;
    

    这是一个 quite popular question .

        9
  •  0
  •   John Bode    16 年前

    没有 单一的 价值观 x 将为其执行条件语句的所有路径(这是 指向 条件语句;要执行一个分支 或 另一个基于 X )

    然而。。。

    在C(和C++)中,可以使用 setjmp / longjmp 用于执行 if - else :

    #include <setjmp.h>
    #include <stdio.h>
    
    jmp_buf Env;
    
    int main(void)
    {
      int status = setjmp(Env);
      if (status == 0)
      {
        printf("In status == 0 branch\n");
        longjmp(Env,1);
      }
      else
      {
        printf("In status != 0 branch\n");
      }
      return 0;
    }
    

    最初的呼叫 塞特姆 返回0,因此取第一个分支。呼唤 朗普 将堆栈展开回 塞特姆 调用返回,但这次返回值为1(第二个参数 朗普 ,所以取第二个分支。但是,这是 不 和 status 同时计算为0和非0。

    在实践中,它类似于写作

    for (status = 0; status < 2; status++)
    {
      if (status == 0)
        printf("In status == 0 branch\n");
      else
        printf("In status != 0 branch\n");
    }
    

    尽管语义不同。

    你可能会用C++做一些类似的丑陋的事情,但是我没有足够的C++专家来确定。

        10
  •  0
  •   Thomas Matthews    16 年前

    对于单语句情况,只执行其中一个语句,而不是同时执行这两个语句。这是对 if .

    然而 ,如果是 如果 语句使用复合语句(也称为语句块),编译器可以优化代码以从 then 语句中的重复语句 else 块。

    例子:

    #include <iostream>
    using namespace std;
    
    int main(void)
    {
      static const char common_text1[] = "Some common text here.\n";
      static const char common_text2[] = "Even more common code here.\n";
      if (true)
      {
         cout << "Condition is true.\n";
         cout << common_text1;  // Execution may jump to same line below.
         cout << common_text2;
      }
      else
      {
         cout << "\nCondition is false.\n";
         cout << common_text1;  // This line and the next may be executed when the
         cout << common_text2;  //   condition is true.
      }
      return 0;
    }
    

    在上面的示例中,编译器可以生成代码,以便在条件为 true ,中的第一个语句 真 然后执行块 执行跳转到公共语句 在 其他的 块。

    编译器正在重写代码:

      if (true)
      {
         cout << "Condition is true.\n";
      }
      else
      {
         cout << "\nCondition is false.\n";
      }
    
      // The compiler factored-out the common statements.
      cout << common_text1; 
      cout << common_text2;
    

    当编译器在两个条件的语句块末尾附近看到重复语句时,可能会发生这种情况。

        11
  •  0
  •   drawnonward    16 年前
    switch ( x ) {
    default: // if ( x )
      // stuff
      // no break
    case 0: // else
      // more stuff
      break;
    }
    

    或者更简单

    if ( x ) {
      // stuff
    }
    // more stuff
    
        12
  •  0
  •   Andronicus    7 年前

    您可以使用:

    #include <stdio.h> 
    int main() 
    { 
    if (//some condition//)
    { 
        IF:{
        printf("Hello "); //Code for if block.
         } 
        goto ELSE;
    } 
    else
    {  
        goto IF;
        ELSE:{
          printf("world");//code for else block.
             }
    }
    return 0; 
    } 
    

    输出: Hello world

        13
  •  -1
  •   Umang    16 年前

    下面是一个简单的例子:

    #include <stdio.h>
    
    int main() {
        int x;
        x = 6;
        if (x % 2 == 0) {
            printf("Divisible by two\n");
        }
        else if (x % 3 == 0) {
            printf("Divisible by three\n");
        }
        else {
            printf("Not divisible by two or three\n");
        }
        return 0;
    }
    

    印刷品

    Divisible by two
    

    不是

    Divisible by two
    Divisible by three
    
    推荐文章