文档章节

C Primer Plus 第7章 C控制语句:分支和跳转 7.2 if语句中添加 else 关键字

idreamo
 idreamo
发布于 2016/06/16 05:59
字数 2630
阅读 45
收藏 2

if else 语句的通用形式为:

if (expression)

    statement1

else

    statement2

如果expression为真(非零),就执行statement1;如果expression为假或零,则执行跟在else后的那一条语句(statement2)。

如果希望在if和else之间有多条语句,必须使用花括号创建一个代码块。

if语句使您能够选择是否执行某个动作。if else语句使您可以在两个动作之间进行选择。

7.2.1 另一个例子:介绍getchar()和putchar()

现在我们将接触专门 为面向字符I/O而设计的一对C函数:getchar()和putchar()。

getchar()函数没有参数,它返回来自输入设备的下一个字符。

ch=getchar();与scanf("%c",&ch);有同样的效果。

putchar()函数打印它的参数。例如,下面的语句将先前赋值给ch的值作为字符打印出来:

putchar(ch);

该语句与printf("%c",ch);有同样的效果。

因为这些函数仅仅处理字符,所以它们比更通用的scanf()和printf()函数更快而且更简洁。同样,注意到它们不需要格式说明符,因为它们只对字符 起作用。

这两个函数通常都是在stdio.h文件中定义的。

下面的示例将说明这些函数是如何工作的,“如果字符 是空格,打印之;否则,打印它们在ASCII序列中的下一个字符”。

程序清单7.2  cypher1.c 程序

/*cypher1.c --改变输入,只保留其中的空格*/
#include  
#define SPACE ' '  /*SPACE相当于“引号-空格-引号”*/
int main(void)
{
    char ch;

    ch=getchar();  /*读入一个字符*/
    while(ch!='\n') /*当一行未结束时*/
    { 
        if(ch==SPACE)
          putchar(ch);
        else
          putchar(ch+1);
        ch=getchar();
    }
    putchar(ch);   /*换行打印字符*/
    return 0;
}
/*下面是一个运行示例:
CALL ME HAL.
DBMM NF IBM/
*/

C灵活的语法使您可以通过将读取和判断合并为单个表达来仿效程序清单7.1。就是说,您可以把这种形式的循环:

ch=getchar();

while(ch!='\n')

{

    ...

    ch=getchar();

}

替换为下面的形式:

while((ch=getchar())!='\n')

{

    ....

}

关键的一行是while( (ch=getchar()) != '\n' )

这体现了c的编程风格:将两个动作合并为一个表达式。

圆括号是必须的,因为!=的优先级要比=的高。

putchar(ch+1)再次证明了字符实际上是作为整数存储的

7.2.2 ctype.h系列字符函数

ctype.h头文件包含了一些可以用来分析字符的函数的原型。这些函数接受一个字符作为参数,如果该字符 属于某特定的种类则返回非零值(真),否则返回零(假)。

例如,如果isalpha()函数的参数是一个字母,则它返回一个非零值。程序清单7.3通过使用该函数扩展了程序清单7.2。

程序清单7.3 cypher2.c

#include 
#include 
int main (void)
{
    char ch;

    while((ch=getchar())!='\n')
    {
        if(isalpha(ch))    //如果是一个字母
            putchar(ch+1); //则改变它
        else               //否则
            putchar(ch);   //原样打印它
    }
    putchar(ch);           //打印换行符
    return 0;
}

表7.1 ctype.h的字符判断函数

函数名 为如下参数时,返回值为真
isalnum() 字母或数字
isalpha() 字母
isblank() 一个标准的空白字符(空格、水平制表符、或换行)
iscntrl() 控制符,例如ctrl+B
isdigit() 阿拉伯数字
isgraph() 除空格外的所有可打印字符
islower() 小写字母
isprint() 可打印字符
ispunct() 标点符号(除空格和字母数字外的可打印字符)
isspace() 空白字符
isupper() 大写字母
isxdigit() 十六进制数字字符

表7.2 ctype.h的字符映射函数

函数名 动作
tolower() 返回参数的小写字符
toupper() 返回参数的大写字符

7.2.3  多重选择else if

日常生活中,经常会给我们提供两个以上的选择。

程序清单7.4  electric.c

/*electric.c --计算用电帐目*/
#include 
#define RATE1 0.12589  /*第1 个360KWH的费率*/
#define RATE2 0.17901  /*下一个320KWH的费率*/
#define RATE3 0.20971  /*超过680KWH的费率*/
#define BREAK1 360.0   /*费率的第一个分界点*/
#define BREAK2 680.0   /*费率的第二个分界点*/
#define BASE1 (RATE1*BREAK1) /*用电360KWH的费用*/
#define BASE2 (BASE1+(RATE2*(BREAK2-BREAK1)))  /*用电680KWH的费用*/
int main (void)
{
    double kwh;   /*用电的千瓦小时数*/
    double bill;  /*费用*/

    printf("Please enter the kwh used.\n");
    scanf("%lf",&kwh);  /*%lf是double类型的说明符*/
    if(kwh<=BREAK1)  
        bill = RATE1 * kwh;
    else if (kwh <= BREAK2)  /*用电量在360-680kwh之间*/
        bill = BASE1 + (RATE2 * (kwh-BREAK1));  
    else               /*用电超出680kwh时*/
        bill = BASE2 + (RATE3 * (kwh-BREAK2));
    printf("The charge for %.1f kwh is $1.2f.\n",kwh,bill);
    return 0;
}
    

程序清单7.4用符号常量表示费率,以便这些常量可以很方便的被放置在一起。该清单也用 符号表示了费率的分界点。BASE1和BASE2根据费率和分界点来表示。这样,如果费率或分界点改变了,它们也会自动的更新。您可能回想起预处理器是不做计算的,程序中BASE1出现的地方将使用0.12589*360.0代替。不用担心,编译器会求得该表达式的数值(45.3204)以便最终的程序代码使用45.3204而不是一个计算表达式。

程序的流程简单明了。应该特别注意的是仅当KWH大于360时程序才到达第一个else。所以,像程序注释的那样,else if 行实际上相当于要求kwh在360和680之间。同样仅当kwh超过680才能到达最后一个else。

说到编译器的嵌套限制,C99标准要求编译器最少支持127层嵌套。

7.2.4  把else 与 if 配对

当有众多的if和else的时候 ,计算机是怎样判断哪个if对应哪个else的?

规则是如果没有花括号指明,else与和它最接近的一个if相匹配。

7.2.5   多层嵌套的if

前面所看到的if...else if...else序列是嵌套if的一种形式,这是从一系列的二选一中进行选择的。当进行了特定的选择后又导致了额外的选择时将使用另一种嵌套if。

我们试着用这种形式的嵌套if来解决下面的问题:给定一个整数,显示所有能整除它的约数;如果没有约数,则报告该数是个素数。

首先,对程序进行整体设计,为了方便,程序需要用一个循环来使您能输入被测试的数。

下一步,需要 计划怎么来找到除数。或许最显而易见的方法是这样的:

for(dir=2;div

    if(num%div==0)

        printf("%d is divisible by %d\n",num,div);

该循环检查界于2到num之间的所有数,看它们是否可以整除num。不幸的是这样浪费了计算机的时间。我们可以做的更好。例如,考虑搜索144的约数。可以发现144%2为0,这意味着144能被2整除。如果明确的拿144除以2,可以得到72,这也是一个约数,因此一次成功的num%div测试可以得到两个约数而不是一个。然而,真正的性能指标在于循环测试界限的改变。

为了弄清这是怎么工作的,看一下循环中所得到的成对的约数:2和72、3和48、4和36、6和24、8和18、9和16、12和12、16和9、18和8等。哦,在得到12和12这对约数后,又开始得到与已找到的相同的约数(以相反的次序)。无须循环到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);

如果num为144,循环运行到div=12终止。如果Num为145,循环运行到div=13终止。

我们还需要提出两个问题,然后才能准备开始编程。第一,如果测试的数是一个完全平方数怎么办?报告144可被12和12整除显然有些愚蠢,但可以用嵌套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\n",num,div);

                else

                         printf("%d is divisible by %d.\n",num,div);

        }

}

第二,怎么知道一个数是素数呢?如果一个数是素数,程序永远也进不了if语句。为了解决这个问题,可以在循环外设置一个变量为某一值,比方说1,在if语句中将这个变更重设为0.那么循环完成后,检查该变量是否仍然是1.如果是,则从来没有进入过if语句,这个数是素数。

这样的变量通常称为标志(flag)。

传统上,C习惯了用Into类型作为标志,但是新型的_Bool型变量极佳地符合了这种需求。而且通过使用stdbool.h头文件,可以用bool代替_Bool表示这种类型,并用标识符true和false代替1和0.

程序清单 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;
}

这个程序将会把1判断为素数,而实际上1不是素数。下一部分将要介绍的逻辑运算符将使你能够把1排除在外。

© 著作权归作者所有

idreamo
粉丝 18
博文 139
码字总数 224743
作品 0
青岛
产品经理
私信 提问
C Primer Plus 第11章 11.7 ctype.h字符函数和字符串

第7章“C控制语句 分支和跳转”介绍了ctype.h系列字符相关的函数。这些函数不能被 应用于整个字符串,但是可以被应用于字符串中的个别字符。程序清单11.26定义了一个函数,它把toupper( )函数...

idreamo
2016/08/27
52
0
《Java从小白到大牛》之第7章 控制语句

《Java从小白到大牛》纸质版已经上架了!!! 程序设计中的控制语句有三种,即顺序、分支和循环语句。Java程序通过控制语句来管理程序流,完成一定的任务。程序流是由若干个语句组成的,语句...

tony关东升
2018/06/25
0
0
C Primer Plus 第7章 C控制语句:分支和跳转 本章概要

在本章中您将学习到以下内容: *关键字 if / else / switch / continue / break / case / default / goto *运算符 && || ?: *函数: getchar() / putchar() 以及ctype.h系列 *怎样使用if和i...

idreamo
2016/06/12
47
0
C语言再学习--关键字

C语言一共有32个关键字,如下表所示: 关键字 说明 auto 声明自动变量 short 声明短整型变量或函数 int 声明整型变量或函数 long 声明长整型变量或函数 float 声明浮点型变量或函数 double 声...

qq_29350001
2016/11/03
0
0
C语言的32个关键字

C语言的关键字共有32个,根据关键字的作用,可分其为数据类型关键字、控制语句关键字、存储类型关键字和其它关键字四类。 1 数据类型关键字(12个): (1) char :声明字符型变量或函数 (2) ...

晨曦之光
2012/03/09
71
0

没有更多内容

加载失败,请刷新页面

加载更多

Rabbit MQ 延迟消息发送

为什么使用延迟消息? 不同于同步消息,有些业务场景下希望可以实现延迟一定时间再消费消息。 典型的场景有微信、支付宝等第三方支付回调接口,会在用户支付后3秒、5秒、30秒等等时间后向应用...

兜兜毛毛
6分钟前
0
0
【0918】正则介绍_grep

【0918】正则介绍_grep 9.1 正则介绍_grep上 9.2 grep中 9.3 grep下 一、正则介绍 正则是一串有规律的字符串,它使用单个字符串来描述或匹配一系列符合某个语法规则的字符串。 二、grep工具 ...

飞翔的竹蜻蜓
36分钟前
4
0
为什么要在网站中应用CDN加速?

1. 网页加载速度更快 在网站中使用CDN技术最直接的一个好处就是它可以加快网页的加载速度。首先,CDN加速的内容分发是基于服务器缓存的,由于CDN中缓存了不少数据,它能够给用户提供更快的页...

云漫网络Ruan
今天
8
0
亚玛芬体育(Amer Sports)和信必优正式启动合作开发Movesense创新

亚玛芬体育和信必优正式启动合作开发Movesense创新,作为亚玛芬体育的完美技术搭档,信必优利用Movesense传感器技术为第三方开发移动应用和服务。 Movesense基于传感器技术和开放的API,测量...

symbiochina88
今天
4
0
创龙TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA核心板规格书

SOM-TL437xF是一款广州创龙基于TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA芯片设计的核心板,采用沉金无铅工艺的10层板设计,适用于高速数据采集和处理系统、汽车导航、工业自动化等领...

Tronlong创龙
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部