为什么显示红色的else无配对的if?

img


为什么显示那个else没有配对的if?这个是求二次方程的程序

img


上面的if后面多了个分号

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/192926
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:策略模式解决多级if 、else if嵌套问题
  • 除此之外, 这篇博客: 计算机组成原理之指令和运算(一)中的 从 if…else 来看程序的执行和跳转 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • #include <time.h>
    #include <stdlib.h>
    int main()
    {
      srand(time(NULL));
      int r = rand() % 2;
      int a = 10;
      if (r == 0)
      {
        a = 1;
      } else {
        a = 2;
      } 
    }
    

    在这里插入图片描述
    if…else 条件判断语句。对应的汇编代码是这样的:

    if (r == 0)
      33:	83 7d fc 00          	cmp    DWORD PTR [rbp-0x4],0x0
       /*
       cmp 指令比较了前后两个操作数的值,这里的 DWORD PTR 代表操作的数据类型是 32 位的整数,而 [rbp-0x4] 则是一个寄存器的地址。所以,
       第一个操作数就是从寄存器里拿到的变量 r 的值。第二个操作数 0x0 就是我们设定的常量 0 的 16 进制表示。cmp 指令的比较结果,会存入到
       条件码寄存器当中去。
    
       如果比较的结果是 True,也就是 r == 0,就把零标志条件码(对应的条件码是 ZF,Zero Flag)设置为 1。除了零标志之外,Intel 的 CPU
        下还有进位标志(CF,Carry Flag)、符号标志(SF,Sign Flag)以及溢出标志(OF,Overflow Flag),用在不同的判断条件下。
      */
      37:	75 09                	jne    42 <main+0x42>
      /*
        jne 指令,是 jump if not equal 的意思,它会查看对应的零标志位。如果为 0,会跳转到后面跟着的操作数 42 的位置。这个 42,对应这
        里汇编代码的行号,也就是上面设置的 else 条件里的第一条指令。当跳转发生的时候,PC 寄存器就不再是自增变成下一条指令的地址,而是被
        直接设置成这里的 42 这个地址。这个时候,CPU 再把 42 地址里的指令加载到指令寄存器中来执行。
      */
      {
        a = 1;
      39:	c7 45 f8 01 00 00 00 	mov    DWORD PTR [rbp-0x8],0x1
      40:	eb 07                	jmp    49 <main+0x49>
      /*
       if 条件,如果满足的话,在赋值的 mov 指令执行完成之后,有一个 jmp 的无条件跳转指令。跳转的地址就是这一行的地址 49。我们的 main 函
       数没有设定返回值,而 mov eax, 0x0 其实就是给 main 函数生成了一个默认的为 0 的返回值到累加器里面。if 条件里面的内容执行完成之后也
       会跳转到这里,和 else 里的内容结束之后的位置是一样的。
      */
      } else {
        a = 2;
      42:	c7 45 f8 02 00 00 00 	mov    DWORD PTR [rbp-0x8],0x2
      /*
        跳转到执行地址为 42 的指令,实际是一条 mov 指令,第一个操作数和前面的 cmp 指令一样,是另一个 32 位整型的寄存器地址,以及对应的2
        的16进制值 0x2。mov 指令把 2 设置到对应的寄存器里去,相当于一个赋值操作。然后,PC 寄存器里的值继续自增,执行下一条 mov 指令
      */
      }
      return 0;  
      49:	b8 00 00 00 00       	mov    eax,0x0
      /*
       这条 mov 指令的第一个操作数 eax,代表累加寄存器,第二个操作数 0x0 则是 16 进制的 0 的表示。这条指令其实没有实际的作用,它的作用
       是一个占位符。
      */
    }
      4e:	c9                   	leave  
      4f:	c3                   	ret    
    

    在这里插入图片描述

    • 条件码寄存器会记录下当前执行指令的条件判断状态,然后通过跳转指令读取对应的条件码,修改 PC 寄存器内的下一条指令的地址,最终实现 if…else 以及 for/while 这样的程序控制流程。
    • 汇编指令的文档:http://www.unixwiz.net/techtips/x86-jumps.html