选择结构:switch...case与if...else

一、switch…case 语句

switch(表达式)//float、double不可做参数
{ 
    case 常量表达式1:  语句1;//case后必须为常量
    case 常量表达式2:  语句2;
    … 
    case 常量表达式n:  语句n;
    default:  语句n+1;
}

(1)switch语句执行时由首个case开始,直至遇到break或’ }’结束;
(2)若case后未加break,程序会从满足条件的第一个case起执行下去到尾——直通性。
这里写图片描述
二、if…else 语句

if(判断表达式1)
{
     主体语句1;
}
else if(判断表达式2)
{
     主体语句2;
}
...

//嵌套
if(判断表达式1)
{
     if(判断表达式2)
     {
           主体语句1;
     }
     else 
     {
           主体语句2;
     }  
}
else 
{
     ...
}

(1)通过关系运算符判断表达式的真假来决定执行哪个分支,可嵌套使用;
(2)注意逻辑运算:
&&逻辑与:一假则假(遇假停止);
|| 逻辑或:一真则真(遇真停止)——>短路问题
这里写图片描述

三、二者区别

1、执行顺序:

1)switch…case语句:生成一份大小(表项数)为最大case常量+1(default情况)的跳转表,跳转表指示实际case分支的地址,其索引号与switch变量的值相等。
(1)判断switch变量是否大于最大case常量
(2)大于:跳到default分支处理
小于:取得索引号为switch变量大小的跳表项(即跳表起始地址+表项大小*索引号),跳到此地址执行
(3)完成分支跳转

2)if…else 语句:从上到下执行
(1)程序判断条件成立与否
(2)成立:执行相应的的主体语句,忽略后面的else if和else
不成立:跳过,转至离此if最近的else if语句,再次判断

2、表达式:

switch语句的控制表达式只能是某个整形(int,char,long等)或string;
其他任何类型(包括float和double类型)只能用if语句,但 if需显示给定判断式

3、性能:switch性能略胜于if语句

(1)执行主体语句情况:
if语句:若判断为真则只执行这个判断后的语句,执行完就跳出if语句,不会执行其他if语句;
switch语句:若case后不加break时,不会在执行判断为真后的语句之后跳出循环,而是继续执行后面所有case语句。因此,在每一case语句之后增加break 语句,使每一次执行之后均可跳出switch语句,从而避免输出不应有的结果
(2)判断次数:
switch语句:直接跳转,正常情况下只需判断一次;
if语句:当条件比较多时,可能会判断直至最后一个才符合,故要判断至少一次。

void main()
{
    switch(3)
    {
    case 1: printf("one\n");
        break;
    case 2: printf("two\n");
        break;
    case 3: printf("three\n");
        break;
    case 4: printf("four\n");
        break;
    case 5: printf("five\n");
        break;
    default:
        break;
    }
    getchar();
}

//反汇编
void main()
{
00C113D0  push        ebp  
00C113D1  mov         ebp,esp  
00C113D3  sub         esp,0C4h  
00C113D9  push        ebx  
00C113DA  push        esi  
00C113DB  push        edi  
00C113DC  lea         edi,[ebp-0C4h]  
00C113E2  mov         ecx,31h  
00C113E7  mov         eax,0CCCCCCCCh  
00C113EC  rep stos    dword ptr es:[edi]  
    switch(3)
00C113EE  mov         dword ptr [ebp-0C4h],3  
00C113F8  mov         eax,dword ptr [ebp-0C4h]  
00C113FE  sub         eax,1  
00C11401  mov         dword ptr [ebp-0C4h],eax  
00C11407  cmp         dword ptr [ebp-0C4h],4  
00C1140E  ja          $LN6+7Bh (0C1149Ch)  
00C11414  mov         ecx,dword ptr [ebp-0C4h]  
00C1141A  jmp         dword ptr [ecx*4+0C114C4h]  
    {
    case 1: printf("one\n");
00C11421  mov         esi,esp  
00C11423  push        0C15858h  
00C11428  call        dword ptr ds:[0C192BCh]  
00C1142E  add         esp,4  
00C11431  cmp         esi,esp  
00C11433  call        __RTC_CheckEsp (0C11136h)  
        break;
00C11438  jmp         $LN6+7Bh (0C1149Ch)  
    case 2: printf("two\n");
00C1143A  mov         esi,esp  
00C1143C  push        0C15860h  
00C11441  call        dword ptr ds:[0C192BCh]  
00C11447  add         esp,4  
00C1144A  cmp         esi,esp  
00C1144C  call        __RTC_CheckEsp (0C11136h)  
        break;
00C11451  jmp         $LN6+7Bh (0C1149Ch)  
    case 3: printf("three\n");
00C11453  mov         esi,esp  
00C11455  push        0C15868h  
00C1145A  call        dword ptr ds:[0C192BCh]  
00C11460  add         esp,4  
00C11463  cmp         esi,esp  
00C11465  call        __RTC_CheckEsp (0C11136h)  
        break;
00C1146A  jmp         $LN6+7Bh (0C1149Ch)  
    case 4: printf("four\n");
00C1146C  mov         esi,esp  
00C1146E  push        0C15870h  
00C11473  call        dword ptr ds:[0C192BCh]  
00C11479  add         esp,4  
00C1147C  cmp         esi,esp  
00C1147E  call        __RTC_CheckEsp (0C11136h)  
        break;
00C11483  jmp         $LN6+7Bh (0C1149Ch)  
    case 5: printf("five\n");
00C11485  mov         esi,esp  
00C11487  push        0C15878h  
00C1148C  call        dword ptr ds:[0C192BCh]  
00C11492  add         esp,4  
00C11495  cmp         esi,esp  
00C11497  call        __RTC_CheckEsp (0C11136h)  
        break;
    default:
        break;
    }
    getchar();
00C1149C  mov         esi,esp  
00C1149E  call        dword ptr ds:[0C192C0h]  
        break;
    default:
        break;
    }
    getchar();
00C114A4  cmp         esi,esp  
00C114A6  call        __RTC_CheckEsp (0C11136h)  
}
00C114AB  xor         eax,eax  
00C114AD  pop         edi  
00C114AE  pop         esi  
00C114AF  pop         ebx  
00C114B0  add         esp,0C4h  
00C114B6  cmp         ebp,esp  
00C114B8  call        __RTC_CheckEsp (0C11136h)  
00C114BD  mov         esp,ebp  
00C114BF  pop         ebp  
00C114C0  ret  
00C114C1  lea         ecx,[ecx]  
00C114C4  and         dword ptr [ecx+eax*8],edx  
00C114C7  add         byte ptr [edx],bh  
00C114C9  adc         al,0C1h  
00C114CB  add         byte ptr [ebx+14h],dl  
00C114CE  rol         dword ptr [eax],6Ch  
00C114D1  adc         al,0C1h  
00C114D3  add         byte ptr [ebp-0FF3EECh],al 

猜你喜欢

转载自blog.csdn.net/qq_39191122/article/details/79777922