关键字: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语句
// 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang colddays.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang cypher1.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang cypher2.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang electric.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang divisors.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang chcount.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang wordcnt.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang paint.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang skippart.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang break.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang animals.c
[wlsh@wlsh-MacbookPro] 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;
}
[wlsh@wlsh-MacbookPro] ch07$ clang vowels.c
[wlsh@wlsh-MacbookPro] 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.8 goto语句
7.9 关键概念
7.10 本章小结