switch中的while

 


来自csdn的一个问题:问题如下:

〉〉〉〉〉〉〉〉〉〉〉〉〉〉〉〉
请问那位高手能指明为什么while语句下的switch语句会执行和当i等于2时case 1:printf("i=%d,",i);语句又不执行了。希望能

将代码中while和switch将明白些

main()
{
int i,j;
printf("...../n");
for(i=0;i<3;i++)
{
j=3;
switch(i)
{
case 0:
while(j)
{
case 1:printf("i=%d,",i);
case 2:printf("j=%d,",j);j--;
default:;
}
}printf("...../n");
}
}

〈〈〈〈〈〈〈〈〈〈〈〈〈〈〈〈〈〈〈〈
下面是俺的回答,记录一下自己第一次使用汇编分析C代码:)

先看这个程序的输出:
//-----switch1.c----
int main()
{
int i=2;
    switch(i)
         {
          case 0:
          printf("case 0");
          case 1:
          printf("case 1");
          case 2:
          printf("case 2");
          case 3:
          printf("case 3");
          default:
          printf("case default");
         }
         getchar();
}

//OUTPUT:
case 2case 3 case default

说明了没有break的时候,如果switch找到了匹配的项,它将一直继续下去直到break或者switch终止。
于是我们回头看源程序:
//----------switch.c---------
main()
{
int i,j;
printf("...../n");
for(i=0;i<3;i++)
{
j=3;
switch(i)
{
case 0:
while(j)
{
case 1:printf("i=%d,",i);
case 2:printf("j=%d,",j);j--;
default:;
}
}printf("...../n");
}

getchar();
}

这里的for循环中i没有变化,所以i的值分别为 0 ,1,2
当i=0时进入for循环内部后:
case 0 匹配,所以后面的所有case都将被执行(因为没有break)
于是进入while循环:j进行递减直到=0。于是输出:i=0,j=3,i=0,j=2,i=0,j=1,.......
下一次循环i=1,此时case 0 不能匹配,但是进入while循环中的 case 1匹配了,于是输出类似于上面:
i=1,j=3,i=1,j=2,i=1,j=1,.......
i=2时,先匹配到的是case 2.于是输出为j=3,i=2,j=2,i=2,j=1,.......

为了更清楚地明白while在switch中的作用,我们精简了一下代码
//-switch.c---
main()
{
int i=1,j=3;
    switch(i)
        {
        case 0:
        while(j)
                {
        case 1:printf("i=%d,",i);
        case 2:printf("j=%d,",j);j--;
        default:;
                 }
        }
}

下面是汇编码:
 
 .file "switch.c"
gcc2_compiled.:
___gnu_compiled_c:
 .def ___main; .scl 2; .type 32; .endef
.text
LC0:
 .ascii "i=%d,/0"
LC1:
 .ascii "j=%d,/0"
 .align 4
.globl _main
 .def _main; .scl 2; .type 32; .endef
_main:
 pushl %ebp
 movl %esp,%ebp
 subl $24,%esp
 call ___main
 movl $1,-4(%ebp)         ;这两句为i和j赋值 i为-4(%ebp) j为-8(%ebp)
 movl $3,-8(%ebp)
 movl -4(%ebp),%eax    ;i到eax
 cmpl $1,%eax               ;i和1比较
 je L8                            ;相等跳到L8
 cmpl $1,%eax                ;i和1比较     
 jg L12                           ;大于跳到L12
 testl %eax,%eax     ;执行testl %eax,%eax可以用于判断eax中是否为零 
 je L4      ;是零跳到L4   
 jmp L10                  ;while 循环
 .p2align 4,,7
L12:                                      ;case 2
 cmpl $2,%eax
 je L9
 jmp L10
 .p2align 4,,7
L4:
 nop
 .p2align 4,,7
L5:
 cmpl $0,-8(%ebp)           ;while 条件
 jne L8
 jmp L3
 .p2align 4,,7
L7:
L8:                                                     ;L8为case 1 中执行的语句
 addl $-8,%esp
 movl -4(%ebp),%eax
 pushl %eax
 pushl $LC0
 call _printf
 addl $16,%esp
L9:                                                   ;L9为case 2中执行的语句
 addl $-8,%esp
 movl -8(%ebp),%eax
 pushl %eax
 pushl $LC1
 call _printf
 addl $16,%esp
 decl -8(%ebp)
L10:
 jmp L5
 .p2align 4,,7
L6:
L3:
L2:
 leave
 ret
 .def _printf; .scl 2; .type 32; .endef

看完这个因该可以明白它的调用顺序了吧。具体编译器如何运作的,还需要高人来解释:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值