關鍵字: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.
- while循環的測試條件利用scanf()的傳回值來結束循環,因為scanf()讀到非數字字元時會傳回0.
- 未避免整數除法,強制類型轉換。其實不使用也可以,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.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語句
// 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.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.3.1 備選拼寫:iso646.h頭檔案
7.3.2 優先級
a > b && b > c || b > d
((a > b) && (b > c)) || (b > d)
7.3.3 求值順序
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.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語句
/* 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.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