手写C语言之分支循环语句-语法详细版(06)
前言
前期,我们通过几篇文章了解了C语言的基本语法和大体的框架,认识了什么是C语言,C语言的重点和难点是什么?如何去学习C语言,总而言之,学习是一个不断积累的过程,想要从“量变到质变”,只有不断地练习,不断地总结。
可能有的粉丝朋友或者读者会疑问,为什么这个专栏叫手写C语言系列呢?难道现实的开发和工作中,真的是需要我们手写C语言吗?博主在这里很明确的告诉你,完全不需要,工作等于接触了实际项目,写代码和开发完全不需要死记硬背,只需要掌握基本的框架和思想,至于那些周而复始的语法,你完全可以利用网上的第三方平台,比如:这一篇博客,介绍了分支循环语句的详细的思想和语法,那么如果你在以后的项目实践中,突然短路了,那么此时这一篇博客的重要性就已经显现出来了。
之所以定义为:手写C语言,是因为目前我认为的熟练是自己能够看到题目就可以马上有这个代码的思路,而不是完全的死记硬背,当然,备也需要有规律有技巧的背,前提是你必须要熟练,这样你才可能比较容易得到更高的收获。
本专栏面向的是:
- 在校大学生,计算机系和对编程感兴趣的同学
- C语言小白,需要学习并且通过计算机二级等级考试的同学
- 平时没有努力的,但是想要期末努力的好学生
- 计算机大类下的考研党
这是我的初衷,也是我的回忆,为什么这些人群需要手写C语言呢?或者是为什么要达到手写C语言的效果呢?举一个简单的例子,期末考试难不成老师会给你开网络吗?(不排除“高手”),考研过程笔试,你有机会百度查询这个代码应该怎么写,那个函数不记得呢,还可以查查,就算是计算机二级考试,都是只给你比较简单的编译器(没有提示代码的功能),所以手写的目的不是为了不懂得变化,而是为了不变应万变!
废话不多说,我们开启新的知识旅途!
什么是语句?
C语句可分为以下五类:
- 表达式语句
- 函数调用语句
- 控制语句
- 复合语句
- 空语句
本文着重讲解控制语句:
控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。可分成以下三类:
- 条件判断语句也叫分支语句:if语句、switch语句;
- 循环执行语句:do while语句、while语句、for语句;
- 转向语句:break语句、goto语句、continue语句、return语句。
分支选择语句
if 语句
语法结构:
if(表达式)
{
语句;
}
if(表达式)
{
语句1;
}
else
{
语句2;
}
//多分支
if(表达式1)
{
语句1;
}
else if(表达式2)
{
语句2;
}
else
{
语句3;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
注意为了我们的代码规范,我们应该对于语法的要满足美观而不冗余,复杂但不失逻辑
#include <stdio.h>
int main()
{
int age = 0;
printf("请输入你的年龄:");
scanf("%d", &age);
if (age < 18)
{
printf("少年\n");
}
else if (age >= 18 && age < 30)
{
printf("青年\n");
}
else if (age >= 30 && age < 50)
{
printf("中年\n");
}
else if (age >= 50 && age < 80)
{
printf("老年\n");
}
else
{
printf("老寿星\n");
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
上面的这个代码就比较的完整的展现了条件分支的语法,代码也是比较的规范的,下面我们看看这个代码:
#include <stdio.h>
int main()
{
int score = 0;
printf("请输入你的分数:");
scanf("%d", &score);
if (score < 60) printf("不及格!");
else if (score >= 60 && score <= 80) printf("成绩中等!");
else printf("成绩不错!");
printf("输入错误!");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
首先看到这个代码,你是不是比较的懵,怎么都写在一行上面呢?C语言支持这样的语法,它不会报错,因为语句都是一个分号结束的!后面的最后一个代码,是分支语句都无法管到的,所以要想达到需求,就需要写代码块{}
故:最终无论你输入什么都会出现一个输入错误的信息!
#include <stdio.h>
int main()
{
if(表达式)
{
语句列表1;
}
else
{
语句列表2;
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
表达式内部的条件是:1则成立,0则不成立
我们来看看下面这个例子:
感觉很奇怪,为什么这个代码输出和我们预期的设想不一致呢?很显然这个代码虽然语法没有报错,但是存在逻辑错误!在C语言的语句里面,我们需要注意的是,逻辑判断的真假的顺序,如果第一个是满足的,那么它就会成为一个真的条件,及时后面不是满足的条件,这就和我们的运算符比较的类似:&(全部为真才为真,一个为假全为假) 和 |(一个为真就为真,全部为假才为假)
这里显然是满足了第一个条件18>0所以它就为1,然后1<10故成立,所以它就执行了这个分支下面的语句!
再看这里,-1满足大于0故为0,但是0却小于10故成立!
所以这是我们同学需要注意的一点细节,可能你自己写代码不会这样,但是如果你是参加一些考试或者面试,这个就会作为一个考点来让你很纠结!
悬空else
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("您好!\n");
else
printf("你好呀!\n");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
这个代码不会打印出来任何东西!
else的匹配:else是和它离的最近的if匹配的。
代码写得好不是对比写的比较深奥,而是养成一个良好的编程
switch语句
switch语句也是一种分支语句。常常用于多分支的情况。
那么这个和if else有什么区别呢?它的优势又在哪里呢?
switch(整型表达式)
{
语句项;
}
- 1
- 2
- 3
- 4
switch最大的优势就是,简洁的代码量可以快速执行需要判断的分支
switch和break
在switch语句中,我们没办法直接实现分支,搭配break使用才能实现真正的分支。
#include <stdio.h>
int main()
{
int day = 0;
printf("请输入星期几(数字):");
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
从这,我们就可以发现switch语句的特点了,break是必须的,在每一条语句后面,其次首先定义了一个变量,待用户输入,其次将这个变量传到这个switch括号里面,后面的就可以写case 加结果进行判断!
但是有时候,我们的需求发生了改变,比如输入1-5,那么就输出:工作日,好好工作!输入6-7就输出:假期,多出去走走吧!
从这里,我们就可以看到break的作用是什么呢?它就是结束这一条语句,如果没有的话就一直往下执行!
break语句 的实际效果是把语句列表划分为不同的分支部分。
通常的一些考试也会对这一个进行考察,对break进行不同范围的考察!
switch-default
如果表达的值与所有的case标签的值都不匹配怎么办?其实也没什么,结构就是所有的语句都被跳过而已。程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?
你可以在语句列表中增加一条default子句,把下面的标签:default:写在任何一个 case 标签可以出现的位置。
当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。
所以,每个switch语句中只能出现一条default子句。
但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
任意位置,而且只能出现一次!
#include <stdio.h>
int main()
{
int n = 1;
int m = 2;
switch (n)
{
case 1:
m++; // m:3
case 2:
n++; // n:2
case 3:
switch (n)
{//switch允许嵌套使用
case 1:
n++; //这里不会执行!因为条件是1,但是n是2
case 2:
m++; //m:4
n++;//n:2
break;
}
case 4:
m++;//m:5
break;
default:
break;
}
printf("m = %d, n = %d\n", m, n);
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
为什么是这个结果,大家一定要明白这个执行逻辑顺序,这里强调的是:break是跳出,如果没有写就会一次执行,但是前提是必须要满足这个条件(和变量有一一对应),且依次执行后面的语句。
这样对应上面的代码就可以完全可以看懂了!
switch也是选择题里面经常会考察的一个点,如果你觉得它难,那一定是没有理解到精髓,建议多看和多测试!
循环语句
while循环
当条件满足的情况下,if语句后的语句执行,否则不执行。但是这个语句只会执行一次。由于我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。那我们怎么做呢?
C语言中给我们引入了: while 语句,可以实现循环。
//while 语法结构
while(表达式)
循环语句;
- 1
- 2
- 3
表达式成立:1,不成立:0
死循环演示
#include <stdio.h>
int main()
{
int i = 0;
while (1) {
i++;
printf("正在执行第%d次任务!",i);
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
在写代码的过程中,我们需要避免死循环的产生!
break与continue
在循环中,我们经常需要使用这两个关键词关键词进行跳出循环,最终达到我们所需的要求的!
其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。
所以:while中的break是用于永久终止循环的。
我们在写代码的过程中,一定要学会自己分析算法,一般的考试和面试重点在于如何使用代码完成这个算法功能效果
九九乘法表(while)
比如,我们可以利用while循环自己写一个九九乘法表:
#include <stdio.h>
int main()
{
int i = 0;
while (i < 9) {
i++;
int j = 0;
while (j < i) {
j++;
printf("%d*%d=%d\t", i, j, i * j);
}
printf("\n");
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
那么有的同学就会疑问,如果是嵌套循环的话,break是怎么个规则法呢?
它的规则是,跳出本次循环,而不是全部循环!
#include <stdio.h>
int main() {
int i = 0;
while (i < 5) {
printf("%d", i);
while (i < 5) {
if (i == 0) {
break;
}
}
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
其次:continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,
而是直接跳转到while语句的判断部分。进行下一次循环的入口判断
#include <stdio.h>
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
putchar(ch);
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这个代码是什么意思呢?
首先getchar()是读取字符,但是它会把\0也读进去,也就是说,我们输入一个字符,一般不是一个字符,它还有一个反斜杠0
这里EOF是文件读取错误的一种显示!那么如果,我们需要达到回车之后,不进入下一行又该怎么去实现呢?
#include <stdio.h>
int main()
{
char ch = '\0';
while ((ch = getchar()) != EOF)
{
if (ch < ‘0’ || ch > ‘9’)
continue;
putchar(ch);
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
这个代码的作用是:只打印数字字符,跳过其他字符的,具有清空缓冲区的作用!
密码区缓冲代码
那么在日常的生活中我们有什么具体的案例?
假设,目前需要你写一个密码验证程序,用户输入密码进行确认,然后进行判断密码是否正确!
#include <stdio.h>
int main() {
char passwoed[15] = { 0 };
printf("请设置你的密码():");
scanf("%s", &passwoed);//读取密码,但是在终端我们会回车
//清空缓冲区,将\n清空,因为scanf只会接收password这个里面的东西
getchar();
printf("输入Y确认:");
getchar();//清空缓冲区
char result = getchar();
if (result = 'Y') {
printf("确认成功!");
}
else {
printf("确认失败!");
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
简单的来说就是,getchar()可以用来清空缓冲区,这样就避免bug的出现!
这样看来,C语言果然适合做一些系统和软件的设计,在python语言中,我们都不用担心这些东西!
但是真的这个程序就是没有bug的吗?我们如果请专业的测试人员,可能一测试!
当我们的密码里面出现空白格之后,也是不可以的,同时当我们输入过快的时候,没有输入Y而是输入的回车那么他也确认成功?
原来是,之前这个等号没有写出双等号!第一个bug解决了,那么我们继续解决第二个!
#include <stdio.h>
int main() {
char passwoed[15] = { 0 };
printf("请设置你的密码():");
scanf("%s", &passwoed);//读取密码,但是在终端我们会回车
//清空缓冲区,将\n清空,因为scanf只会接收password这个里面的东西
getchar();
printf("输入Y确认:");
//getchar();//清空缓冲区
int temp = 0;
while ((temp = getchar()) != '\n') {
;
}
char result = getchar();
if (result == 'Y') {
printf("确认成功!");
}
else {
printf("确认失败!");
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
每文一语
日积月累才是最好的前进!
文章来源: wxw-123.blog.csdn.net,作者:王小王-123,版权归原作者所有,如需转载,请联系作者。
原文链接:wxw-123.blog.csdn.net/article/details/124430256
- 点赞
- 收藏
- 关注作者
评论(0)