引言
什么是语句?
通俗来讲:C语言中由一个分号;隔开的就是一条语句
C语言中的1语句分类,可以分位以下五类:
表达式语句,函数调用语句,控制语句,复合语句,空语句。
#include<stdio.h> int main() { 3 + 5;//表达式语句 printf("haha\n");//函数调用语句 ;//空语句 //有时候我们需要一条空语句,但是这条语句什么都不需要做,就可以使用 return 0; }
本篇博文主要是介绍控制语句
控制语句用于控制程序的执行流程,以实现程序的各种结构的方式(C语言是一种结构化的程序设计语言——C语言支持三种结构:顺序结构,选择结构,循环结构),它们由特定的语句定义符组成,C语言有九种控制语句。
三类:
条件判断语句也叫分支语句:if语句,switch语句;
循环执行语句:do while语句,while语句,for语句;
转向语句:break语句;goto语句;continue语句,return语句。
分支语句
if语句
语法结构
首先,我们先要了解if语句的语法结构是怎么样的?
if(表达式)//表达式为真则执行;表达式为假则不执行。0为假,非0为真
语句;
if(表达式)
语句1;
else
语句2;
if(表达式1)//多分支
语句1;
else if(表达式2)
语句2;
else
语句3;
关于在C语言种如何表示真假?
练习
接下来我们来练习一下:
//练习1:输入一个整数代表年龄, // 若大于等于18,则输出成年人 //否则输出未成年人
#include<stdio.h> int main() { int age = 0; scanf("%d", &age); if (age >= 18) printf("成年人\n"); else printf("未成年人"); return 0; }
如果我们想要实现多分支呢?
上面我们提到的三种语法结构都可以使用嵌套。
//练习2 //输入年龄数字 //输出对应的年龄 //age<18 未成年 //18~30 青年 //31~50 中年 //51~70 中老年 //71~99 老年 //>99 老寿星
#include<stdio.h> int main() { int age = 0; scanf("%d", &age); if (18>age) printf("青年\n"); else//age>=18范畴 { if (age >= 18 && 30 <= age) printf("青年"); else//age>30的范畴 { if (age >= 31 && 50 <= age) printf("中年"); else//age>50的范畴 { if (age >= 51 && 70 <= age) printf("中老年"); else//age>70的范畴 { if (age >= 71 && 99 <= age) printf("老年"); else//age>99的范畴 { if (age > 99) printf("老寿星"); } } } } } return 0; }
嵌套之后非常冗长,那我们能不能简化以下呢?
#include<stdio.h> int main() { int age = 0; scanf("%d", &age); if (18 > age) printf("青年\n"); else if (30 >= age) printf("青年"); else if (50 >= age) printf("中年"); else if (70 >= age) printf("中老年"); else if (99 >= age) printf("老年"); else printf("老寿星"); return 0; }
//练习3 //判断一个数是否为奇数
//练习:判断一个数是否为奇数 #include<stdio.h> int main() { int a = 0; scanf("%d", &a); if (a % 2 != 0) printf("奇数"); else printf("偶数"); return 0; }
//练习4 //输出1~100之间的奇数
//练习:输出1~100之间的奇数 #include<stdio.h> int main() { int a = 0; while (a <= 100) { //必须要加{},while只能控制一条语句。 a++; if (a % 2 != 0) printf("%d ", a); } return 0; }
注意的tips
NO1.限制条件的范围写法
为什么此刻输入50,屏幕上也打印了青年?
这是因为编译器先执行了18<=age这条语句为真,则为1;又执行了1<=30这条语句也为真,则可以输出青年。所以我们在取范围时,应该用&&或者||等。
NO2.代码块
为什么12未成年也可以执行谈恋爱?
因为if语句只能控制其他一条语句。若要控制多条需要用代码块
NO.3悬空的else
大家思考以下代码输出结果?
#include <stdio.h> int main() { int a = 0; int b = 2; if(a == 1) if(b == 2) printf("hehe\n"); else printf("haha\n"); return 0; }
答案是:什么都不输出。这是为什么呢?
因为else并不和第一个if匹配,而是和它离的最近的if匹配。那以上的写法很容易就看错。
所以我们注意else的匹配。同时我们也要养成良好的写代码的风格。
#include <stdio.h> int main() { int a = 0; int b = 2; if (a == 1) { if (b == 2) printf("hehe\n"); else printf("haha\n");//逻辑清晰的表达 } return 0; }
NO.4代码的书写形式
关于减少代码的错误,这里还有小的技巧。
#include<stdio.h> int main() { int a = 10;//= 赋值符号 //if (a == 5)//== 等于符号 //如果二者搞混,编译器不会报错,寻找错误很麻烦,如果代码很长 if(5 == a)//所以可以这么写 printf("hehe\n"); else printf("haha\n"); return 0; }
要想养成良好的代码风格,在平时练习中,我们就需要去注意。同时这里也推荐一本书《高质量的C C++编程》
switch语句
特别是,switch语句和if语句不能强制套用,还得分情况合理使用两种分支语句。
语法结构
switch(整型表达式)//需要强调是“整型”
{
语句项(case:语句);//是一些case语句,case:整型常量表达式语句
}
switch语句中的break
实例1: //输入1,输出星期一 //输入2,输出星期二 //输入3,输出星期三 //输入4,输出星期四 //输入5,输出星期五 //输入6,输出星期六 //输入7,输出星期七
明明我只想要输出星期三但是却把后面全部打印出来了?这就是缺少break。
在switch中我们没办法实现分支,但是搭配上break我们就可以实现break。
#include<stdio.h> int main() { int a = 0; scanf("%d", &a); switch(a) { 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; }
实例2: 1. 输入1-5输出的是“weekday”; 2. 输入6-7输出“weekend”;
#include<stdio.h> int main() { int a = 0; scanf("%d", &a); switch (a) { case 1: case 2: case 3: case 4: case 5: printf("weekday\n"); break; case 6: case 7: printf("weekend\n"); break; } return 0; }
综上所述:break语句的实际作用效果就是把语句列表划分为不同的部分。
switch语句中的default子句
default子句
如果表达的值余所有case标签的值都不匹配怎么办?
其实也没什么,结果就是所有的语句都被跳过而已。
程序并不会终止,也不会报错,因为这种情况在C中并不认为适合错误。
但是,如果你并不想忽略不匹配所有标签的表达式的值该怎么办?
你可以在语句列表中增加一条default子句,把下面的标签
default:
写在任何一个case标签可以出现的位置。
当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。
所以,每个swutch语句中只能出现一条default子句。
但是它可以出现在列表任何位置,而且语句流会像贯穿一个case标签一样贯穿default子句。
就像上面实例1中,我想输入有与8匹配的case标签是“选择错误,请重新输入值”,那该去写呢?
#include<stdio.h> int main() { int a = 0; scanf("%d", &a); switch(a) { 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; default: printf("选择错误,请重新输入值"); } return 0; }
以上就是我们全部的分支语句讲解,这里有一个练习,可以思考一下?m,n的值?
#include <stdio.h> int main() { int n = 1; int m = 2; switch (n) { case 1: m++; case 2: n++; case 3: switch (n) {//switch允许嵌套使用 case 1: n++; case 2: m++; n++; break; } case 4: m++; break; default: break; } printf("m = %d, n = %d\n", m, n); return 0; }
——————→m=5,n=3
循环语句
在前面我们学习了分支语句,但是这个语句要么不执行,要么只能执行一次。但是在我们生活当中,我们需要一件相同的事情重复做。那我们要怎样去做?
C语言中给我们引入了:循环语句。
while循环
语法结构
//while循环的语法结构
while(表达式)
循环语句;
while循环中的continue
#include<stdio.h> int main() { int i = 0;//循环变量 while (i <= 10)//判断条件 { i++; if (i == 4) continue; printf("%d ", i); }//循环语句 return 0; }
总结:continue在while循环中的作用就是:
continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环入口的判断。
while循环中的break
#include<stdio.h> int main() { int i = 0;//循环变量 while (i <= 10)//判断条件 { i++; if (i == 4) break; printf("%d ", i); }循环语句 return 0; }
总结:break在while循环中的作业:
其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。
所以:while中的break是用于永久终止循环的。
getchar和putchar
这里我们来介绍一下getchar和putchar。
getchar()作用是是获取(输入)一个字符。函数不接受任何的参数。——scanf
getchar读取字符成功的时候,返回字符的ASCLL码值。
读取失败或者遇到文件末尾的时候就返回EOF(-1)
putchar()作用是输出一个字符。——printf
使用1
//windows环境按ctrl+z getchar返回EOF #include <stdio.h> int main() { int ch = 0; while ((ch = getchar()) != EOF) { if (ch < '0' || ch > '9') continue; putchar(ch); //打印0~9的字符 } return 0; }
放张图方便以后复习🙂绝望了,怎么还没写完,反正也没人看!好烦,我爱写代码!
使用2
解析来我们用一个例子来循序渐进的讲解。🆒
关于下面这段代码为什么会出现读取失败的原因呢???
解释如下🙂🙂🙂
#include<stdio.h> int main() { char password[20]; printf("请输入密码:"); scanf("%s", password);//数组名本来就是地址不用取地址 //第一次scanf读取了缓存区的xgdtaq 留下了\n(回车)再缓存区。 printf("请确认密码(Y/N):"); char ch=getchar();//getchar只能读取一个字符 //当getchar读取字符的时候正好看到\n(回车算一个字符)就读取成功了 if (ch == 'Y') printf("确认成功"); else printf("确认失败"); //getchar读取到的\n≠"Y"就输出确认失败 return 0; }
此刻,我们需要再getchar读到\n时清空缓存区。所以我们需要在前面加入一个getchar。
但是如果我们想选用空格当作密码之一呢?
依然说确认失败,为什么呢?
因为scanf函数遇到空格就不在读取了,那我们可以在多加几个getchar就解决问题了,可是我们如果不知道输入的人想要在空格后输入多少位字符,所以这里我们又要用到我们的循环!!!
#include<stdio.h> int main() { char password[20]; printf("请输入密码:"); scanf("%s", password);//数组名本来就是地址不用取地址 while (getchar() != '\n');//循环条件 //增加一个循环,直到getchar读到\n,清空缓存区 { ; //表示这里有一条语句,需要这条空语句,什么都不干。 } printf("请确认密码(Y/N):"); char ch=getchar();//getchar只能读取一个字符 if (ch == 'Y') printf("确认成功"); else printf("确认失败"); return 0; }
以上代码就实现了清空缓存区。
for循环
语法结构
//for循环的语法结构
//for循环的语法优于while且用的很多
//循环安顺序需注意
for(表达式1;表达式2;表达式3)
循环语句;
使用for循环 在屏幕上打印1 - 10的数字 #include<stdio.h> int main() { int i = 0; while (i < 10) { i++; printf("%d ", i); } return 0; } //第一种 #include<stdio.h> int main() { int i = 1; while (i <= 10) { printf("%d ", i); i++; } return 0; } //第二种 #include<stdio.h> int main() { int i = 0; for (i = 1; i <= 10; i++) printf("%d ", i); return 0; } //第三种 //特点:初始化只执行一次
for循环中的break
//break在for循环中也是终止循环的作用 //while和for循环中break作用一样,只要遇到break都是终止循环。 #include<stdio.h> int main() { int i = 0; for (i = 1; i <= 10; i++) { if (i == 5) break; printf("%d ", i); } return 0; }
for循环中的continue
//在for循环中的continue,直接跳过continue后面的代码,来到for循环中的调整部分 //和while循环中的continue有区别 #include<stdio.h> int main() { int i = 0; for (i = 1; i <= 10; i++) { if (i == 5) continue; printf("%d ", i); } return 0; }
建议
1.我们在for循环体内部尽量不修改循环变量。 如果我们在循环体内部去修改循环变量,很可能导致得 不到想要的结果,从而导致死循环。
人会有以下写法,虽然它很简便,但是它有弊端。所定义的变量出了循环体就不能使用了。
#include<stdio.h> int main() { //C99时引出的写法 for ( int i = 1; i <= 10; i++) { printf("%d ", i); } //弊端就是i只能在循环体内部使用 //出了循环体就不能使用了 return 0; }
2.我们建议for循环的循环体采用"前闭后开区间"的写法。来看看对比,那个更容易理解?
//建议2.在for循环中尽量采用“左闭右开”的方法 //用数组和for循环打印1~10的数字 //左闭右开 #include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int i = 0; for (i = 0; i < 10; i++)//数组下标从0~9 //【0,10) printf("%d ", arr[i]);//打印下标即可 return 0; } //全闭 #include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int i = 0; for (i = 0; i <= 9; i++) //【0,10】 printf("%d ", arr[i]); return 0; }
for循环的变种
这里我们还有一个练习题,搞一下????
请问循环要循环多少次? #include <stdio.h> int main() { int i = 0; int k = 0; for(i =0,k=0; k=0; i++,k++) k++; return 0; }
——————————————-——→0次,看清楚for循环中判断条件是k=0,是赋值不是判断,意为把0赋值给k,表达式为假不进入循环
do while循环
语法结构
do
循环语句; //循环语句若为一条可不要{},反之有多条,必须加上{}
while(表达式); //表达式为真继续循环,为假跳出循环
//注意不要遗漏了后面的的分号
语法特点
do while循环至少执行一次,使用的场景有限,所以不是经常使用。
#include<stdio.h> int main() { int a = 0; do { a++; printf("%d ", a); } while (a < 10); return 0; } //循环至少执行一次,使用的场景有限,所以不是经常使用
do while循环中的break
break: 终止循环的作用。
#include<stdio.h> int main() { int a = 0; do { if (a == 5) break; a++; printf("%d ", a); } while (a < 10); return 0; }
do while循环中的continue
continue:终止本次循环。跳过本次循环后面的代码,直接去判断部分。
#include<stdio.h> int main() { int a = 1; do { if (a == 5) continue; printf("%d ", a); a++; } while (a < 10); return 0; }
go to语句
关于goto语句我们介绍三个点。
用法
跳转到前面:
#include<stdio.h> int main() { printf("1111 "); printf("2222 "); flag: printf("3333 "); goto flag; printf("4444 "); printf("5555 "); printf("6666 "); return 0; }
跳转到后面:
#include<stdio.h> int main() { printf("1111 "); printf("2222 "); printf("3333 "); goto flag; printf("4444 "); printf("5555 "); flag: printf("6666 "); return 0; }
适用
从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。 但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过 程,例如一次跳出两层或多层循环。 这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。
//真正适用场景如下 for(...) for(...) { for(...) { if(disaster) goto error; } } … error: if(disaster) // 处理错误情况
【在下面一篇文章中我们将继续介绍goto使用在一个关机程序上,可以先动手写写。】
提醒
NO1-----以上所有无论分支和循环语句,都只能控制一条语句,所以在写一条及多条语句的时候一定要加上{ }
NO2-----关于break和continue,请一定仔细判断,看好边界条件,才能得出正确答案✔✔✔
NO3-----关于==和=,等于和赋值我们一定要判断清楚,才不会把程序搞错。🙂🙂
✔✔✔✔✔最后,感谢大家的阅读,欢迎大家指针不足和错误!!🙂🙂🙂🙂
代码------→【gitee:https://gitee.com/TSQXG/c.start】
联系------→【邮箱:2784139418@qq.com】