switch case 求助!!!

东方石头 2012-10-16 03:37:37
C程序设计 清大 第三版书上有一句话是这样的:
“case常量表达式”只是起语句标号的作用,并不是在该处进行条件判断。在执行switch语句时,根据switch后面表达式的值找到匹配的入口标示,就从此标示开始执行下去,不再进行判断。。。。。所以才用了break语句。
这句话改怎样理解?书上的例题我练过,但还是不太明白为什么这样写的原因呢。
希望各位大侠的帮助。。。
...全文
371 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
firendlys 2012-11-09
  • 打赏
  • 举报
回复
这个东西还是直接看汇编吧,简单易懂... 不需要什么高深汇编知识,看懂 jmp , cmp 这2条语句就够了. 有时候,类似这种基础语法,直接看汇编结果吧,简单直接明了(复杂的那些就不建议看汇编了)...

46:       int i=1;
00401048   mov         dword ptr [ebp-4],1
47:       int j=0;
0040104F   mov         dword ptr [ebp-8],0
48:       switch(i)//注意这里,整个switch只有在这里进行同一判断,然后直接跳转.
49:       {//这里有一大堆东西,具体意思不需要知道(毕竟现在不是在学汇编)
00401056   mov         eax,dword ptr [ebp-4]//只需要知道,整个switch里面所有case都是通过这堆代码
00401059   mov         dword ptr [ebp-0Ch],eax//进行跳转,就足够了.
0040105C   mov         ecx,dword ptr [ebp-0Ch]
0040105F   sub         ecx,1
00401062   mov         dword ptr [ebp-0Ch],ecx
00401065   cmp         dword ptr [ebp-0Ch],3
00401069   ja          $L7455+7 (00401095)
0040106B   mov         edx,dword ptr [ebp-0Ch]
0040106E   jmp         dword ptr [edx*4+4010A3h]
50:       case  1://在随后的这些case里面,实际上不需要在进行判断. 所以,这些case实际上只是一个标号的作用.
51:           j=1;//目的是为了在第一个case之前计算好每一个case需要跳转的地址.
00401075   mov         dword ptr [ebp-8],1
52:           break;//遇到 break 就直接跳转到 switch(){}大括号后面
0040107C   jmp         $L7455+0Eh (0040109c)
53:       case 2:
54:           j=2;
0040107E   mov         dword ptr [ebp-8],2
55:           break;
00401085   jmp         $L7455+0Eh (0040109c)
56:       case 3:
57:           j=3;//没有break的情况,就不会跳转出去,所以,程序就会继续执行,直到遇到break,或者
00401087   mov         dword ptr [ebp-8],3//执行到switch(){}大括号后面为止
58:       case 4:
59:           j=4;
0040108E   mov         dword ptr [ebp-8],4
60:       default:
61:           j=5;
00401095   mov         dword ptr [ebp-8],5
62:           break;
63:       }

//执行流程也该清楚了吧?
mymtom 2012-11-09
  • 打赏
  • 举报
回复
引用 4 楼 zhuankeshumo 的回复:
这种情况是C的缺点 C#里面必须加break; 不然报错
不是缺点,是特点。不然也不会有 Duff's device
SKATE11 2012-11-09
  • 打赏
  • 举报
回复
意思是先找到对应的case处 然后向后执行 如果后面没有遇到退出语句的话 就会一直执行下去
lin5161678 2012-11-09
  • 打赏
  • 举报
回复
引用 4 楼 zhuankeshumo 的回复:
这种情况是C的缺点 C#里面必须加break; 不然报错
C#的处理还不如C 如果必须加 那么干脆处理完一个case后直接退出
gaochizhen33 2012-11-09
  • 打赏
  • 举报
回复
引用 12 楼 gaochizhen33 的回复:
引用 11 楼 summybloom 的回复:引用 8 楼 zhao4zhong1 的回复:VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断……
我看错楼主的困惑了。。。 没有break的话会逐一执行剩下的case,break的作用就是执行完一个case后跳出switch中。
gaochizhen33 2012-11-09
  • 打赏
  • 举报
回复
引用 11 楼 summybloom 的回复:
引用 8 楼 zhao4zhong1 的回复:VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Tur……
这是赵老师的专用回复。 switch和case之间的语句将不会被执行,匹配到case后将直接跳到相应的case中。

switch(x){
int a = 2;
case 1:printf("1");
    break;
case 2:printf("2");
    break;
}
在这个语句中int a = 2将不会被执行,如何在case中使用了变量a,是会报错的。
东方石头 2012-11-08
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo De……
我试了一下您说的快捷按键,但是没反应呢?我用的VC6.0 是不是这个快捷键和你说的那个不一样啊? 像这种快捷键从哪里看? 我还是初学者 一下方面不懂 请见谅!
L_chxu 2012-10-16
  • 打赏
  • 举报
回复
简单的说,当你用switch语句判断的时候,程序跳到符合条件的那个Case进入执行,

“只是起语句标号的作用,并不是在该处进行条件判断”

这句话的意思是,case作标记用,符合条件时的入口。不是进行判断的原因是:当它进入这个入口后,如果下面的case语句后面没有break;语句,它仍然会进去执行。(如果它是进行条件判断,那么下面的肯定不符合条件,就不会进去了,而事实上它执行了,就说明不是判断的)
proorck6 2012-10-16
  • 打赏
  • 举报
回复
这样说是为了和if-else区分开来
如果是

switch(x){
case 1:printf("1");
case 2:printf("2");
}
将显示两个数
这样设计是为了实现如下的代码

switch(x){
case 1:case 2:
printf("1 or 2");
case 3:case 4:
printf("3 or 4");
}
赵4老师 2012-10-16
  • 打赏
  • 举报
回复
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
xiaoxiao8310 2012-10-16
  • 打赏
  • 举报
回复
“case常量表达式”只是起语句标号的作用 个人觉得可以理解为goto语句的标号一样

...........
goto end;
..........
end:
printf("end\n");

whizered 2012-10-16
  • 打赏
  • 举报
回复
根据switch后面的值,在case里面找到对应的项,然后从这个case开始顺序执行,遇到break跳出switch.如果没有遇到break,则一直执行完毕,所以为了只执行一个case语句,往往会在其后加break.但是也有不加break的情况,那么就会顺序向下执行.
mymtom 2012-10-16
  • 打赏
  • 举报
回复
[code=C/C++]
#include <stdio.h>

int main(int argc, char *argv[])
{
int c;

c = argc;

switch (c) {
case 3:
printf("%s@%d\t: c=%d\n", __FILE__, __LINE__, c);
case 2:
printf("%s@%d\t: c=%d\n", __FILE__, __LINE__, c);
case 1:
printf("%s@%d\t: c=%d\n", __FILE__, __LINE__, c);
default:
c = -1;
break;
}

return 0;
}
[/Code]
newtee 2012-10-16
  • 打赏
  • 举报
回复
这种情况是C的缺点
C#里面必须加break; 不然报错
newtee 2012-10-16
  • 打赏
  • 举报
回复
case后面的常量表达式实际上只起语句标号作用,而不起条件判断作用,即"只是开始执行处的入口标号". 因此,一旦与switch后面圆括号中表达式的值匹配,就从此标号处开始执行,而且执行完一个case后面的语句后,若没遇到break语句,就自动进入 下一个case继续执行,而不在判断是否与之匹配,直到遇到break语句才停止执行,退出break语句.因此,若想执行一个case分之后立即跳出 switch语句,就必须在此分支的最后添加一个break语句.
newtee 2012-10-16
  • 打赏
  • 举报
回复
#include <stdio.h>

int main()
{
char x = 'B';
switch (x){
case 'A':printf("A");
case 'B':printf("B");
case 'C':printf("C");
default: printf("D");
}
}
result: BCD

case后面的常量表达式实际上只起语句标号作用,而不起条件判断作用,即"只是开始执行处的入口标号". 因此,一旦与switch后面圆括号中表达式的值匹配,就从此标号处开始执行,而且执行完一个case后面的语句后,若没遇到break语句,就自动进入 下一个case继续执行,而不在判断是否与之匹配,直到遇到break语句才停止执行,退出break语句.因此,若想执行一个case分之后立即跳出 switch语句,就必须在此分支的最后添加一个break语句.
  • 打赏
  • 举报
回复
switch后面的值是几,就在case里面找到对应的项,执行,跳出,每次进入switch,只执行其中的一个case

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧