C语言中switch和case之间的语句是否执行?(答案:不执行)

前几天有一个同事询问,switch和case语句中间的代码是否会执行?

本能的认为,不会被执行!!

又想了一下原理,从汇编的角度,无论是switch还是if,最后的汇编代码都是一条条判断语句。

只是在C语言语法上有不同的写法而已,所以我要证明一下我的想法。

一、首先,写一段测试代码:

#include <string.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
	unsigned int uiSwitch;
	
	for(uiSwitch = 0;uiSwitch < 5;uiSwitch++)
	{
		switch(uiSwitch)
		{
			/* 下面这行Log是否会输出呢? */
			printf("This is no output log \r\n");
			
			case 0:
				printf("This is %d \r\n",uiSwitch);
				break;
			case 1:
				printf("This is %d \r\n",uiSwitch);
				break;
			case 2:
				printf("This is %d \r\n",uiSwitch);
				break;
			case 3:
				printf("This is %d \r\n",uiSwitch);
				break;
			default:
				printf("This is default %d \r\n",uiSwitch);
				break;
		}
	}
	
	return 0;
}

当然,最后执行结果,没有那行Log的输出,如下:

This is 0
This is 1
This is 2
This is 3
This is default 4

二、让我们看看汇编代码:

因为switch语句只有4个case,所以有4个cmp判断语句,用来比较后跳转到对应的case代码中。

当所有cmp的判断都没有成立的情况下,执行default处理中的jmp指令。

所以,switch和case中间的语句不会执行,并且都不生成汇编代码,属于代码Miss。

  400541:	8b 45 fc             	mov    -0x4(%rbp),%eax
  400544:	83 f8 01             	cmp    $0x1,%eax
  400547:	74 27                	je     400570 <main+0x4a>
  400549:	83 f8 01             	cmp    $0x1,%eax
  40054c:	72 0c                	jb     40055a <main+0x34>
  40054e:	83 f8 02             	cmp    $0x2,%eax
  400551:	74 33                	je     400586 <main+0x60>
  400553:	83 f8 03             	cmp    $0x3,%eax
  400556:	74 44                	je     40059c <main+0x76>
  400558:	eb 58                	jmp    4005b2 <main+0x8c>

 

[main函数全部汇编]

0000000000400526 <main>:
#include <string.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
  400526:	55                   	push   %rbp
  400527:	48 89 e5             	mov    %rsp,%rbp
  40052a:	48 83 ec 20          	sub    $0x20,%rsp
  40052e:	89 7d ec             	mov    %edi,-0x14(%rbp)
  400531:	48 89 75 e0          	mov    %rsi,-0x20(%rbp)
	unsigned int uiSwitch;
	
	for(uiSwitch = 0;uiSwitch < 5;uiSwitch++)
  400535:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
  40053c:	e9 8a 00 00 00       	jmpq   4005cb <main+0xa5>
	{
		switch(uiSwitch)
  400541:	8b 45 fc             	mov    -0x4(%rbp),%eax
  400544:	83 f8 01             	cmp    $0x1,%eax
  400547:	74 27                	je     400570 <main+0x4a>
  400549:	83 f8 01             	cmp    $0x1,%eax
  40054c:	72 0c                	jb     40055a <main+0x34>
  40054e:	83 f8 02             	cmp    $0x2,%eax
  400551:	74 33                	je     400586 <main+0x60>
  400553:	83 f8 03             	cmp    $0x3,%eax
  400556:	74 44                	je     40059c <main+0x76>
  400558:	eb 58                	jmp    4005b2 <main+0x8c>
		{
			/* 下面这行Log是否会输出呢? */
			printf("This is no output log \r\n");
			
			case 0:
				printf("This is %d \r\n",uiSwitch);
  40055a:	8b 45 fc             	mov    -0x4(%rbp),%eax
  40055d:	89 c6                	mov    %eax,%esi
  40055f:	bf 64 06 40 00       	mov    $0x400664,%edi
  400564:	b8 00 00 00 00       	mov    $0x0,%eax
  400569:	e8 92 fe ff ff       	callq  400400 <printf@plt>
				break;
  40056e:	eb 57                	jmp    4005c7 <main+0xa1>
			case 1:
				printf("This is %d \r\n",uiSwitch);
  400570:	8b 45 fc             	mov    -0x4(%rbp),%eax
  400573:	89 c6                	mov    %eax,%esi
  400575:	bf 64 06 40 00       	mov    $0x400664,%edi
  40057a:	b8 00 00 00 00       	mov    $0x0,%eax
  40057f:	e8 7c fe ff ff       	callq  400400 <printf@plt>
				break;
  400584:	eb 41                	jmp    4005c7 <main+0xa1>
			case 2:
				printf("This is %d \r\n",uiSwitch);
  400586:	8b 45 fc             	mov    -0x4(%rbp),%eax
  400589:	89 c6                	mov    %eax,%esi
  40058b:	bf 64 06 40 00       	mov    $0x400664,%edi
  400590:	b8 00 00 00 00       	mov    $0x0,%eax
  400595:	e8 66 fe ff ff       	callq  400400 <printf@plt>
				break;
  40059a:	eb 2b                	jmp    4005c7 <main+0xa1>
			case 3:
				printf("This is %d \r\n",uiSwitch);
  40059c:	8b 45 fc             	mov    -0x4(%rbp),%eax
  40059f:	89 c6                	mov    %eax,%esi
  4005a1:	bf 64 06 40 00       	mov    $0x400664,%edi
  4005a6:	b8 00 00 00 00       	mov    $0x0,%eax
  4005ab:	e8 50 fe ff ff       	callq  400400 <printf@plt>
				break;
  4005b0:	eb 15                	jmp    4005c7 <main+0xa1>
			default:
				printf("This is default %d \r\n",uiSwitch);
  4005b2:	8b 45 fc             	mov    -0x4(%rbp),%eax
  4005b5:	89 c6                	mov    %eax,%esi
  4005b7:	bf 72 06 40 00       	mov    $0x400672,%edi
  4005bc:	b8 00 00 00 00       	mov    $0x0,%eax
  4005c1:	e8 3a fe ff ff       	callq  400400 <printf@plt>
				break;
  4005c6:	90                   	nop

int main(int argc,char* argv[])
{
	unsigned int uiSwitch;
	
	for(uiSwitch = 0;uiSwitch < 5;uiSwitch++)
  4005c7:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)
  4005cb:	83 7d fc 04          	cmpl   $0x4,-0x4(%rbp)
  4005cf:	0f 86 6c ff ff ff    	jbe    400541 <main+0x1b>
				printf("This is default %d \r\n",uiSwitch);
				break;
		}
	}
	
	return 0;
  4005d5:	b8 00 00 00 00       	mov    $0x0,%eax
  4005da:	c9                   	leaveq 
  4005db:	c3                   	retq   
  4005dc:	0f 1f 40 00          	nopl   0x0(%rax)

以上,没啦

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值