一、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