什么是语句?
C语言中由一个分号;隔开的就是一条语句。比如:
printf("hello, world!\n");
printf("hehe\n");
分支语句
在现实生活中需要进行判断和选择的情况是很多的。比如:
- 如果你在家,我去拜访你。(需要判断你是否在家)。
- 如果考试不及格,需要补考。(需要判断考试是否合格)。
- 如果遇到红灯,要停车等待。(需要判断是否是红灯)。
- 周末去郊游。(需要判断是否是周末)。
- 本市人进本市景区免费。(需要判断是否是本市人)。
- 如果b * b - 4 * a * c >= 0,可以求出方程a * x * x + b * x + c = 0;的是跟。(需要判断b * b - 4 * a * c >= 0是否满足)。
C语言中有两种选择语句:
- if语句。
- switch语句。
if语句
0表示假,非0表示真。
代码演示
#include <stdio.h>
#include <math.h>
int main(){
double a, b, c, disc, p, q, x1, x2;
printf("Please input a, b and c: \n");
scanf("%lf %lf %lf", &a, &b, &c);
disc = b * b - 4 * a * c;
if(disc < 0){
printf("The equation hasn't real roots!\n");
}
else{
p = -b / (2 * a);
q = sqrt(disc) / (2 * a);
x1 = p + q;
x2 = p - q;
printf("real root: x1 = %7.2f\t x2 = %7.2f\n",
x1, x2);
}
return 0;
}
运行结果
[sss@aliyun choose]$ !gcc
gcc equation.c -o equation -lm
[sss@aliyun choose]$ ./equation
Please input a, b and c:
1 2 3
The equation hasn't real roots!
[sss@aliyun choose]$ ./equation
Please input a, b and c:
2 4 1
real root: x1 = -0.29 x2 = -1.71
多分支
#include <stdio.h>
#include <math.h>
int main(){
double a, b, c, disc, p, q, x1, x2;
printf("Please input a, b and c: \n");
scanf("%lf %lf %lf", &a, &b, &c);
disc = b * b - 4 * a * c;
if(disc < 0){
printf("The equation hasn't real roots!\n");
}
else if(disc == 0){
p = -b / (2 * a);
x1 = x2 = p;
printf("real root: x1 = x2 = %7.2f\n",
x1, x2);
}
else{
p = -b / (2 * a);
q = sqrt(disc) / (2 * a);
x1 = p + q;
x2 = p - q;
printf("real root: x1 = %7.2f\t x2 = %7.2f\n",
x1, x2);
}
return 0;
}
运行结果
[sss@aliyun choose]$ !gcc
gcc equation.c -o equation -lm
[sss@aliyun choose]$ ./equation
Please input a, b and c:
6 3 1
The equation hasn't real roots!
[sss@aliyun choose]$ ./equation
Please input a, b and c:
2 4 1
real root: x1 = -0.29 x2 = -1.71
[sss@aliyun choose]$ ./equation
Please input a, b and c:
1 2 1
real root: x1 = x2 = -1.00
if语句书写形式对比
**代码三和代码四更好,逻辑更加清晰,**不容易出错。不建议使用代码二,虽然使用代码二的写法能够更快的发现将==写成=的失误,但是这种写法可读性不好,而且现在的编译器检错能力都比较强,前面那种失误是可以被检查到的。
switch语句
switch语句也是一种分支语句,常常用于多分支的情况。
比如:
- 输入1,输出星期一。
- 输入2,输出星期二。
- 输入3,输出星期三。
- 输入4,输出星期四。
- 输入5,输出星期五。
- 输入6,输出星期六。
- 输入7,输出星期天。
写成if…else if… else if的形式太复杂,就可以使用switch语句。
switch(整型表达式){
语句项;
}
语句项是什么?
是一些case语句,如下:
case 整型常量表达式: 语句;
switch语句中的break
在switch语句中,我们没法直接实现分支,搭配break使用才能实现真正的分支。
比如:
#include <stdio.h>
int main(){
int day = 0;
printf("Please input the day: \n");
scanf("%d", &day);
switch(day){
case 1: printf("星期一\n"); break;
case 2: printf("星期二\n"); break;
case 3: printf("星期三\n"); break;
case 4: printf("星期四\n"); break;
case 5: printf("星期五\n"); break;
case 6: printf("星期六\n"); break;
case 7: printf("星期天\n"); break;
}
return 0;
}
运行结果
[sss@aliyun choose]$ gcc switch.c -o switch
[sss@aliyun choose]$ ./switch
Please input the day:
1
星期一
[sss@aliyun choose]$ ./switch
Please input the day:
7
星期天
需求变了
- 输入1~5,输出weekday。
- 输入6~7,输出weekend。
#include <stdio.h>
int main(){
int day = 0;
printf("Please input the day: \n");
scanf("%d", &day);
switch(day){
case 1:
case 2:
case 3:
case 4:
case 5: printf("weekday\n"); break;
case 6:
case 7: printf("weekend\n"); break;
}
return 0;
}
运行结果
[sss@aliyun choose]$ !gcc
gcc switch.c -o switch
[sss@aliyun choose]$ ./switch
Please input the day:
1
weekday
[sss@aliyun choose]$ ./switch
Please input the day:
5
weekday
[sss@aliyun choose]$ ./switch
Please input the day:
6
weekend
[sss@aliyun choose]$ ./switch
Please input the day:
7
weekend
break语句的实际效果是把语句列表划分为不同的部分。
在最后一个case语句的后面加上一条break语句。(防止最后一个case语句忘记添加break语句)。
default子句
- 如果表达的值域所有的case标签的值都不匹配怎么办?其实也没什么,所有的语句都被跳过而已。程序并不会终止,也不会报错,因为这种情况在C中并不认为是错误。但是,如果你不想忽略不匹配所有标签的表达式的值时该怎么办呢?你可以在语句列表中增加一条default子句,把下面的标签default:写在任何一个case标签可以出现的位置。
- 当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。但是它可以出现在语句列表的任何位置,而且语句流会像贯穿一个case标签一样贯穿default子句。建议在每个switch语句中都放一条default子句是个好习惯,甚至可以在后边再加一个break。
switch子句可以嵌套使用吗?
代码演示
#include <stdio.h>
int main(){
int day = 0;
printf("Please input the day: \n");
scanf("%d", &day);
switch(day){
case 1:
case 2:
case 3:
case 4:
case 5: switch(day){
case 1: printf("星期一\n"); break;
case 2: printf("星期二\n"); break;
case 3: printf("星期三\n"); break;
case 4: printf("星期四\n"); break;
case 5: printf("星期五\n"); break;
} break;
case 6:
case 7: switch(day){
case 6: printf("星期六\n"); break;
case 7: printf("星期天\n"); break;
} break;
}
return 0;
}
运行结果
[sss@aliyun choose]$ !gcc
gcc switch.c -o switch
[sss@aliyun choose]$ ./switch
Please input the day:
1
星期一
[sss@aliyun choose]$ ./switch
Please input the day:
5
星期五
[sss@aliyun choose]$ ./switch
Please input the day:
7
星期天
switch可以嵌套使用。
循环语句
前面介绍了分支语句,但是只了解分支语句是不够的,还需要用到循环结构(或者成重复结构)。因为在日常生活中或是在程序所处理的问题中常常遇到需要需要重复处理的问题。如:
- 要向计算机输入全班50个学生的成绩。(重复50次相同的输入操作)。
- 分别统计全班50个学生的平均成绩。(重复50次相同的计算操作)。
- 求30个整数之和。(重复30次相同的加法操作)。
- 检查30个学生的成绩是否及格。(重复30次相同的判别操作)。
C语言中有三种实现循环的方法:while、for、do while。
while语句实现循环
while语法结构
while(表达式)
循环语句;
while语句执行的流程:
代码演示
#include <stdio.h>
typedef struct Student{
int chinese;
int math;
int english;
} Student;
int main(){
int i = 0;
Student stu[5];
while(i < 5){
printf("Please input the No.%d student's score: \n",
i + 1);
scanf("%d %d %d",
&stu[i].chinese, &stu[i].math, &stu[i].english);
double avg = (stu[i].chinese + stu[i].math + stu[i].english)
/ 3.0;
printf("The No.%d student's average score is: %.1f\n",
i + 1, avg);
++i;
}
return 0;
}
运行结果
[sss@aliyun rotate]$ !gcc
gcc while.c -o while
[sss@aliyun rotate]$ ./while
Please input the No.1 student's score:
10 20 10
The No.1 student's average score is: 13.3
Please input the No.2 student's score:
20 10 30
The No.2 student's average score is: 20.0
Please input the No.3 student's score:
100 100 100
The No.3 student's average score is: 100.0
Please input the No.4 student's score:
59 95 100
The No.4 student's average score is: 84.7
Please input the No.5 student's score:
89 98 78
The No.5 student's average score is: 88.3
while中break和continue
break介绍
代码示例
#include <stdio.h>
int main(){
int i = 1;
while(i <= 10){
if(i == 5){
break;
}
printf("%d ", i);
++i;
}
printf("\n");
return 0;
}
运行结果
[sss@aliyun rotate]$ !gcc
gcc break.c -o break
[sss@aliyun rotate]$ ./break
1 2 3 4
总结:在循环中只要遇到break,就停止后期的所有循环,直接终止循环。while中的break是用于永久终止循环。
continue介绍
代码演示
#include <stdio.h>
int main(){
int i = 0;
while(i < 10){
++i;
if(i == 5){
continue;
}
printf("%d ", i);
}
printf("\n");
return 0;
}
注意:++i放到if(){}后会死循环。
运行结果
[sss@aliyun rotate]$ !gcc
gcc continue.c -o continue
[sss@aliyun rotate]$ ./continue
1 2 3 4 6 7 8 9 10
总结:continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳到while语句的判断部分。进行下一次循环的入口判断。
再来看两个代码
代码一
#include <stdio.h>
int main(){
int ch = 0;
while((ch = getchar()) != EOF){
putchar(ch);
}
return 0;
}
运行结果
[sss@aliyun rotate]$ !gcc
gcc getchar.c -o getchar
[sss@aliyun rotate]$ ./getchar
hss
hss
meng
meng
^C
代码二
#include <stdio.h>
int main(){
int ch = 0;
while((ch = getchar()) != EOF){
if(ch < '0' || ch > '9'){
continue;
}
putchar(ch);
}
return 0;
}
运行结果
[sss@aliyun rotate]$ !gcc
gcc getchar2.c -o getchar2
[sss@aliyun rotate]$ ./getchar2
1
1
h
2
2
t
^C
for循环
我们已经知道了while循环,为什么还要一个for循环呢?
for循环语法:
for(表达式1; 表达式2; 表达式3)
循环语句;
表达式1为初始化部分,用于初始化循环变量的。表达式2为条件判断部分,用于循环终止的判断。表达式3位调整部分,用于循环条件的调整。
代码演示
#include <stdio.h>
typedef struct Student{
int chinese;
int math;
int english;
} Student;
int main(){
int i = 0;
Student stu[5] = {0};
for(i = 0; i < 5; ++i){
printf("Please input the No.%d student's score: \n",
i + 1);
scanf("%d %d %d",
&stu[i].chinese, &stu[i].math, &stu[i].english);
double avg = (stu[i].chinese + stu[i].math + stu[i].english) / 3.0;
printf("The No.%d student's average is: %.1f\n",
i + 1, avg);
}
return 0;
}
运行结果
[sss@aliyun rotate]$ !gcc
gcc for.c -o for
[sss@aliyun rotate]$ ./for
Please input the No.1 student's score:
19 20 41
The No.1 student's average is: 26.7
Please input the No.2 student's score:
25 35 45
The No.2 student's average is: 35.0
Please input the No.3 student's score:
100 9 98
The No.3 student's average is: 69.0
Please input the No.4 student's score:
100 100 100
The No.4 student's average is: 100.0
Please input the No.5 student's score:
60 50 88
The No.5 student's average is: 66.0
for循环执行流程图
for循环与while循环的对比
可以发现在while循环中依然存在循环的三个必要条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹。for循环实用的频率也最高。
break和continue在for循环中
for循环中也可以出现break和continue,它们的意义和在while循环中是一样的。
建议:
- 不可在for循环体内修改循环变量,防止for循环失去控制。
- for语句的循环控制变量的取值采用半开半闭的写法。
半开半闭写法:
for(i = 0; i < 10; ++i){
}
全闭写法:
for(i = 0; i <= 10; ++i){
}
特殊的for循环
来看一段代码
#include <stdio.h>
int main(){
int i, k;
for(i = 0, k = 0; k = 0; ++i, ++k){
++k;
printf("test!\n");
}
return 0;
}
运行结果
[sss@aliyun rotate]$ !gcc
gcc test.c -o test
[sss@aliyun rotate]$ ./test
不会进入循环,判断条件k = 0;一直为假。
do…while()循环
do…while()语法:
do
循环语句;
while(表达式);
do…while()执行流程
do…while()语句特点
循环至少执行一次,使用的场景有限,不是经常使用。
代码演示
#include <stdio.h>
typedef struct Student{
int chinese;
int math;
int english;
} Student;
int main(){
int i = 0;
Student stu[5] = {0};
do{
printf("Please input the No.%d student's score: \n",
i + 1);
scanf("%d %d %d", &stu[i].chinese, &stu[i].math, &stu[i].english);
double avg = (stu[i].chinese + stu[i].math + stu[i].english) / 3.0;
printf("The No.%d student's average is: %.1f\n", i + 1, avg);
++i;
}
while(i < 5);
return 0;
}
运行结果
[sss@aliyun rotate]$ !gcc
gcc do_while.c -o do_while
[sss@aliyun rotate]$ ./do_while
Please input the No.1 student's score:
100 100 100
The No.1 student's average is: 100.0
Please input the No.2 student's score:
40 60 80
The No.2 student's average is: 60.0
Please input the No.3 student's score:
88 99 77
The No.3 student's average is: 88.0
Please input the No.4 student's score:
45 56 88
The No.4 student's average is: 63.0
Please input the No.5 student's score:
100 99 98
The No.5 student's average is: 99.0
goto语句
- goto语句也称为无条件转移语句。
- C语言中不限制程序中使用标号的次数,但各标号不得重名。goto语句的语义是改变程序流向,转去执行语句标号所标识的语句。
- 主要功能:跳出多重循环。
- 但是,在结构化程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难。