当前位置:嗨网首页>书籍在线阅读

08-多层嵌套的if语句

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

7.2.5 多层嵌套的 if 语句

前面介绍的 if...else   if...else 序列是嵌套 if 的一种形式,从一系列选项中选择一个执行。有时,选择一个特定选项后又引出其他选择,这种情况可以使用另一种嵌套 if 。例如,程序可以使用 if   else 选择男女, if   else 的每个分支里又包含另一个 if   else 来区分不同收入的群体。

我们把这种形式的嵌套 if 应用在下面的程序中。给定一个整数,显示所有能整除它的约数。如果没有约数,则报告该数是一个素数。

在编写程序的代码之前要先规划好。首先,要总体设计一下程序。为方便起见,程序应该使用一个循环让用户能连续输入待测试的数。这样,测试一个新的数字时不必每次都要重新运行程序。下面是我们为这种循环开发的一个模型(伪代码):

提示用户输入数字

scanf() 返回值为 1

分析该数并报告结果

提示用户继续输入

回忆一下在测试条件中使用 scanf() ,把读取数字和判断测试条件确定是否结束循环合并在一起。

下一步,设计如何找出约数。也许最直接的方法是:

for (div = 2; div < num; div++)
     if (num % div == 0)
         printf("%d is divisible by %d\n", num, div);

该循环检查 2num 之间的所有数字,测试它们是否能被 num 整除。但是,这个方法有点浪费时间。我们可以改进一下。例如,考虑如果 144%20 ,说明 2144 的约数;如果 144 除以 272 ,那么 72 也是 144 的一个约数。所以, num % div 测试成功可以获得两个约数。为了弄清其中的原理,我们分析一下循环中得到的成对约数: 2723484366248189161212169188 ,等等。在得到 1212 这对约数后,又开始得到已找到的相同约数(次序相反)。因此,不用循环到 143 ,在达到 12 以后就可以停止循环。这大大地节省了循环时间!

分析后发现,必须测试的数只要到 num 的平方根就可以了,不用到 num 。对于 9 这样的数字,不会节约很多时间,但是对于 10000 这样的数,使用哪一种方法求约数差别很大。不过,我们不用在程序中计算平方根,可以这样编写测试条件:

for (div = 2; (div * div) <= num; div++)
     if (num % div == 0)
          printf("%d is divisible by %d and %d.\n",num, div, num / div);

如果 num144 ,当 div = 12 时停止循环。如果 num145 ,当 div = 13 时停止循环。

不使用平方根而用这样的测试条件,有两个原因。其一,整数乘法比求平方根快。其二,我们还没有正式介绍平方根函数。

还要解决两个问题才能准备编程。第1个问题,如果待测试的数是一个完全平方数怎么办?报告 144 可以被 1212 整除显得有点傻。可以使用嵌套 if 语句测试 div 是否等于 num /div 。如果是,程序只打印一个约数:

for (div = 2; (div * div) <= num; div++)
{
     if (num % div == 0)
     {
          if (div * div != num)
               printf("%d is divisible by %d and %d.\n",num, div, num / div);
          else
               printf("%d is divisible by %d.\n", num, div);
     }
}

注意 从技术角度看, if   else 语句作为一条单独的语句,不必使用花括号。外层 if 也是一条单独的语句,也不必使用花括号。但是,当语句太长时,使用花括号能提高代码的可读性,而且还可防止今后在 if 循环中添加其他语句时忘记加花括号。

第2个问题,如何知道一个数字是素数?如果 num 是素数,程序流不会进入 if 语句。要解决这个问题,可以在外层循环把一个变量设置为某个值(如, 1 ),然后在 if 语句中把该变量重新设置为 0 。循环完成后,检查该变量是否是 1 ,如果是,说明没有进入 if 语句,那么该数就是素数。这样的变量通常称为标记(flag)。

一直以来,C都习惯用 int 作为标记的类型,其实新增的 _Bool 类型更合适。另外,如果在程序中包含了 stdbool.h 头文件,便可用 bool 代替 _Bool 类型,用 truefalse 分别代替 10

程序清单7.5体现了以上分析的思路。为扩大该程序的应用范围,程序用 long 类型而不是 int 类型(如果系统不支持 _Bool 类型,可以把 isPrime 的类型改为 int ,并用 10 分别替换程序中的 truefalse )。

程序清单7.5  divisors.c 程序

// divisors.c -- 使用嵌套if语句显示一个数的约数
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
     unsigned long num;          // 待测试的数
     unsigned long div;          // 可能的约数
     bool isPrime;               // 素数标记
     printf("Please enter an integer for analysis; ");
     printf("Enter q to quit.\n");
     while (scanf("%lu", &num) == 1)
     {
          for (div = 2, isPrime = true; (div * div) <= num; div++)
          {
               if (num % div == 0)
               {
                    if ((div * div) != num)
                    printf("%lu is divisible by %lu and %lu.\n",
                              num, div, num / div);
                    else
                         printf("%lu is divisible by %lu.\n",
                              num, div);
                    isPrime = false;    // 该数不是素数
               }
          }
          if (isPrime)
               printf("%lu is prime.\n", num);
          printf("Please enter another integer for analysis; ");
          printf("Enter q to quit.\n");
     }
     printf("Bye.\n");
     return 0;
}

注意,该程序在 for 循环的测试表达式中使用了逗号运算符,这样每次输入新值时都可以把 isPrime 设置为 true

下面是该程序的一个输出示例:

Please enter an integer for analysis; Enter q to quit.
123456789
123456789 is divisible by 3 and 41152263.
123456789 is divisible by 9 and 13717421.
123456789 is divisible by 3607 and 34227.
123456789 is divisible by 3803 and 32463.
123456789 is divisible by 10821 and 11409.
Please enter another integer for analysis; Enter q to quit.
149
149 is prime.
Please enter another integer for analysis; Enter q to quit.
2013
2013 is divisible by 3 and 671.
2013 is divisible by 11 and 183.
2013 is divisible by 33 and 61.
Please enter another integer for analysis; Enter q to quit.
q
Bye.

该程序会把 1 认为是素数,其实它不是。下一节将要介绍的逻辑运算符可以排除这种特殊的情况。

小结:用 if 语句进行选择

关键字: ifelse

一般注解:

下面各形式中, statement 可以是一条简单语句或复合语句。表达式为真说明其值是非零值。

形式1:

if (expression)
   statement

如果expression为真,则执行statement部分。

形式2:

if (expression) statement1 else statement2

如果expression为真,执行statement1部分;否则,执行statement2部分。

形式3:

if (expression1) statement1 else if (expression2) statement2 else statement3

如果expression1为真,执行statement1部分;如果expression2为真,执行statement2部分;否则,执行statement3部分。

示例:

if (legs == 4)
     printf("It might be a horse.\n");
else if (legs > 4)
     printf("It is not a horse.\n");
else        /* 如果legs < 4 */
{
     legs++;
     printf("Now it has one more leg.\n");
}