天天看點

第7章 C控制語句:分支和跳轉

關鍵字:if、else、switch、continue、break、case、default、goto

運算符:&&、||、?

函數:getchar()、putchar()、cype.h系列

如何使用if和if else語句,如何嵌套它們

在更複雜的測試表達式中用邏輯運算符組合關系表達式

C的條件運算符

switch語句

break、continue和goto語句

使用C的字元I/O函數:getchar()和putchar()

ctype.h頭檔案提供的字元分析函數系列

目錄

7.1 if語句

7.2 if else語句

7.2.1 介紹getchar()和putchar()

7.2.2 ctype.h系列的字元函數

7.2.3 多重選擇else if

7.2.4 多層嵌套的if語句

7.3 邏輯運算符

7.3.1 備選拼寫:iso646.h頭檔案

7.3.2 優先級

7.3.3 求值順序

7.3.4 範圍

7.4 一個統計單詞的程式

7.5 條件運算符:?

7.6 循環輔助:continue和break

7.6.1 continue語句

7.6.2 break語句

7.7 多重選擇:swithc和break

7.7.1 switch語句

7.7.2 隻讀每行的首字元

7.7.3 多重标簽

7.7.4 switch和if else

7.8 goto語句

7.9 關鍵概念

7.10 本章小結

7.1 if語句

// colddays.c -- finds percentage of days below freezing
#include <stdio.h>
int main(void)
{
    const int FREEZING = 0;
    float temperature;
    int cold_days = 0;
    int all_days = 0;
    
    printf("Enter the list of daily low temperatures.\n");
    printf("Use Celsius, and enter q to quit.\n");
    while (scanf("%f", &temperature) == 1)
    {
        all_days++;
        if (temperature < FREEZING)
            cold_days++;
    }
    if (all_days != 0)
        printf("%d days total: %.1f%% were below freezing.\n",
               all_days, 100.0 * (float) cold_days / all_days);
    if (all_days == 0)
        printf("No data entered!\n");
    
    return 0;
}
           
[[email protected]] ch07$ clang colddays.c 
[[email protected]] ch07$ ./a.out 
Enter the list of daily low temperatures.
Use Celsius, and enter q to quit.
12 5 -2.5 0 6 8 -3 -10 5 10 q
10 days total: 30.0% were below freezing.
           
  1. while循環的測試條件利用scanf()的傳回值來結束循環,因為scanf()讀到非數字字元時會傳回0.
  2. 未避免整數除法,強制類型轉換。其實不使用也可以,C的自動轉換類型規則,乘積會被強制轉換成浮點數。為什麼選擇用強制類型轉換,是因為明确表達轉換類型的意圖,保護程式免受不同版本的編譯器的影響。

7.2 if else語句

if ( expression )
    statement1
else
    statement2
           

7.2.1 介紹getchar()和putchar()

ch = getchar(); //隻處理字元,不需要轉換說明
scanf("%c",&ch);

putchar(ch);
printf("%c",ch)
           
// cypher1.c -- alters input, preserving spaces 
#include <stdio.h>
#define SPACE ' '             // that's quote-space-quote 
int main(void)
{
    char ch;
    
    ch = getchar();           // read a character         
    while (ch != '\n')        // while not end of line    
    {
        if (ch == SPACE)      // leave the space          
            putchar(ch);      // character unchanged      
        else
            putchar(ch + 1);  // change other characters  
                                //字元實際上作為整數存儲
        ch = getchar();       // get next character       
    }
    putchar(ch);              // print the newline        
    
    return 0;
}
           
[[email protected]] ch07$ clang cypher1.c 
[[email protected]] ch07$ ./a.out 
CALL ME HAL. 
DBMM NF IBM/
           
//ch = getchar();           // read a character         
    while ((ch = getchar()) != '\n')        // while not end of line    
    {
        if (ch == SPACE)      // leave the space          
            putchar(ch);      // character unchanged      
        else
            putchar(ch + 1);  // change other characters  
    //    ch = getchar();       // get next character       
    }
           

C常見程式設計風格--把兩個行為合并成一個表達式.

另外“/”對應的ASCII碼比“.”對應的ASCII碼多1

7.2.2 ctype.h系列的字元函數

// cypher2.c -- alters input, preserving non-letters
#include <stdio.h>
#include <ctype.h>            // for isalpha()
int main(void)
{
    char ch;
    
    while ((ch = getchar()) != '\n')
    {
        if (isalpha(ch))      // if a letter,
            putchar(ch + 1);  // display next letter
        else                  // otherwise,
            putchar(ch);      // display as is
    }
    putchar(ch);              // display the newline
    
    return 0;
}
           
[[email protected]] ch07$ clang cypher2.c 
[[email protected]] ch07$ ./a.out 
Look! It's a programmer!
Mppl! Ju't b qsphsbnnfs!
           
第7章 C控制語句:分支和跳轉

7.2.3 多重選擇else if

// electric.c -- calculates electric bill 
#include <stdio.h>
#define RATE1   0.13230       // rate for first 360 kwh      
#define RATE2   0.15040       // rate for next 108 kwh  
#define RATE3   0.30025       // rate for next 252 kwh
#define RATE4   0.34025       // rate for over 720 kwh       
#define BREAK1  360.0         // first breakpoint for rates  
#define BREAK2  468.0         // second breakpoint for rates 
#define BREAK3  720.0         // third breakpoint for rates
#define BASE1   (RATE1 * BREAK1)
// cost for 360 kwh            
#define BASE2  (BASE1 + (RATE2 * (BREAK2 - BREAK1)))
// cost for 468 kwh
#define BASE3   (BASE1 + BASE2 + (RATE3 *(BREAK3 - BREAK2)))
//cost for 720 kwh
int main(void)
{
    double kwh;               // kilowatt-hours used         
    double bill;              // charges                     
    
    printf("Please enter the kwh used.\n");
    scanf("%lf", &kwh);       // %lf for type double         
    if (kwh <= BREAK1)
        bill = RATE1 * kwh;
    else if (kwh <= BREAK2)   // kwh between 360 and 468     
        bill = BASE1 + (RATE2 * (kwh - BREAK1));
    else if (kwh <= BREAK3)   // kwh betweent 468 and 720
        bill = BASE2 + (RATE3 * (kwh - BREAK2));
    else                      // kwh above 680               
        bill = BASE3 + (RATE4 * (kwh - BREAK3));
    printf("The charge for %.1f kwh is $%1.2f.\n", kwh, bill);
    
    return 0;
}
           
[[email protected]] ch07$ clang electric.c 
[[email protected]] ch07$ ./a.out 
Please enter the kwh used.
580
The charge for 580.0 kwh is $97.50.
           

7.2.4 多層嵌套的if語句

第7章 C控制語句:分支和跳轉
// divisors.c -- nested ifs display divisors of a number
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
    unsigned long num;          // number to be checked
    unsigned long div;          // potential divisors
    bool isPrime;               // prime flag
    
    printf("Please enter an integer for analysis; ");
    printf("Enter q to quit.\n");
    while (scanf("%lu", &num) == 1)
    {
        /*
        for (div = 2; div < num; div++)
            if(num % div == 0)
                printf("%lu is divisible by %lu and %lu.\n",num, div, num / div);
        */
        for (div = 2, isPrime = true; (div * div) <= num; div++)
        //num是144,當div = 12時停止循環 。 num是145,當div = 13時停止循環
        {
            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; // number is not prime
            //如何知道一個數是素數?如果沒有進入if語句,就是素數,标記(flag)
            }
        }
        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;
}
           
[[email protected]] ch07$ clang divisors.c 
[[email protected]] ch07$ ./a.out 
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.
           
第7章 C控制語句:分支和跳轉
第7章 C控制語句:分支和跳轉

7.3 邏輯運算符

// chcount.c  -- use the logical AND operator
#include <stdio.h>
#define PERIOD '.'
int main(void)
{
    char ch;
    int charcount = 0;
    
    while ((ch = getchar()) != PERIOD)
    {
        if (ch != '"' && ch != '\'') //如果測試字元不是雙引号,并且也不是單引号
            charcount++;
    }
    printf("There are %d non-quote characters.\n", charcount);
 
    return 0;
}
           
[[email protected]] ch07$ clang chcount.c 
[[email protected]] ch07$ ./a.out 
I didn't read the "I'm a Programming Fool" best seller.
There are 50 non-quote characters.
           
第7章 C控制語句:分支和跳轉

7.3.1 備選拼寫:iso646.h頭檔案

7.3.2 優先級

a > b && b > c || b > d
((a > b) && (b > c)) || (b > d)
           

7.3.3 求值順序

第7章 C控制語句:分支和跳轉

7.3.4 範圍

if(range >= 90 && range <= 100)

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

if(islower(ch))
           

7.4 一個統計單詞的程式

// wordcnt.c -- counts characters, words, lines
#include <stdio.h>
#include <ctype.h>         // for isspace()
#include <stdbool.h>       // for bool, true, false
#define STOP '|'
int main(void)
{
    char c;                 // read in character
    char prev;              // previous character read
    long n_chars = 0L;      // number of characters
    int n_lines = 0;        // number of lines
    int n_words = 0;        // number of words
    int p_lines = 0;        // number of partial lines
    bool inword = false;    // == true if c is in a word
//一個單詞裡是否有某個字元,在程式讀入單詞的首字元時把标記inword設定為1
//隻要為1,後續的非空白字元都不記為單詞的開始
    
    printf("Enter text to be analyzed (| to terminate):\n");
    prev = '\n';            // used to identify complete lines
    while ((c = getchar()) != STOP)
    {
        n_chars++;          // count characters
        if (c == '\n')
            n_lines++;      // count lines
        if (!isspace(c) && !inword) //查找單詞,不含空格
        {
            inword = true;  // starting a new word
            n_words++;      // count word
        }
        if (isspace(c) && inword)
            inword = false; // reached end of word
        prev = c;           // save character value
    }
    
    if (prev != '\n')
        p_lines = 1;
    printf("characters = %ld, words = %d, lines = %d, ",
           n_chars, n_words, n_lines);
    printf("partial lines = %d\n", p_lines);
    
    return 0;
}
           
[[email protected]] ch07$ clang wordcnt.c 
[[email protected]] ch07$ ./a.out 
Enter text to be analyzed (| to terminate):
Reason is a 
powerful servant but 
an inadequate master.
!
|
characters = 58, words = 10, lines = 4, partial lines = 0
           
如果c不是空白字元,且inword為假
    設定inword為真,并給單詞計數
如果c是空白字元,且inword為真
    設定inword為假
即讀到每個單詞的開頭時,把inword設定為1(真),在讀到每個單詞的末尾時把inword設定為0(假),隻有标記從0設定為1時,遞增單詞計數。
if(inword) if(inword == true)
if(!inword) if(inword == false)
           

7.5 條件運算符:?

條件運算符是C語言中唯一的三元運算符

expression1 ? expression2 : expression3
           
/* paint.c -- uses conditional operator */
//計算給定平方英尺的面積需要多少罐油漆,用平方英尺數除以每罐油漆能刷的面積,但是,商店隻賣整罐油漆,不會拆分來賣,是以1.7罐,就需要兩罐。得到小樹結果應該進1.

#include <stdio.h>
#define COVERAGE 350       // square feet per paint can
int main(void)
{
    int sq_feet;
    int cans;
    
    printf("Enter number of square feet to be painted:\n");
    while (scanf("%d", &sq_feet) == 1)
    {
        cans = sq_feet / COVERAGE; //截斷
        cans += ((sq_feet % COVERAGE == 0)) ? 0 : 1; //整除 ; 餘數
        printf("You need %d %s of paint.\n", cans,
               cans == 1 ? "can" : "cans");
        printf("Enter next value (q to quit):\n");
    }
    
    return 0;
}
           
[[email protected]] ch07$ clang paint.c 
[[email protected]] ch07$ ./a.out 
Enter number of square feet to be painted:
349
You need 1 can of paint.
Enter next value (q to quit):
351
You need 2 cans of paint.
Enter next value (q to quit):
q
           
第7章 C控制語句:分支和跳轉

7.6 循環輔助:continue和break

7.6.1 continue語句

/* skippart.c  -- uses continue to skip part of loop */
#include <stdio.h>
int main(void)
{
    const float MIN = 0.0f;
    const float MAX = 100.0f;
    
    float score;
    float total = 0.0f;
    int n = 0;
    float min = MAX;
    float max = MIN;
    
    printf("Enter the first score (q to quit): ");
    while (scanf("%f", &score) == 1)
    {
        if (score < MIN || score > MAX)
        {
            printf("%0.1f is an invalid value. Try again: ",
                   score);
            continue;   // jumps to while loop test condition
            //跳過本次疊代的剩餘部分,并開始下一輪疊代。
            //continue語句在嵌套循環内,則隻影響包含該語句的記憶體循環
        }

        /*
        //減少主語句組的一級縮進,提高代碼可讀性

            if(score < MIN || score > MAX) {}
            else{

            }

            if(score >= 0 && score <=100)
        */
        printf("Accepting %0.1f:\n", score);
        min = (score < min)? score: min;
        max = (score > max)? score: max;
        total += score;
        n++;
        printf("Enter next score (q to quit): ");
    }
    if (n > 0)
    {
        printf("Average of %d scores is %0.1f.\n", n, total / n);
        printf("Low = %0.1f, high = %0.1f\n", min, max);
    }
    else
        printf("No valid scores were entered.\n");
    return 0;
}
           
[[email protected]] ch07$ clang skippart.c 
[[email protected]] ch07$ ./a.out 
Enter the first score (q to quit): 50
Accepting 50.0:
Enter next score (q to quit): 200
200.0 is an invalid value. Try again: q
Average of 1 scores is 50.0.
Low = 50.0, high = 50.0
           
count = 0;
while (count < 10)
{
    ch = getchars();
    if(ch == '\n')
        continue;
    putchar(ch);
    count++;
}
//除換行符,因為ch是換行符,程式會跳過count++語句,并重新顯示它們

for(count = 0; count < 10; count++)
{
    ch = getchars();
    if(ch == '\n')
        continue;
    putchar(ch)
}
//換行符也計算在内
           

7.6.2 break語句

第7章 C控制語句:分支和跳轉
/* break.c -- uses break to exit a loop */
#include <stdio.h>
int main(void)
{
    float length, width;
    
    printf("Enter the length of the rectangle:\n");
   //while(scanf("%f %f",&length,&width)==2)
    while (scanf("%f", &length) == 1)
    {
        printf("Length = %0.2f:\n", length);
        printf("Enter its width:\n");
        if (scanf("%f", &width) != 1)
            break;
        printf("Width = %0.2f:\n", width);
        printf("Area = %0.2f:\n", length * width);
        printf("Enter the length of the rectangle:\n");
    }
    printf("Done.\n");
    
    return 0;
}
           
[[email protected]] ch07$ clang break.c 
[[email protected]] ch07$ ./a.out 
Enter the length of the rectangle:
10
Length = 10.00:
Enter its width:
20
Width = 20.00:
Area = 200.00:
Enter the length of the rectangle:
ab
Done.
           

7.7 多重選擇:swithc和break

switch(整型表達式)
{
    case 常量1:
        語句
    case 常量2
        語句
    default:
        語句
}
           
/* animals.c -- uses a switch statement */
#include <stdio.h>
#include <ctype.h>
int main(void)
{
    char ch;
    
    printf("Give me a letter of the alphabet, and I will give ");
    printf("an animal name\nbeginning with that letter.\n");
    printf("Please type in a letter; type # to end my act.\n");
    while ((ch = getchar()) != '#')
    {
        if('\n' == ch)
            continue;
        if (islower(ch))     /* lowercase only          */
            switch (ch)
        {
            case 'a' :
                printf("argali, a wild sheep of Asia\n");
                break;
            case 'b' :
                printf("babirusa, a wild pig of Malay\n");
                break;
            case 'c' :
                printf("coati, racoonlike mammal\n");
                break;
            case 'd' :
                printf("desman, aquatic, molelike critter\n");
                break;
            case 'e' :
                printf("echidna, the spiny anteater\n");
                break;
            case 'f' :
                printf("fisher, brownish marten\n");
                break;
            default :
                printf("That's a stumper!\n");
        }                /* end of switch           */
        else
            printf("I recognize only lowercase letters.\n");
        while (getchar() != '\n')
            continue;      /* skip rest of input line */
        printf("Please type another letter or a #.\n");
    }                        /* while loop end          */
    printf("Bye!\n");
    
    return 0;
}
           
[[email protected]] ch07$ clang animals.c 
[[email protected]] ch07$ ./a.out 
Give me a letter of the alphabet, and I will give an animal name
beginning with that letter.
Please type in a letter; type # to end my act.
a
argali, a wild sheep of Asia
Please type another letter or a #.
dab
desman, aquatic, molelike critter
Please type another letter or a #.
r
That's a stumper!
Please type another letter or a #.
Q
I recognize only lowercase letters.
Please type another letter or a #.
#
Bye!
           

7.7.1 switch語句

第7章 C控制語句:分支和跳轉

7.7.2 隻讀每行的首字元

7.7.3 多重标簽

// vowels.c -- uses multiple labels
#include <stdio.h>
int main(void)
{
    char ch;
    int a_ct, e_ct, i_ct, o_ct, u_ct;
    
    a_ct = e_ct = i_ct = o_ct = u_ct = 0;
    
    printf("Enter some text; enter # to quit.\n");
    while ((ch = getchar()) != '#')
    {
        switch (ch)
        {
            case 'a' :
            case 'A' :  a_ct++;
                break;
            case 'e' :
            case 'E' :  e_ct++;
                break;
            case 'i' :
            case 'I' :  i_ct++;
                break;
            case 'o' :
            case 'O' :  o_ct++;
                break;
            case 'u' :
            case 'U' :  u_ct++;
                break;
            default :   break;
        }                    // end of switch
    }                        // while loop end
    printf("number of vowels:   A    E    I    O    U\n");
    printf("                 %4d %4d %4d %4d %4d\n",
           a_ct, e_ct, i_ct, o_ct, u_ct);
    
    return 0;
}
           
[[email protected]] ch07$ clang vowels.c 
[[email protected]] ch07$ ./a.out 
Enter some text; enter # to quit.
I see under the overserr.#
number of vowels:   A    E    I    O    U
                    0    6    1    1    1
           

7.7.4 switch和if else

第7章 C控制語句:分支和跳轉
第7章 C控制語句:分支和跳轉

7.8 goto語句

第7章 C控制語句:分支和跳轉

7.9 關鍵概念

第7章 C控制語句:分支和跳轉

7.10 本章小結

第7章 C控制語句:分支和跳轉
第7章 C控制語句:分支和跳轉