第九章 条件分支语句

9.1 if...else 语句

9.2 if... 语句

9.3 ? : 表达式

9.4 多级 if...else...语句

9.5 switch 语句

9.6 小结

 

"to be or not be"? 

这个问题深深地困扰着哈姆雷特。他必须在“生存还是毁灭”之间做出一个选择,这是一个困难的选择。

在你的人生中,您曾经面对什么选择?

“学编程还是不学编程”?

“学CB还是学VC”?

 

选择哪一个,最终总要是要决定,不同的是每个人在作出选择时所要面对的不同条件。前一章我们讲“顺序流程”就好像长安街一样笔直的,从头走到尾;这一章我们要讲的“条件分支流程”,就像是在道路上遇到了分叉,是直行还是右拐?全看程序走到分叉时所碰上的条件。

 

9.1 if...else  语句

if,中文意思“如果”……

痞子蔡说: “如果把整个太平洋的水倒出,也浇不熄我对你爱情的火”。 多么充满感情的话!当然,这一切仅仅是因为你还没有学过编程。如果你学了编程,学了本章,你就会明白这是一句多么冰凉的条件分支语句,正如它后面的那句所揭示的一切:“整个太平洋的水全部倒得出吗?不行。所以我并不爱你”。来看看if...else 语句在C,C++语言中如何使用。

 

if...else 语法格式:

 

if (条件)

{

  分支一

}

else

{

  分支二

}

 

其中,“条件”由表达式如何,典型的如关系表达式(忘了什么叫“关系表达式”?回头找找讲小情侣遇校监那章)。“分支一”和“分支二”表示当条件成立时和不成立分别要执行语句。用一句表达,就是:如果条件成立(也称条件为真),那么程序执行分支一中的语句,否则(条件为假)程序执行分支二的语句。这就是if...else语句。

举一生活中的例子:

 

if (我中了这一期体彩的500万大奖)

{

  我买房;

  我买车;

  我去欧洲旅游;

}

else

{

  我要修理自行车;

  我买下一期体彩,

 我继续烧香。

}

 

上面的例子中:

  我买房;

  我买车;

  我去欧洲旅游;

}

 

这是第一个分支,而:

  我要修理自行车;

  我买下一期体彩,

 我继续烧香。

}

 

这是第二个分支。到底我将执行哪个分支,依赖于条件:“我中了这一期体彩的500万大奖”是否成立。在梦中,我经常很开心地执行第一个分支,因为那个条件只能在梦中成立。

 

来一段真实的程序:

 

设a,b,c为已定义的三个int变量,有以下代码片段:

 

if (a > b)

{

  c = 1;

}

else

{

  c = 0;

}

 

若a值为2,b值为1,那么执行上面代码,c的值将为1;相反,如果a值为1,b值为1,由于条件:a > b不成立,所以程序将执行else后面一对{}中的代码,结果将是c值为0。

 

用流程图可以直观在表达程序的执行可能的方向。我们来看 if...else...的流程图:

 

箭头表示了程序可能的走向,当遇到条件(菱形)时,根据条件成立的真假,程序将作出选择,是走分支一还是分支二。但无论经过哪个分支,最后都将同样继续后面的代码。

 

上机题目一:用户输入一个整数,请写一程序,通过if...else...判断该数是偶数或奇数。

 

解题:被2整除的整数叫偶数,什么叫整除?就是除了以后余数为0啊。还得我们学过一个操作符是用来求两数相除的余数吗?(如果不记得,先自觉到墙角站10分钟,然后找第七章复习)。

% 操作符用来求两数相除的余数,比如 5 % 2 得到余数1。那么一个数,比如 a,是否偶数,条件就是 (a % 2) == 0。(对 == 也看着也有点生疏?20分钟!然后还找第七章)。 

 

打CB,然后新建一个空白控制台工程。在代码中加下以下黑体部分:

 

//---------------------------------------------------------------------------

#include <iostream.h>

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

int main(int argc, char* argv[])

{

  int num;

 

  cout << "请输入一个整数:";

 

  cin >> num;

 

  if((num % 2) == 0)

     cout << num << "是一个偶数。" << endl;

  else

     cout << num << "是一个奇数。" << endl;

 

  getchar();

  return 0;

}

//---------------------------------------------------------------------------

按F9编译并运行程序后,笔者输入123,以下是屏幕显示结果:

 

9.2 if... 语句

 

if...else...中的 else(否则)并不是必须的,因为有时候,当指定条件成立时,我们执行某些动作,否则,我们不执行那些动作。用流程图表示就是:

对比if...else...的流程图,我们发现if...语句中,当条件不成立时,将绕过分支一的语句,直接执行后面的代码。

 

if...语句格式:

 

if (条件)

{

   分支一

}

 

来看这个例子,然后做出你的判断:

if (我每天赚100万)

{

   我每天都将100成中的90万分给你。

}

看完上面的“程序”,你觉得我是个大方的人吗?看起来是噢,但问题是我永远也无法每天赚100万,所以关于“我每天都将100成中的90万分给你” 整个是在穷开心呵。同样的道理,你自已分析痞子蔡的那句话吧。

 

上机题目二:用户输入一个字符,用程序判断是否为小写字母,如果是,请输出“您输入的字符是小写字母”。

解题:如何判断一个字符是小写字母?让我们查一下第五章中的ASCII码表。在表里头,小写字母( a ~ z)对应的ASCII值为:

 

97 ~ 122  a ~ z

 

可见,所有小写字母的值是连续的。那么,判断一个字符是否为小写字母,就看它的值是否大于等于97,并且小于等122。

假设一个字符变量: a;要判断它是否“大于等于97,并且小于等122”--

不能这样写:

if ( 97 <= a <= 122) //错误!

 

你应该使用 && 来表达"并且":

if (a >= 97 &&  a <= 122)

 

当然,更直观,更不易出错的写法,是直接使用字符,而不是使用字符的ASCII值:

if (a >= 'a' && a <= 'z')

 

新建一个控制台空白工程。然后在代码中输入以下黑体部分:

 

//---------------------------------------------------------------------------

#include <iostream.h>

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

int main(int argc, char* argv[])

{

  char a;

  cout << "请输入一个字符:" ;

  cin >> a;

  if(a >= 'a' && a <= 'z')

     cout << a << "是一个小写字母。" << endl;

 

  getchar();

  return 0;

}

//---------------------------------------------------------------------------

9.3  ? :  表达式

? :  表达式 我们称为 问号冒号表达式。

 

用if...else... 和 if...语句,已经可以很好地实现所有条件分支的代码。不过C是一门追求简捷高效的语言,它提供的 ? : 表达式 来在某种情况下代替if...else...,起来让代码更简捷的作用。

 

来看看if...else...语句在什么情况下可以简化。

 

首先来看原型:

if (条件)

{

  分支一

}

else

{

  分支二

}

我们知道,分支一或分支二一般都是一组(多行)语句,用来分别实现条件是否成立时的动作。由于是一组(多行)语句,所以我们有一对{}括在外面,用于形成复合语句。不过,有时候,分支中的语句比较简单,用一句话就可以实现。比如我们所举的例子:

if (a > b)

{

  c = 1;

}

else

{

  c = 0;

}

在这个例子中,分支一、二都分别只有一条语句。对于只有一条语句的情况,我们可以省略{}(除了在特殊的上下文中外,其它情况下都可以省略。以后我们学习的其它流程控制也一样),如:

if (a > b)

   c = 1;

else

   c = 0;

看,没有花括号的代码,感觉多紧凑。不过,对于上面的代码,我们还可以继续简化,那就是使用 ? : 语句。

 

c = (a > b)? 1 : 0;

 

就一行话,多简捷!语句中的问号问的是什么?问的是 a 是否大于 b ? 如果是,则得到值1,否则,得到值0。

 

? : 表达式格式语法:

 

(条件) ? 值1 : 值2

 

举一例子:

设有int变量 a,b,二者均已初始化。请得到二者中的较大值。

 

方法是:

 

int c = (a  > b) ?  a : b;

 

是的,就这么简单,执行上面代码,c 将得到a和b中的较大值。

 

我们称 (a > b) ? a : b 为一个表达式,而不称它为完整的一个语句(尽管它的确也可以作一个单独的语句存在)。一般地,? : 表达式拿来作为等号的右值,用于通过条件判断确定一个值后,该值被赋予等号的左值。因此,并不是所有的if..else...语句都可以用 : ? 来代替,只有那些两个分支都只是用来计算一个同一类型的值,然后赋予同一变量的条件分支语句,才适合。

 

上机题目三:两数取大

 

新建一个控制台空白工程。然后在代码中输入以下黑体部分:

 

//---------------------------------------------------------------------------

#include <iostream.h>

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

int main(int argc, char* argv[])

{

  int a,b,c;

  cout << "请输入两个整数(用空格分开):" ;

  cin >> a >> b;

  

  c = (a > b)? a : b;

  

  cout << c << "大" << endl;

 

  getchar();

  return 0;

}

//---------------------------------------------------------------------------

下面是屏幕输出的结果。我输入的两个数是 102 和 134。

 

9.4  多级 if...else...语句

 

不要害怕为什么一个条件分支就有这么多种语句。多级if..else..语句——只是我这么叫它,其实它完全是由if..else..语句组成,就好像楼梯,一个阶的楼梯是楼梯,100个阶的楼梯也是楼梯。

多级 if..else...语法格式:

 

if(条件1)

{
    分支一  
   }
   else if(条件2)

{
      分支二
   }
   else if(条件3)

{
   分支三
   }
   else

{
   分支四
   }

 

格式中举出四个分支,实际可以只有三个,两个,也可以有更多个。请看下在这个例子。

 

让我们想像这么一幕情景剧——

时间:XXXX年2月14日;地点:某校园内小公园;
     人物:女生一,男生一。
    (男生送给女生一束环瑰)
     女生(高兴地):多美啊——多少钱买的!
     男生:猜。
     女生(心里想:如果多于100元我就亲他一口):超过100元吗?
     男生:NO。
     女生:(心里想:如果多于50元我就许他亲我一口):那,不低于50元吧?
     男生:NO。
     女生:(心里想:如果多于10元就跟他说声谢谢吧):那是不低于10元了?
     男生:NO。
     女生:(不再有任何想法,一把丢掉鲜花):呸!

看明白了吗?

“看明白了……”一个小男生眼泪汪汪地站起来,回答:“我是看明白了,现在的女生没一个是好东西!”#·$&*%!@ 啊?? 我是说,大家看出其中的多级条件分支了吗?

写成程序,便是:

 

int price = 玫瑰花价钱;

   if (price > 100)

{
        小女生要亲小男生一口;
   }
   else if(price > 50)

{
        小女生准备让小男生亲一口;
   }
   else if (price > 10)

{
       小女生对小男生说声“谢谢”;
   }
   else

{
       小女生扔掉花,说:“呸!”;
   }

 

如果花价大于100元,那么女生亲男生一口;否则呢?否则就再判断花价是否大于50元,如果还是不大,那不再来判断花价是否大于10元,如果还是不大,最后无条件地执行“小女生扔掉花……”这一句。

 

看一下多级if...else...语句的流程图:

 

 

上机题目四:送花待遇,要求根据上面的情景剧,写一程序,用户输入花价后,程序根据不同的花价输出相应的待遇。

 

新建一控制台工程。

 

 

//---------------------------------------------------------------------------

#include <iostream.h>

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

int main(int argc, char* argv[])

{

 int flowerPrice;

 

  cout << "公元2002年2月14日,一小男生向一小女生赠送一束玫瑰……" << endl;

  cout << "女生:请输入这束花的价钱。" << endl;

  cout << "男生:";

  cin  >> flowerPrice;

  

  if(flowerPrice > 100)

     cout << "女生:哇!我太喜欢这花了,让我亲你一口以示谢意!" << endl; 

  else if (flowerPrice > 50)

     cout << "女生:哈!花美人更美,你不想亲我一口吗?" << endl;

  else if (flowerPrice > 10)

     cout << "女生:谢谢!" << endl;

  else 

     cout << "女生:什么破花,大头鬼才会喜欢。" << endl;

 

  getchar();

 

  return 0;

}

//---------------------------------------------------------------------------

以下是运行结果的一种,我实在买不起100元以上的花:

 

9.5 switch 语句

 

多级 if...else...显然是为了那些可能需要进行多级判断才能做出选择的情况。如前面的花价。如果正好是大于100元,那么只需判断一次,女生就可以做出决定,但如果是7元钱,那就必须经过“是否大于100?是否大于50?是否大于10?”三次判断。

C为了简化这种多级判断,又提供了switch语句。

 

switch 语句的格式:

 

switch ( 整型或字符型变量 )

{
     case 变量可能值1 : 
         分支一;
         break;

   case 变量可能值2 : 
         分支二;
         break;

   case 变量可能值3 : 
         分支三;
         break;

   ...

   default :

       最后分支;

 

在 switch 的语法里,我们要学到4个关键字:switch、case 、break、default。

 

在 switch ( 变量 ) 这一行里,变量只能是整型或字符型。程序先读出这个变量的值,然后在各个"case"里查找哪个值和这个变量相等,如果相等,就算条件成立,程序执行相应的分支,直到碰上break或者switch语句结束。

 

说起来有点抽象。我们结合一个实例看看。

实例模拟一个网上调查。它要求网友输入数字以选择自已是如何到达当前网页。然后,程序根据网友这一输入,打出不同的结果。

 

上机题目五:模拟网络调查,要求输出不同的选项,供网友选择(通过简单地输入数字),程序根据网友的选择,输出相应不同的结果。

 

请新建一控制台空白工程,然后在代码里输入以下黑体部分。

 

//---------------------------------------------------------------------------

#include <iostream.h>

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

int main(int argc, char* argv[])

{

  int fromWay;

 

  cout << "请通过输入序号,选择您如何来到本网站。" << endl;

  cout << "1) ---- 通过搜索引擎" << endl;

  cout << "2) ---- 通过朋友介绍" << endl;  

  cout << "3) ---- 通过报刊杂志" << endl;

  cout << "4) ---- 通过其它方法" << endl;

 

  cin >> fromWay;

 

  switch (fromWay)

  {

    case 1 : 

       cout << "您是通过搜索引擎来到本网站的。" << endl;

       break;

    case 2 : 

       cout << "您是通过朋友介绍来到本网站的。" << endl;

       break;

    case 3 : 

       cout << "您是通过报刊杂志来到本网站的。" << endl;

       break;

    case 4 : 

       cout << "您是通过其它方法来到本网站的。" << endl;

       break;

    default :

       cout << "错误的选择!请输入1~4的数字做出选择。" << endl;

  }

 

  getchar();

 

   return 0;

}

 

以下是我运行的一个结果,我输入的是2。

 

对照输入结果,我们讲一讲这段代码,其中主要目的是要弄明白switch语句的用法。

 

首先,int fromWay 定义了一个整型变量,准备用来存储用户输入的选择。

 

cout << "请通过输入序号,选择您如何来到本网站。" << endl;

cout << "1) ---- 通过搜索引擎" << endl;

cout << "2) ---- 通过朋友介绍" << endl;  

cout << "3) ---- 通过报刊杂志" << endl;

cout << "4) ---- 通过其它方法" << endl;

 

这些语句输出提示和选择项,结果如上图。

 

cin >> fromWay; 这一句则负责等待用户输入,并且将用户的输入存储到 fromWay。

接下来程序遇上了 switch 语句:

 

switch (fromWay)

程序将根据 fromWay 值,在下面的各个case 中找到匹配的值。 本例中switch带有四个case,值分别是1、2、3、4。在结果图中,由于我输入的是2,所以程序进入下面这个case:

case 2 : 

    cout << "您是通过朋友介绍来到本网站的。" << endl;

    break;

 

程序打出"您是通过朋友介绍来到本网站的。" 这行内容。最后遇上 break;于是跳出整个switch语句。

 

同样的道理,如果用户输入的是其它的数,如1或3,则会进入相应的case 1 或 case 3 分支。

但如果用户输入的数在所有的case 里都找不到时,会怎么样?比如,用户输入5。这种情况下,default分支将起作用,所有case里的值都不匹配时,switch进入default分支。如果连default也没有,那么程序在switch语句里什么也不做,直接完成switch语句。

我们来看一下如果用户不按所列的情况输入,而造成的结果:

 

了解一下switch,case,break,default的意思,对理解前面的一切也会有帮助,它们分别是:开关,情况,中断,默认(值)。那么用一句话套起来的说法就是:根据开关值的不同,执行不同的情况,直到遇上中断;如果所有的情况都不符合开关值,那么就执行默认的分支。

 

最后说一下关于switch中非常重要的几个注意点。

 

第一、switch ( 整型或字符型变量 ) 中,变量的类型如文中所标,只能是整型和字符类型。它们包含 int,char。当然无符类型或不同的长度整型(unsigned int,short,unsigned char)等都可以。另外,枚举类型(enum)内部也是由整型或字符类型实现。所以也可以。实型(浮点型)数就不行,如:

float a = 0.123;

switch(a) //错误!a不是整型或字符类型变量。  

{

  ....

}

 

第二、case 之后可以是直接的常量数值,如例中的1、2、3、4,也可以是一个使用常量计算式,如2+2等,但不能是变量或带有变量的表达式,如 a * 2等。当然也不能是实型数,如4.1,或2.0 / 2 等。

switch(formWay)

{

   case 2-1 :  //正确

     ...

   case a-2 :  //错误

     ...

   case 2.0 :  //错误

     ...

}

另外,在case 与常量值之后,需要一个冒号,请注意不要疏忽。

 

第三、break 的作用。

break 使得程序在执行完选中的分支后,可以跳出整个switch语句(即跳到switch接的一对{}之后),完成switch。如果没有这个break,程序将在继续前进到下一分支,直到遇到后面的break或者switch完成。

比如,假设现在程序进入case 1: 中的分支,但case 1 的分支这回没有加break:

 

case 1 :

    cout << "您是通过搜索引擎来到本网站的。" << endl;

case 2 : 

    cout << "您是通过朋友介绍来到本网站的。" << endl;

 

那么,程序在输出 "您是通过搜索引擎来到本网站的。" 之后,会继续输出case 2中的 "您是通过朋友介绍来到本网站的。" 。

请大家将前面实例中的代码片段改为如下(红色部分,即将所有的break都通过加//使之无效。):

    ...

  case 1 : 

       cout << "您是通过搜索引擎来到本网站的。" << endl;

       //break;

    case 2 : 

       cout << "您是通过朋友介绍来到本网站的。" << endl;

       //break;

    case 3 : 

       cout << "您是通过报刊杂志来到本网站的。" << endl;

       //break;

    case 4 : 

       cout << "您是通过其它方法来到本网站的。" << endl;

       //break;

    default :

       cout << "错误的选择!请输入1~4的数字做出选择。" << endl;

    ...

 

运行后,结果会是如何?请大家动手试试,然后在作业中回答我。

 

第四、default是可选中,前面我们已经说过它的用处,及如果没有default,程序在找不到匹配的case分支后,将在switch语句范围内不做什么事,直接完成switch。大家也可以在实例中将default的代码注释掉,然后试运行,并且在选择时输入5。

...

//default :

   //cout << "错误的选择!请输入1~4的数字做出选择。" << endl;

...

 

第五、必要时,可在各个case中使用{}来明确产生独立的复合语句。

前面我们在讲if...语句和其它流程控制语句时,都使用{}来产生复合语句:

if (条件)

{

  分支一;

}

除非在分支中的语句正好只有一句,这里可以不需要花括号{}。但在switch的各个case语句里,我们在语法格式上就没有标出要使用{},请看:

switch ( 整型或字符型变量 )

{
     case 变量可能值1 : 
         分支一;
         break;

   case 变量可能值2 : 
      ....

}

 

一般教科书上只是说 case 分支可以不使用{},但这里我想提醒大家,并不是任何情况下case分支都可以不加{},比如你想在某个case里定义一个变量:

switch (formWay)

{

   case 1 :

     int a=2;  //错误。由于case不明确的范围,编译器无法在此处定义一个变量。

     ...

   case 2 :

     ...

}

 

在这种情况下,加上{}可以解决问题。

switch (formWay)

{

   case 1 :

 { 

     int a=2;  //正确,变量a被明确限定在当前{}范围内。

     ...

  } 

   case 2 :

     ...

}

由于本注意点涉及到变量的作用范围,所以你如果看得不是很明白,可以暂时放过。

 

第六、switch并不能代替所有有if..else...语句。这一点你应该知道了,因为前面已说过,它在对变量做判断时,只能对整型或字符型的变量做判断。另外,switch也只能做“值是否相等”的判断。你不能在case里写条件:

 

switch (i)

{

  case (i >= 32 && i<=48) //错误! case里只能写变量的可能值,不能写条件。

     ...

}

 

在这种情况下,你只能通过 if...else来实现。

 

9.6 小结

 

这一节课我们学了所有条件分支的流程控制语句。在编程的时候,我们选择什么语句呢?嗯,这是一个问题。幸好,这个问题不像丹麦王子哈姆雷特面对的那样困难。你所要做的就是多看几遍本章课程多做几次本章的各个短小简单的例程。从基础做起。然后,我们会安排一个完整的,适合我们现在水准的小项目进行实战。

 

也许你害怕做选择、也许你正在为难于某个选择、也许你一直为某个错误的选择而后悔……

但如果生活真的没有了选择……或者

如果我们所要经历一切选择都只能由别人做出决定……

这样的生活肯定不精彩。

编程也一样。学好条件选择的流程,你就能写一些精彩的程序!

所以庆贺一下吧,就在这一章的内容,我们学完了所有的条件分支的流程控制语句!要知道,无论是什么编程语言,也都只有两大流程控制!

多加努力!下一章《循环语句》见!

 

[到页首]