第六章 C控制语句:分支和跳转
6.1if语句
程序
#define _CRT_SECURE_NO_WARNINGS 1
//coladays.c -- 求出温度低于零度的天数
#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: %1.f%% were below freezing.\n",all_days,100.0*(float)cold_days/all_days);
if (all_days == 0)
printf("No data entered!\n");
return 0;
}
结果
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% were below freezing.
C:\Users\51670\Desktop\C Program\colddays.c\Debug\colddays.c.exe (进程 11200)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
6.2在if语句中添加else关键字
1.另一个例子:介绍getchar()和putchar()
getchar()函数没有参数,它返回来自输入设备的下一个字符。例如,下面的语句读取下一个输入字符并将它的值赋给变量ch:
ch = getchar();
该语句与下面的语句有同样的效果:
scanf("%c",&ch);
putchar()函数打印它的参数。例如,下面的语句将先前赋给ch的值作为字符打印出来:
putchar(ch);
该语句与下面的语句有同样的效果:
printf("%c",ch);
因为这些函数仅仅处理字符,所以它们比更通用的scanf()和printf()函数更快而且更简洁。它们不需要格式说明符,因为它们只对字符起作用。
3.ctype.h系列字符函数
本章稍后讨论的逻辑运算符提供一种方法以判断字符是否不是空格、逗号,如此等等,但是罗列所有可能性太麻烦。ANSI C有一系列标准的函数可以用来分析字符;ctype.h头文件包含了这些函数的原型。这些函数接受一个字符作为参数,如果该字符属于某特定的种类则返回非零值(真),否则返回零(假)。
#define _CRT_SECURE_NO_WARNINGS 1
//cypher2.c -- 改变输入,只保留非字母字符
#include<stdio.h>
#include<ctype.h> //为isalpha()函数提供原型
int main(void)
{
char ch;
while (1)
{
while ((ch = getchar()) != '\n')
{
if (isalpha(ch))
putchar(ch + 1);//如果是一个字母,改变它
else
putchar(ch);//否则原样打印它
}
putchar(ch); //打印换行字符
}
return 0;
}
结果
Look! It's a programmer!
Mppl! Ju't b qsphsbnnfs!

4.多重选择else if
用电量 | 价格 |
---|---|
第一个360kWh | 每kWh $0.12589 |
下一个320kWh | 每kWh $0.17901 |
超过680kWh | 每$0.20971 |
程序
#define _CRT_SECURE_NO_WARNINGS 1
//electric.c -- 计算用电账单
#include <stdio.h>
#define RATE1 0.12589 //第一个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);
if( kwh <= BREAK1 )
bill = RATE1 * kwh;
else if( kwh <= BREAK2 ) //用电量在360kwh和680kwh之间时
bill = BASE1 + ( RATE2 * (kwh - BREAK1) );
else
bill = BASE2 + ( RATE3 * (kwh - BREAK2) );
printf("The charge for %.1f kwh is $%1.2f.\n", kwh, bill);
return 0;
}
结果
Please enter the kwh used.
580
The charge for 580.0 kwh is $84.70.
C:\Users\51670\Desktop\C Program\electric\Debug\electric.exe (进程 3500)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
●传统上,C习惯用int类型作为标志,但是新型的_Bool型变量极佳地符合了这种需求。而且,通过包含stbool.h头文件,可以用bool代替关键字 _Bool表示这种类型,并用标识符true和false代替1和0。
程序
#define _CRT_SECURE_NO_WARNINGS 1
//2022年4月12日16:45:31
//divisors.c -- 使用嵌套显示一个数的约数
#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.\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;
}
结果
Please enter an integer for analysis; Enter q to quit.
36
36 is divisible by 2.
36 is divisible by 3.
36 is divisible by 4.
36 is divisible by 6.
Please enter another integer for analysis;Enter q to quit.
149
149 is prime.
Please enter another integer for analysis;Enter q to quit.
30077
30077 is divisible by 19.
Please enter another integer for analysis;Enter q to quit.
q
Bye.
C:\Users\51670\Desktop\C Program\divisors\Debug\divisors.exe (进程 2068)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
6.3获得逻辑性
●C保证逻辑表达式是从左至右求值的。
6.4一个统计字数的程序
程序
#define _CRT_SECURE_NO_WARNINGS 1
//2022年4月13日19:30:08
//wordcnt.c -- 统计字符、单词和行
#include <stdio.h>
#include <ctype.h> //为isspace()提供函数原型
#include <stdbool.h> //为bool、true和false提供定义
#define STOP '|'
int main(void)
{
char c; //读入字符
char prev; //读前一个字符
long n_chars = 0L; //字符数
long n_lines = 0; //行数
int n_words = 0; //单词数
int p_lines = 0; //不完整的行数
bool inword = false; //如果c在一个单词中,则inword等于true
printf("Enter text to be analyzed( | to terminate):\n");
prev = '\n'; //用于识别完整行
while ((c = getchar()) != STOP)
{
n_chars++; //统计字符
if (c == '\n')
n_lines++; //统计行
if ( !isspace(c) && !inword )
{
inword = true; //开始一个新单词
n_words++; //统计单词
}
if (isspace(c) && inword)
inword = false; //到达单词的尾部
prev = c; //保存字符值
}
if (prev != '\n')
p_lines = 1;
printf("charcters = %ld, words = %d, lines = %d,",n_chars,n_words,n_lines);
printf("partial lines = %d\n",p_lines);
return 0;
}
结果
Enter text to be analyzed( | to terminate):
Reason is a
powerful servant but
an inadequate master.
|
charcters = 55, words = 9, lines = 3,partial lines = 0
C:\Users\51670\Desktop\C Program\wordcnt\Debug\wordcnt.exe (进程 15476)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
6.5条件运算符?:
程序
#define _CRT_SECURE_NO_WARNINGS 1
//2022年4月13日19:55:59
//paint.c -- 使用条件运算符
#include <stdio.h>
#define COVERAGE 200 //每罐漆可喷的平方英尺数
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;
}
结果
Enter number of square feet to be painted:
200
You need 1 can of paint.
Enter next value ( q to quit):
215
You need 2 cans of paint.
Enter next value ( q to quit):
q
C:\Users\51670\Desktop\C Program\paint.c\Debug\paint.c.exe (进程 1996)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
●总结:条件运算符(?:)
总体注解:这个运算符带有三个操作数,每个操作数都是一个表达式。它们如下排列:
expression1 ? expression2 : expression3
expression1为真,整个表达式的值就为expression2。否则为expression3。
6.6循环辅助手段:continue和break
一般来说,进入循环体以后,在下次循环判断之前程序执行循环体中所有的语句。continue和break语句使您可以根据循环体内进行的判断结果来忽略部分循环甚至终止它。
1.continue语句
该语句可以用于三种循环形式。当运行到该语句时,它将导致剩余迭代部分被忽略,开始下一次迭代。如果continue语句处于嵌套结构中,那么它仅仅影响包含它的最里层的结构。
程序
#define _CRT_SECURE_NO_WARNINGS 1
//2022年4月19日10:05:25
//skippart.c -- 使用continue跳过部分循环
#include <stdio.h>
int main()
{
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;
}
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 score is %0.1f.\n", n, total / n);
printf("Low = %0.1f,high = %0.1f\n", min, max);
}
else
printf("No valid score were entered.\n");
return 0;
}
结果
Enter the first score ( q to quit ): 1
Accepting 1.0:
Enter next score ( q to quit): 2
Accepting 2.0:
Enter next score ( q to quit):
3
Accepting 3.0:
Enter next score ( q to quit): 4
Accepting 4.0:
Enter next score ( q to quit): 5
Accepting 5.0:
Enter next score ( q to quit): q
Average of 5 score is 3.0.
Low = 1.0,high = 5.0
C:\Users\51670\Desktop\C Program\skippart\Debug\skippart.exe (进程 324)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
2.break语句
如果break语句位于嵌套循环里,它只影响包含它最里层的循环。
6.7多重选择:switch和break
break语句用于循环和switch中,而continue仅用于循环。如果仅希望处理某个带标签的语句,swich语句要求使用break。另外,不能在C的case中使用一个范围。不能用变量作为case标签。
多重标签程序:
#define _CRT_SECURE_NO_WARNINGS 1
//2022年4月19日15:36:51
//vowels.c -- 使用多重标签
#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;
}//switch语句结束
}//while语句结束
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;
}
结果
Enter some text; enter # to quit.
I see under the overseer.#
number of vowels: A E I O U
0 7 1 1 1
C:\Users\51670\Desktop\C Program\vowels\Debug\vowels.exe (进程 12592)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
●总结:使用switch进行多重选择
关键字:
switch
总体注解:
程序控制按照expression的值跳转到相应的case标签处。然后程序流程继续通过所有剩余的语句,直到再次由break语句重定向。expression和case标签必须都是整型值(包括char),并且标签必须是常量或者完全由常量组成的表达式。如果没有与表达式值相匹配的case标签,那么控制定位到标签为default的语句,如果它存在的话。否则,控制传递给紧跟着switch语句的下一条语句。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)