相信大家经过之前的学习,已经对C语言的基本内容(数据表达和运算等)有了初步认识,下面我们通过一些典型程序解析,讨论分支结构程序设计的思想和实现。
实例1:
- 猜数游戏
输入你所猜的整数yournumber(假定1~100内),与计算机产生的被猜数mynumber比较,若相等,显示猜中;若不等,显示与被猜数的大小关系。
可以分析:
yournumber vs mynubmer 有3种情况:
yournumber == mynumber
yournumber > mynumber
yournumber < mynumber
可以使用分支结构:
♾️ c 代码:if (==) Good Guess!
else if (>) Too big!
else Too small!
代码如下:
♾️ c 代码:# include <stdio.h>
int main (void)
{
int mynumber = 38;
int yournumber;
printf ("Input your number: ");
scanf ("%d", &yournumber);
if ( yournumber == mynumber ){
printf ("Good Guess!\n");
}else if ( yournumber > mynumber ){
printf ("Too big!\n");
}else{
printf ("Too small!\n");
}
return 0;
}
运行结果:
♾️ c 代码:Input your number:38
Good Guess!
多层缩进的书写格式,使程序层次分明。
分支结构
下面来看看二分支结构:
左图用if-else语句实现,该语句的一般形式为:
if (表达式)
语句1
else
语句2
右图用省略else的if语句实现,一般形式为:
♾️ c 代码:if (表达式)
语句1
实例2
奇偶分家
♾️ c 代码:
输入一个正整数n,再输入n个非负整数,统计奇数和偶数各有多少个?
在这里 偶数用number % 2 == 0表示
代码如下:#include <stdio.h> int main (void) { int count_odd, count_even, i, n, number; count_odd = 0; count_even = 0; printf ("Enter n: "); scanf ("%d", &n); printf ("Enter %d numbers: ", n); for (i = 1; i <= n; i++){ scanf ("%d", &number); //读入一个非负整数number if ( number % 2 != 0 ){ /* 该数为偶数 */ count_odd++; }else{ /* 该数为奇数 */ count_even++; } } printf ("Odd: %d, Even: %d \n", count_odd, count_even); return 0; }
运行程序:
♾️ c 代码:Enter n: 4 Enter 4 numbers: 5 8 101 9 Odd: 3, Even: 1
实例3
统计学生成绩
♾️ c 代码:
输入一个正整数n,再输入n个学生的成绩,计算平均分,并统计不及格成绩的个数。
首先分析程序:for (i = 1; i <= n; i++){ 输入1个学生的成绩 score 累加成绩 total 统计不及格成绩的个数 count } 输出结果
代码如下:
♾️ c 代码:# include <stdio.h>
int main (void)
{ int count, i, n;
double score, total;
printf ("Enter n: "); scanf ("%d", &n);
total = 0; count = 0;
for (i = 1; i <= n; i++){
printf ("Enter score #%d: ", i);
scanf ("%lf", & score);
total = total + score;
if (score < 60) {
count++;
}
}
if(n != 0) printf("Average = %.2f\n", total / n);
else printf("Average = %.2f\n", 0.0);
printf ("Number of failures = %d\n", count);
return 0;
}
输出结果:
♾️ c 代码:Enter n: 4
Enter score #1: 67
Enter score #2: 54
Enter score #3: 88
Enter score #4: 73
Grade average = 70.50
Number of failures = 1
下面来看看多分支结构
else-if 语句是最常用的实现多分支(多路选择)的方法:
♾️ c 代码:if (表达式1)
语句1;
else if (表达式2)
语句2;
……
else if (表达式n-1)
语句n-1;
else
语句n;
实例4
- 分段计水费
居民应交水费y(元)与月用水量x(吨)的函数
关系式如下,并编程实现。
根据x的范围分成3段,代码如下:
# include <stdio.h>
int main (void)
{
double x, y;
printf ("Enter x:");
scanf ("%lf", &x);
if (x < 0){
y = 0;
}else if (x <= 15){
y = 4 * x / 3;
}else{
y = 2.5 * x - 10.5;
}
printf ("f(%.2f) = %.2f\n", x, y);
return 0;
}
输出结果:
♾️ c 代码:Enter x: -0.5
f(-0.50) = 0.00
Enter x: 9.5
f(9.50) = 12.67
实例5
- 四则运算
输入一个形式如“操作数 运算符 操作数”的四则运算表达式,输出运算结果。
程序解析:
♾️ c 代码:value1 op value2
(op:存放一个字符 + - * / 等)
if(op == '+') value1 + value2
else if (op == '-') value1 – value2
else if (op == '*') value1 * value2
else if (op == '/') value1 / value2
else "Unknown operator”
代码如下:
♾️ c 代码:# include <stdio.h>
int main (void)
{ double value1, value2;
char op;
printf ("Type in an expression: ");
scanf ("%lf%c%lf", &value1, &op, &value2);
if (op == '+'){
printf ("=%.2f\n", value1 + value2);
}else if (op == '-'){
printf ("=%.2f\n", value1 - value2);
}else if (op == '*'){
printf ("=%.2f\n", value1 * value2);
}else if (op == '/'){ //对除数为0的情况作特别处理
if (value2 != 0){
printf ("=%.2f\n", value1 / value2);
}else{
printf ("Divisor can not be 0!\n");
}
}else{
printf ("Unknown operator!\n");
}
return 0;
}
输出结果:
♾️ c 代码:Type in an expression: 3.1+4.8
=7.90
注意:
操作符与运算符之间必须连续输入,两者之间不能有空格。
字符型数据
字符型常量
指单个字符,用一对单引号及其括起来的字符来表示。如: 'A'
、 'a'
'$'
.
要区分数字和数字字符:
1是数字,'1'是字符。
字符型变量定义:
char op
字符型数据的输入和输出
1.调用scanf和printf输入输出字符
字符型的格式控制说明为 %c
。
2.字符输入函数getchar ()
输入一个字符
char ch;
ch = getchar ( );
3.字符输出函数putchar ()
输出一个字符
putchar (输出参数);
putchar()和getchar()只能处理单个字符的输入输出,即调用一次函数,只能输入或者输出一个字符。如果要多次输入输出字符,就需要多次调用。
实例6
- 输出一批字符
输入8个字符,然后将这些字符输出,输出时在字符之间加一个减号,第一个字符的前面和最后一个字符的后面都没有减号。
代码如下:
♾️ c 代码:char ch;
int first = 1, k; /* first为1表示将要处理第1个字符 */
printf("Enter 8 characters: ");
for(k = 1; k <= 8; k++){
ch = getchar();
if ( first == 1 ){
putchar(ch);
first = 0; /* first为0表示将要处理第2个及其后字符 */
}else{
putchar('-');
putchar(ch);
}
}
输出结果:
♾️ c 代码:Enter 8 characters: AMETHYST
A-M-E-T-H-Y-S-T
实例7
查询自动售货机中商品的价格
♾️ c 代码:
假设自动售货机出售4种商品,薯片(crisps)、爆米花(popcorn)、巧克力(chocolate)和可乐(cola),售价分别是每份3.0、2.5、4.0和3.5元。
在屏幕上显示菜单:
[1] Select crisps
[2] Select popcorn
[3] Select chocolate
[4] Select cola
[0] Exit
用户可以连续查询商品的价格,当查询次数超过5次时,自动退出查询;不到5次时,用户可以选择退出。
当用户输入编号1~4,显示相应商品的价格;输入0,退出查询;输入其他编号,显示价格为0。
程序分析:显示菜单 for (i = 1; i <= 5; i++){ 输入选项choice if (choice == 0) 退出循环 若choice ==1~4 price赋单价 ==其他 price赋0 输出单价 }
代码如下:
♾️ c 代码:#include <stdio.h> int main (void) { int choice, i; double price; printf ("[1] Select crisps \n"); printf ("[2] Select popcorn \n"); printf ("[3] Select chocolate \n"); printf ("[4] Select cola \n"); printf ("[0] exit \n"); for( i = 1; i <= 5; i++) { printf ("Enter choice: "); scanf ("%d", &choice); if (choice == 0) break; switch (choice) { case 1: price = 3.0; break; case 2: price = 2.5; break; case 3: price = 4.0; break; case 4: price = 3.5; break; default: price = 0.0; break; } printf ("price = %0.1f\n", price); } printf ("Thanks \n"); }
输出结果:
♾️ c 代码:[1] Select crisps
[2] Select popcorn
[3] Select chocolate
[4] Select cola
[0] Exit
Enter choice: 1
price = 3.0
Enter choice: 7
price = 0.0
Enter choice: 0
Thanks
今天有个很重要的语句:switch语句
switch语句可用来处理多分支选择问题,根据break语句的使用方法有3种情况:
1.在switch语句的每个语句段中都使用break语句,这是switch语句的主要用法,一般形式为:
♾️ c 代码:switch(表达式){ //这里表达式要能计算出一个逻辑值
case 常量表达式1:语句段1; break; //这里是常量表达式,只能是一个常量,不能使用变量和表达式
case 常量表达式2:语句段2; break;
....…
case 常量表达式n:语句段n ; break;
default : 语句段n+1; break;
}
break只能跳出最近范围,即一个"{}".
表达式和常量表达式的值一般是整型和字符型,所有的常量表达式的值都不能相等。
default可以省略,省略后,如果表达式的值与任何一个常量表达式都不相等,就什么都不执行。
实例8
两个数的简单计算器
♾️ c 代码:
编写一个简单计算器程序,可根据输入的运算符,对两个整数进行加、减、乘、除和求余运算,请对除数为0的情况作特别处理。要求使用switch语句编写。
代码如下:# include <stdio.h> int main(void) { int value1, value2; char op; printf ("Type in an expression: "); scanf ("%d%c%d", &value1, &op, &value2); switch (op){ case '+': printf ("=%d\n", value1 + value2); break; case '-': printf ("=%d\n", value1 - value2); break; case '*': printf ("=%d\n", value1 * value2); break; case '/': //对除数为0特殊处理 if (value2 != 0) printf ("=%d\n", value1 / value2); else printf ("Divisor can not be 0!\n"); break; case '%': if (value2 != 0) printf ("=%d\n", value1 % value2); else printf ("Divisor can not be 0!\n"); break; default: printf ("Unknown operator\n"); break; } return 0; }
要记住题目要求对除数为0特殊处理
2.在switch语句中不使用break语句
break语句在switch中是可选的,也可以不使用,一般形式如下:
♾️ c 代码:switch(表达式){ case 常量表达式1:语句段1; case 常量表达式2:语句段2; ....… case 常量表达式n:语句段n; default : 语句段n+1; }
当没有break时,继续执行下一语句段,直到遇到下一个break才停止。即switch语句中可以使用break语句终止程序的继续执行。
3.在switch的某些语句段中使用break
实例9:统计字符
输入n个字符,分别统计出其中空格或回车、数字字符和其他字符的个数。
♾️ c 代码:
代码如下:# include <stdio.h> int main (void) { int blank, digit, i, n, other; //定义三个变量分别存放统计结果 char ch; blank = digit = other = 0; //给存放统计结果的三个变量的初值赋值为0 printf ("Enter n:"); scanf ("%d", &n); getchar (); /* 读入并舍弃换行符 */ printf ("Enter %d characters:", n); //提示输入n个字符 for (i = 1; i <= n; i++){ ch = getchar(); switch (ch){ case ' ' : case '\n': blank ++; break; case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : digit ++; break; //10个常量表达式'0'~'9'共用该语句段 default: other ++; break; } } printf ("blank=%d, digit=%d, other=%d\n", blank, digit, other); return 0; }
switch的局限:
由于在switch中所有的语句都需要被单列出来,所以表范围的语句尽量不使用switch,switch可放在if语句中较简单的语句中使用。
嵌套语句
像if-else语句中还能继续使用if-else,这种结构叫做嵌套。如:
♾️ c 代码:if (表达式1)
if (表达式2) 语句1
else 语句2
else
if (表达式3) 语句3
else 语句4
在嵌套的if-else语句中,如果内嵌的if省略了else部分,可能在语义上产生二义性。
- 所以内嵌的if最好不要省略else部分。
else和if的匹配原则:
♾️ c 代码:
else与最靠近它的、没有与别的else匹配过的if匹配。if (表达式1) if (表达式2) 语句1 else if (表达式3) 语句3 else 语句4
- 有两种方法改变else和if的配对
1.使用大括号,即构造一个复合语句。
2.增加一个空的else与之配对。