【声明】本章重点学习分支语句和循环语句的使用,计划对本章内容做两次更新。
其中代码内容注释较多,可能会给读者造成些许阅读障碍,建议电脑阅读。
由于水平有限,如发现有错误之处,恳切希望读者们批评指正,以免自己或他人入坑!
文章目录
本节重点
分支语句
什么是语句?
C语言中由一个分号;隔开的就是一条语句。
如:
int main()
{
printf("hehe\n");//它是一条语句
3 + 5;//它是一条语句
;//空语句
return 0;
}
什么叫分支语句?
分支语句对应的是选择结构
if 语句
if语句的语法结构
写法1(单分支):if(表达式)//if里面的表达式为真,语句执行,为假,语句不执行
语句;
写法2(双分支):if(表达式)//if里面的表达式为真,语句1执行,为假,语句2执行
语句1;
else
语句2;
写法3(多分支):if(表达式1)//判断表达式1是否成立,如果成立执行语句1,如果不成立判断表达式2
语句1;
else if(表达式2)
语句2;
else
语句3;
提问:C语言是如何表示真和假的呢?
答:非0就是真,0就是假
if语句的语法结构举例逐一讲解
单分支
#include<stdio.h>
int main()
{
int age = 10;
if (age >= 19)
printf("成年\n");//打印结果为空
return 0;
}
双分支
int main()
{
int age = 10;
if (age >= 18)
printf("成年\n");
else
{
printf("未成年\n");
printf("不能谈恋爱");
}
//注意:if和else只能控制一条语句,若想控制多条,需要给它们加上大括号,不带大括号,默认控制1条语句。
//一对大括号叫做一个代码块
return 0;
}
多分支
int main()
{
int age = 160;
if (age < 18)
printf("少年\n");
//else if (18 <= age < 26)//这种表达式的写法是错误的,这样写它会先判断18<=age,结果为真就是1,结果为假就是0,1或0再和26比较,背离初衷。
else if (age >= 18 && age < 26)//这种写法正确
printf("青年\n");
else if (age >= 26 && age < 40)
printf("中年\n");
else if (age >= 40 && age < 60)
printf("壮年\n");
else if (age >= 60 && age < 100)
printf("老年\n");
else //最后这个else也可不写
printf("老不死\n");
return 0;
}
悬空else
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对齐就跟哪个if匹配
因此要重视代码的书写风格,对齐方式,正确书写,以免阅读出错,易于阅读!!
代码分析
if语句书写形式的对比
关于写代码的风格
//num=5的写法
int num = 1;
if (num = 5)//如果我们不小心少写一个等于号,就变成了赋值操作,此时代码也能正常运行,这种写代码风格,不易发现错误
{
printf("hehe\n");//此时打印结果为:hehe
}
return 0;
}
//5=num的写法
int mian()
{
int num = 1;
if (5=num)//如果我们不小心少写一个等于号,就变成了赋值操作,此时代码会给出错误提示,这种写代码风格,易于发现错误,建议采用!!
{
printf("hehe\n");//此时打印会报错,因此可以发现错误
}
return 0;
}
练习:判断一个数是不是奇数
奇数就是除2余1的数字
int main()
{
int num = 15;
if (num % 2 == 1)
printf("奇数\n");
return 0;
}
练习:输出1-100之间的奇数
方式一:
int main()
{
int i= 0;
for (i = 1; i <= 100; i++)
{
if (i % 2 == 1)
printf("%d ", i);
}
return 0;
}
方式二:
int main()
{
for (int i = 1; i <= 100; i += 2)
{
printf("%d ", i);
}
return 0;
}
switch语句 (分支语句)
语法格式:
switch(整型表达式)
{
语句项;
}
语句项是什么呢?
它是一些case语句
如:
case 整型常量表达式: //case后必须是整型常量表达式
语句;
下面来一个例子
int main()
{
int day = 0;
scanf("%d", &day);//把输入的值放到day里面去
switch (day)//switch中的day是几就从case几里面进去(入口),
{
case 1: //case决定入口
printf("星期一\n");
break; //决定出口,只要执行break的话就会跳出case,直接走到最后
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
//不执行break 程序就不会跳出,后面的case也都会执行
//不执行break 程序就不会跳出,后面的case也都会执行
case 4:
printf("星期四\n");
case 5:
printf("星期五\n");
case 6:
printf("星期六\n");
case 7:
printf("星期天\n");
}
return 0;
}
下面再来一个例子,并且输出要求是
1-5工作日
6-7休息日
int main()
{
int day = 0;
scanf("%d", &day);//把输入的值放到day里面去
switch (day)//switch中的day是几就从case几里面进去(入口),
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");//此时前面不加break才能满足要求,因此case后面的break并不是必须加的而是看需不需要
break;
case 6:
case 7:
printf("休息日\n");
break;//最后一个break可加可不加,但最好加上。
default : //default写在前面后面都可以,它是处理异常的
printf("输入错误\n");
break;
}
return 0;
}
switch语句也可嵌套
int main()
{
int n = 1;
int m = 2;
switch (n)//n此时是1,因此需要从case1进去
{
case 1:m++;//3
case 2:n++;//2
case 3:
switch (n)//n此时是2,因此需要从case2进去
{//switch允许嵌套使用
case 1:
n++;
case 2:m++; n++;//4,3
break;//此时的break跳出的是嵌套的switch语句
}
case 4:
m++;//5
break;
default:
break;
}
printf("m=%d,n=%d\n", m, n);//打印结果:m=5,n=3
return 0;
}
循环
while循环
while 语法结构
while(表达式) //表达式结果如果为真,循环语句就会被执行,否则循环停止
循环语句;
举例理解语法
int main()
{
while (1)
printf("hehe\n");//打印结果;hehe死循环
return 0;
}
打印1-10的数
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d ", i);
i++;
}
return 0;
}
while循环里面也会有break跳出循环
break的用法
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break;//如果i=5,跳出循环
printf("%d ", i);
i++;
}
return 0;
//总结:在while循环中,break用于永久的终止循环
}
continue的用法
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue;
//总结continue作用是跳过本次循环continue后面的代码,
//直接去判断部分,看是否进行下一次循环,因为i++在后面,所以就造成了死循环
printf("%d ", i);//打印结果:1 2 3 4后面死循环
i++;
}
return 0;
}
while循环流程图含break和continue
疑问:
1.什么时候用break?
当某个条件发生的时候,循环要终止,就用break
2.什么时候用continue?
当某个条件发生的时候,这一次continue不执行了,但还要继续下一次判断时,因为整个循环还没有结束时用continue
分析下面两个代码
代码1
#include<stdio.h>
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)//getchar读取一个字符放到ch中,如果它不等于EOF(即不是遇到错误了),
//那就正常读取一个字符,并把这个字符打印到屏幕上
{
//getchar:是获取一个字符的意思
//EOF//是定义的一个符号,值是-1.它的全称是end of file(文件结束标志)
putchar(ch);//putchar是输出一个字符到屏幕上。它是getchar对应的输出函数
//它等于:printf("%c\n",ch);
}
return 0;
}
这样的代码有什么意义呢?
1.不断地在屏幕上读取一个字符
2.键盘上按ctrl+z:getchar就读取结束,相当于getchar读到了一个EOF
3.getchar和键盘之间有一个缓冲区,当缓冲区是空时,getchar等待,当输入一个字符并点击回车时,这时getchar实际读到的是一个字符和\n
getchar应用场景
#include<stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码:>");
scanf("%s", password);//password是一个数组,数组的数组名本身就是一个地址,因此不用写&符号
printf("请确认密码(Y/N):>");//如果输入Y,输出确认成功,否则输出确认失败
int ch=getchar();//使用getchar获取要输入的字符
if (ch == 'Y')
{
printf("确认成功\n");//打印结果:如下图
}
else
{
printf("确认失败\n");
}
return 0;
}
上面代码打印结果:
打印结果出错?!!!
为什么呢?
不管是getchar还是scanf他们都是输入函数,这些输入函数是从哪里获取相关信息的呢?
是从键盘上拿到数据吗?当然不是
答:
它要去从输入函数和键盘之间的缓冲区里面拿数据,如果发现缓冲区里面没有数据,它就会等待从键盘里输入信息到缓冲区里面去,如果输入函数发现缓冲区里面有东西
了,它就会拿走;
同时回车会触发scanf去读内容,此时读到的内容是123456;
接下来就是执行“请确认密码”这一行,正常情况下,getchar会等待输入一个字符(Y/N),但此时却没有等待,因为getchar发现缓冲区里面还有一个\n,所以就没有等待直接拿走了\n,并将\n放到了ch里面去了,此时ch就不等于Y了,因此就执行了else,在这个过程中并没有等待让我们输入Y或N,因此没有得到我们想要的输出内容。
那么如何解决这个问题呢?
答:
只要把缓冲区里面的\n清除掉即可(清楚之后getchar就会等待输入一个字符了)。
解决方式:
在getchar前面再写一个getchar让它先把\n处理掉,因为此时的这个getchar读取字符后不用了,所以就无须再设置变量进行存储了,这时第二个getchar就等待输入,就能执行成功了!
代码如下
#include<stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码:>");
scanf("%s", password);//password是一个数组,数组的数组名本身就是一个地址,因此不用写&符号
printf("请确认密码(Y/N):>");//如果输入Y,输出确认成功,否则输出确认失败
getchar();//清理缓冲区,处理'\n'
int ch = getchar();//使用getchar获取要输入的字符
if (ch == 'Y')
{
printf("确认成功\n");//
}
else
{
printf("确认失败\n");
}
return 0;
}
运行结果
可是这时又出现了一个问题
但是如果我们输入的是123456 abcdef\n呢?此时又会出现什么结果呢?
代码及运行结果如下:
这又是什么原因呢?
答:scanf只读缓冲区里面的123456,剩余的
空格abcdef\n还在缓冲区里,但是一个getchar只能处理一个字符,想要处理多个字符就需要使用多个getchar,也就用到了循环,一直循环到读到\n停下来。
解决方式如下面代码:
int main()
{
char password[20] = { 0 };
printf("请输入密码:>");
scanf("%s", password);//password是一个数组,数组的数组名本身就是一个地址,因此不用写&符号
printf("请确认密码(Y/N):>");//如果输入Y,输出确认成功,否则输出确认失败
//清理缓冲区中的多个字符
int tmp = 0;//定义临时变量tmp
while ((tmp = getchar() != '\n'))//读取一个字符放到tmp里,如果读的字符不等于\n
{
;//它是一条空语句,什么都不执行,目的是将读到的字符扔掉,继续循环直到读到\n,跳出循环
}
int ch = getchar();//使用getchar获取要输入的字符
if (ch == 'Y')
{
printf("确认成功\n");//打印结果:截图
}
else
{
printf("确认失败\n");
}
疑问:getchar读取的是一个字符,为什么用整型变量来存的?
答:
1.getchar读取的是一个字符,而字符本质上是以ASCII码值的形式存储,ASCII码值是整型,所以可以写成int,从MSDN中也可查出它的返回值是int
2.getchar读取的时候不一定返回的就是ASCII码值,它也可能会返回EOF值,而EOF本质上是一个-1, -1不是ASCII值而是一个整数,因此返回类型是int
代码2
这个代码的目的是只打印数字字符
int main()
{
int ch = 0;
while ((ch = getchar() != EOF))
{
if (ch<'0' || ch>'9')//ASCII码表上只有0-9是数字字符,其他都是非数字字符
continue;//如果不是数字字符,就执行continue,continue就会跳过本次循环后面的代码,不打印,继续读;
//如果是数字字符,就没有进入if语句中的continue,就会打印
putchar(ch);//打印结果:如下图
}
return 0;
}
ASCII表
最后:附一张ASCII表