switch

来源:互联网 发布:5.11淘宝真假 编辑:程序博客网 时间:2024/04/30 15:43
int aCount = 0 , bCount = 0 , cCount = 0;
 char ch;
 cin>>ch;
 switch (ch)
 {
 case 'a':
 ++aCount;
 case 'b':
 ++bCount;
 case 'c':
 ++cCount;
 }

 cout<<aCount<<endl<<bCount<<endl<<cCount<<endl;

输入a,输出为1 1 1

输入b,输出为0 1 1

输入c,输出为0 0 1

输入d,输出为0 0 0

执行完一个case后,如果未遇到break,会顺次执行后面的case,直到遇到break或switch结束为止。

存在一个普遍的误解:以为程序只会执行匹配的 case 标号相关联的语句。实际上,程序从该点开始执行,并跨越 case 边界继续执行其他语句,直到 switch 结束或遇到 break 语句为止。

有这么一种常见的情况,程序员希望在 case 标号后省略 break 语句,允许程序向下执行多个 case 标号。这时,两个或多个 case 值由相同的动作序列来处理。由于系统限定一个 case 标号只能与一个值相关联,于是为了指定一个范围,典型的做法是,把 case 标号依次排列。例如,如果只希望计算文本中元音的总数,而不是每一个元音的个数,则可以这样写:

  int vowelCnt = 0;
  // ...
  switch (ch)
  {
  // any occurrence of a,e,i,o,u increments vowelCnt
  case 'a':
  case 'e':
  case 'i':
  case 'o':
  case 'u':
  ++vowelCnt;
  break;
  }

每个 case 标号不一定要另起一行。为了强调这些 case 标号表示的是一个要匹配的范围,可以将它们全部在一行中列出:

  switch (ch)
  {
  // alternative legal syntax
  case 'a': case 'e': case 'i': case 'o': case 'u':
  ++vowelCnt;
  break;
  }

比较少见的用法是,为了执行某个 case 的代码后继续执行下一个 case 的代码,故意省略 break 语句。


哪怕没有语句要在 default 标号下执行,定义 default 标号仍然是有用的。定义 default 标号是为了告诉它的读者,表明这种情况已经考虑到了,只是没什么要执行的。

一个标号不能独立存在,它必须位于语句之前。如果 switch 结构以 default 标号结束,而且 default 分支不需要完成任何任务,那么该标号后面必须有一个空语句。

 switch (ch)
 {
 case 'a':
 ++aCount;
 case 'b':
 ++bCount;
 case 'c':
 ++cCount;

 default:
 ;
 }

如果default语句下没有“;”,编译会出错。

switch 求解的表达式可以非常复杂。特别是,该表达式也可以定义和初始化一个变量:

  switch(int ival = get_response())

在这个例子中,ival 被初始化为 get_response 函数的调用结果,其值将要与每个 case 标号作比较。变量 ival 始终存在于整个 switch 语句中,在 switch 结构外面该变量就不再有效了。

case 标号必须是整型常量表达式。例如,下面的标号将导致编译时的错误:

  // illegal case label values
  case 3.14: // noninteger
  case ival: // nonconstant

如果两个 case 标号具有相同的值,同样也会导致编译时的错误。


对于 switch 结构,只能在它的最后一个 case 标号或 default 标号后面定义变量:

  case true:
  // error: declaration precedes a case label
  string file_name = get_file_name();
  break;
  case false:
  // ...

制定这个规则是为避免出现代码跳过变量的定义和初始化的情况。

回顾变量的作用域,变量从它的定义点开始有效,直到它所在块结束为止。现在考虑如果在两个 case 标号之间定义变量会出现什么情况。该变量会在块结束之前一直存在。对于定义该变量的标号后面的其他 case 标号,它们所关联的代码都可以使用这个变量。如果 switch 从那些后续 case 标号开始执行,那么这个变量可能还未定义就要使用了。

在这种情况下,如果需要为某个特殊的 case 定义变量,则可以引入块语句,在该块语句中定义变量,从而保证这个变量在使用前被定义和初始化。

  case true:
  {
  // ok: declaration statement within a statement block
  string file_name = get_file_name();
  // ...
  }
  break;
  case false:
  // ...



原创粉丝点击