title: 第七章 C控制语句:分支和跳转
author: HardyDragon
tags: C Notes
第七章 C控制语句:分支和跳转
7.1 if语句
7.2 if else语句
7.2.1 介绍getchar()
7.2.2 ctype.h 系列的字符函数
7.2.3 多重选择else if
7.2.4 else与if配对
7.2.5 多层嵌套的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 多重选择
7.7.1 switch语句
7.7.2 只读每行的首字符
7.7.3 多重标签
7.7.2 swtich和if else
7.8 goto语句
7.9 关键概念
7.10 本章小结
7.11 复习题
7.12 编程练习
7.1 if语句
// colddays.c -- 找出0摄氏度的天数占总天数的百分比
#include <stdio.h>
int main(int argc, char const *argv[])
{
const int FREEZING = 0;
float temperature = 0;
int cold_days = 0;
int all_days = 0;
printf("输入每日的最低温度列表:(q退出)\n");
while (scanf("%f", &temperature) == 1)
{
/* code */
all_days++;
if (temperature < FREEZING)
{
cold_days++;
}
}
if (all_days != 0)
{
printf("一共 %d 天,其中 %.1f%% 天都是极冷的。\n ", all_days, 100.0* (float)cold_days / all_days);
}
if (all_days == 0)
{
printf("没有数据输入!\n");
}
return 0;
}
result:
输入每日的最低温度列表:(q退出)
12 12 -1 12 12 12 -1 -1 12 12 q
一共 10 天,其中 30.0% 天都是极冷的。
while循环的测试条件是scanf() 的返回值,当读到非数字字符时会返回0,同时将其放入缓冲区,等待下一次读取。temperature 的类型是float 不是 int,这样的程序可以接受像-2.5这样的值,也可以接受8这样的值,会被自动转换为float。
使用强制类型转换可以明确表达式转换类型的意图,保护被编译器的影响,虽然可以自动转换,但是还是使用强制转换来提醒。
7.2 if else语句
-
getchar() 函数不带任何参数,它从输入队列中返回下一个字符。以下两种写法相同。
ch = getchar(); scanf("%c",&ch);
putchar() 打印字符同理:
putchar(ch); printf("%c",ch);
由于这两个函数只是处理字符,所以比通用的scanf和printf速度更快,更简洁,
// cypher1.c -- 更改输入,空格不变,非空格替换成ASCII的下一个字符 #include <stdio.h> #define SPACE ' ' int main(int argc, char const *argv[]) { char ch; ch = getchar(); while (ch != '\n') { /* code */ if (ch == SPACE) { putchar(ch); } else { putchar(ch + 1); } ch = getchar(); } putchar('\n'); return 0; }
result:
aaa bbb ccc bbb ccc ddd
以上的循环可以替换成:
while(ch=getchar() != '\n'){ }
ctype.h 头文件可以判断字符和数字。
// cypher2.c -- 替换字母,非字母字符不变 #include<stdio.h> #include<ctype.h> int main(int argc, char const *argv[]) { char ch; while ((ch = getchar()) != '\n') { /* code */ if(isalpha(ch)){ putchar(ch+1); }else { putchar(ch); } } putchar(ch); return 0; }
result:
Look,it's a Mppl,ju't b
注意判断条件一定是 while ((ch = getchar()) != ‘\n’) 要带括号。因为 != 的优先级高。
// divisors.c -- 使用嵌套if语句显示一个数的约数 #include <stdio.h> #include <stdbool.h> int main(int argc, char const *argv[]) { unsigned long num; unsigned long div; bool isPrime; // flag 标记 素数标志 printf("输入一个数:q退出\n"); while (scanf("%lu", &num) == 1) { /* code */ for (div = 2, isPrime = true; (div * div) <= num; div++) { if (num % div == 0) { if ((div * div) % num != 0) { // 不是完全平方数 printf("%lu 可以被 %lu 和 %lu 整除\n", num, div, num / div); } else { printf("%lu 是完全平方数被 %lu 整除\n", num, div); } isPrime = false; } } if (isPrime) { printf("%lu 是素数!\n", num); } printf("输入一个数:q退出\n"); } printf("886"); return 0; }
result:
输入一个数:q退出 123456789 123456789 可以被 3 和 41152263 整除 123456789 可以被 9 和 13717421 整除 123456789 可以被 3607 和 34227 整除 123456789 可以被 3803 和 32463 整除 123456789 可以被 10821 和 11409 整除 输入一个数:q退出 149 149 是素数! 输入一个数:q退出 2013 2013 可以被 3 和 671 整除 2013 可以被 11 和 183 整除 2013 可以被 33 和 61 整除 输入一个数:q退出 q 886
7.3 逻辑运算符
&& 与 || 或 !非 ,引入 iso646.h 头文件可以 and or not 代替
// chcount.c -- 使用逻辑与运算符
#include<stdio.h>
#include <stdbool.h>
#define PERIOD '.'
int main(int argc, char const *argv[])
{
char ch;
int charcount = 0;
while ((ch = getchar() != PERIOD))
{
/* code */
if(ch!='"'&&ch!='\''){
charcount++;
}
}
printf("这里有 %d 个字符.\n",charcount);
return 0;
}
result:
中文二字符abcd.
这里有 14 个字符.
7.4 一个统计单词的程序
// wordcnt.c -- 统计字符数,单词数,行数
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#define STOP '|'
int main(int argc, char const *argv[])
{
char c; // 读入字符
char prev; // 读入的前一个字符
long n_chars = 0L; // 字符数
int n_lines = 0; // 行数
int n_words = 0; // 单词数
int p_lines = 0; // 不完整的行数
bool inword = false; // 如果c在单词中,inword为true
printf("输入文本以|结束:\n");
prev = '\n';
while ((c = getchar()) != STOP)
{
/* code */
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("字符数 = %ld,单词数 = %d ,行数 = %d, ",n_chars,n_words,n_lines);
printf("不完整的行数为 %d\n",p_lines);
return 0;
}
result:
输入文本以|结束:
Reasin is a
powerful servant but
an inadequate master.
|
字符数 = 55,单词数 = 9 ,行数 = 3, 不完整的行数为 0
--------------------------------------------------
输入文本以|结束:
123|
字符数 = 3,单词数 = 1 ,行数 = 0, 不完整的行数为 1
7.5 条件运算符:?:
带一个运算对象的称为一元运算符,两个就是二元运算符,3个运算对象的就叫三元运算符。问号语句也叫三元运算符。
// paint.c -- 使用条件运算符
#include <stdio.h>
#define COVERAGE 350 // 每一罐油漆可以刷的面积
int main(int argc, char const *argv[])
{
int sq_feet;
int cans;
printf("输入面积:q退出\n");
while (scanf("%d", &sq_feet) == 1)
{
/* code */
cans = sq_feet / COVERAGE;
cans += ((sq_feet % COVERAGE == 0)) ? 0 : 1;
printf("你需要 %d %s 来刷!\n", cans, cans == 1 ? "can" : "cans");
printf("输入面积:q退出\n");
}
return 0;
}
result:
输入面积:q退出
349
你需要 1 can 来刷!
输入面积:q退出
351
你需要 2 cans 来刷!
输入面积:q退出
q
7.6 循环辅助:continue 和 break
continue 跳过当前循环的剩余部分,进入下一次循环;break 终止当前层次的循环。
// skippart.c -- 使用continue跳过部分循环
#include <stdio.h>
int main(int argc, char const *argv[])
{
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("输入第一个分数(q退出):\n");
while (scanf("%f", &score) == 1)
{
/* code */
if (score < MIN || score > MAX)
{
printf("%0.1f 是一个非法的值,重新输入:", score);
continue;
}
printf("接收:%0.1f:\n", score);
min = (score < min) ? score : min;
max = (score > max) ? score : max;
total += score;
n++;
printf("输入第一个分数(q退出):\n");
}
if (n > 0)
{
printf("一共 %d 个分数的平均分是 %0.1f.\n", n, total / n);
printf("最小值 = %0.1f,最大值 = %0.1f\n", min, max);
}
else
{
printf("无效的分数!\n");
}
return 0;
}
result:
输入第一个分数(q退出):
1
接收:1.0:
输入第一个分数(q退出):
2
接收:2.0:
输入第一个分数(q退出):
3
接收:3.0:
输入第一个分数(q退出):
q
一共 3 个分数的平均分是 2.0.
最小值 = 1.0,最大值 = 3.0
--------------------------
输入第一个分数(q退出):
188
188.0 是一个非法的值,重新输入:12
接收:12.0:
输入第一个分数(q退出):
32
接收:32.0:
输入第一个分数(q退出):
q
一共 2 个分数的平均分是 22.0.
最小值 = 12.0,最大值 = 32.0
使用continue为了使代码逻辑简洁,有时也可以增加代码可读性。
while(getchar()!='\n'){
continue;
}
break 语句对switch语句很重要
7.7 多重选择:swtich和break
7.8 goto语句
让它爬。
入第一个分数(q退出):
q
一共 3 个分数的平均分是 2.0.
最小值 = 1.0,最大值 = 3.0
输入第一个分数(q退出):
188
188.0 是一个非法的值,重新输入:12
接收:12.0:
输入第一个分数(q退出):
32
接收:32.0:
输入第一个分数(q退出):
q
一共 2 个分数的平均分是 22.0.
最小值 = 12.0,最大值 = 32.0
使用continue为了使代码逻辑简洁,有时也可以增加代码可读性。
```c
while(getchar()!='\n'){
continue;
}
break 语句对switch语句很重要
7.7 多重选择:swtich和break
[外链图片转存中…(img-yqfGRyXt-1616425949909)]
[外链图片转存中…(img-TlvH7YFV-1616425949911)]
7.8 goto语句
让它爬。