【C初阶】-分支循环语句(2)

switch语句:

switch语句也是一种分支语句。常常用于多分支的情况。
举一个例子:
我们先用上节讲的if……else if……else if语句写这样一个程序

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	if (1 == day)
	{
		printf("星期1\n");
	}
	else if (2 == day)
	{
		printf("星期2\n");
	}
	else if (3 == day)
	{
		printf("星期3\n");
	}
	else if (4 == day)
	{
		printf("星期4\n");
	}
	return 0;
}

分析这个程序可知这个程序的目的就是输出星期几。
但这种形式显然有些太复杂,所以我们就需要一个不一样的语法形式。
即就是switch语句。

(1)switch语句的一般形式

switch(整型表达式)
{
   语句项;
}

注意:switch的括号里面必须是一个整型表达式

(2)语句项是什么呢

是一些case语句
如下

case 整型常量表达式:
     语句

(3)在switch语句中的break

在switch语句中我们没法实现分支,搭配break使用才能实现真正的分支。
比如刚才输出星期几的程序,如果我们这样写:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("星期1\n");
	case 2:
		printf("星期2\n");
	case 3:
		printf("星期3\n");
	case 4:
		printf("星期4\n");
	case 5:
		printf("星期5\n");
	case 6:
		printf("星期6\n");
	case 7:
		printf("星期天\n");
	}
	return 0;
}

按我们正常所需,输入1的时候需要输出星期1
好我们看运行结果:
在这里插入图片描述
可以看到输入1进去后,程序直接将星期一到星期天全部打印了出来那么接下来我们分析一下原因
原因:由于在case语句后面没有使用break语句,所以当case1语句生效后并没有成功的跳出switch语句,而是接下来顺序执行,将每个case语句都执行了一遍才结束的,所以每个case下面的打印函数都会生效一次,就会把星期1到星期天全部打印出来。
接下来使用break语句改正好程序:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("星期1\n");
		break;
	case 2:
		printf("星期2\n");
		break;
	case 3:
		printf("星期3\n");
		break;
	case 4:
		printf("星期4\n");
		break;
	case 5:
		printf("星期5\n");
		break;
	case 6:
		printf("星期6\n");
		break;
	case 7:
		printf("星期天\n");
		break;
	}
	return 0;
}

运行结果:
在这里插入图片描述
我们可以清楚的看到在每个case语句后加了break语句,这个时候case1执行完后程序成功的跳转了出来,只输出了星期一,这就是switch语句中break的作用。

而有时候我们的需求变了,比如我们提出以下要求:
①输入1-5输出的是工作日
②输入6-7输出的是休息日
所以我们的代码就应该这样实现了:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日\n");
		break;
	case 6:
	case 7:
		printf("休息日\n");
		break;
	}
	return 0;
}

运行结果:
在这里插入图片描述
所以说break语句的实际效果是把语句列表划分为不同的部分。

编程的好习惯:
在最后一条case语句后面加上一条break语句。(之所以这样写是可以避免出现以前的最后一个case语句后面忘了添加break语句)。
试想某一天别人更改你的程序的时候,需要在你最后一条case语句后面再加东西,如果你习惯性不加,万一别人没注意到那就会产生bug,同时当你改正别人程序的时候,你也会希望他的程序更加严谨,这就是一个好的程序员应该具有的素质。

(4)default子语句

如果表达的值与所有的case标签的值都不匹配怎么办?
其实也没什么,结构就是所有的语句都被跳过而已。
程序并不会终止,也不会报错,因为这种情况在C中并不认为适合错误。
但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?
你可以在语句列表中增加一条default子句,把下面的标签
default:
写在任何一个case标签可以出现的位置。 当 switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。
比如:

int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日\n");
		break;
	case 6:
	case 7:
		printf("休息日\n");
		break;
	default:
		printf("选择错误\n");
		break;
	}
	return 0;
}

这样当我们输入其他值的时候他就会自动报错:
运行结果:
在这里插入图片描述

同时注意,default语句可以出现在语句列表的任何位置,不会对结果造成影响
比如我们把上面程序的default语句写在最上面

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	default:
		printf("选择错误\n");
		break;
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日\n");
		break;
	case 6:
	case 7:
		printf("休息日\n");
		break;
	}
	return 0;
}

运行结果:
在这里插入图片描述

我们注意到运行结果没有任何变化
但是我们应该注意,一条switch语句中只能有一个default语句。

接下来我们看一道练习题:

#define _CRT_SECURE_NO_WARNINGS
#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 = ? n = ?分析:进入第一个switch语句时:n=1 m=2
由于switch语句的整型表达式为n,于是进入到case1
case1结束后:n=1 m=3
此时case1后面并没有break语句,于是继续执行case2
case2结束后:n=2 m=3
接下来进入case3时n=2,m=3,而switch语句的整型表达式为n,于是直接进入到case2
case2结束后:n=3 m=4
接下来遇到break语句跳出case3的switch语句,进入到第一个switch语句的case4
case4结束后:n=3 m=5接下来遇到break语句跳出switch语句,打印m和n的值分别为3和5
运行结果:
在这里插入图片描述
注意:switch语句允许嵌套使用

(2)循环语句

①while
②for
③do while

while循环

我们已经掌握了,if语句

if(条件)
    语句

当条件满足的情况下,if语句后的语句执行,否则不执行。
但是这个语句只会执行一次。但是我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。
那我们怎么做呢? C语言中给我们引入了:while语句,可以实现循环。

(1)while语法结构

while(表达式)
   循环语句

看一个简单的例子:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	while (1)
	{
		printf("hehe\n");
	}
	return 0;
}

分析:while表达式的值为常量1,所以判断恒为真,所以while语句一直执行,把hehe打印到屏幕上,这样我们就说程序陷入了死循环
运行结果:
在这里插入图片描述

(2)while语句的执行流程

在这里插入图片描述

(3)while循环中的continue语句

continue在while循环中的作用是:
continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。
我们看一下下面这个程序并且分析一下运行结果

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 1;
	while (i<=10)
	{
		if (i == 5)
		{
			continue;
		}
		printf("%d ", i);
		i++;
	}
	return 0;
}

分析:i的初始值为1,进入循环后一直从1打印到4,当i=5后,if语句里的continue语句触发,这时候后面的语句将不再执行,又回到while语句的初始位置判断,i的值依旧为5,然后继续刚才的操作,陷入了死循环,程序的运行结果就是打印出1-4然后陷入死循环。
运行结果:
在这里插入图片描述

(4)while循环中的break语句

break在while循环中的作用:
其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。 所以:while中的 break是用于永久终止循环的。
我们将上一个程序的continue改成break再看一下运行结果

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (i == 5)
		{
			break;
		}
		printf("%d ", i);
		i++;
	}
	return 0;
}

分析:程序开始还是和刚才一样,i的初始值为1,进入循环后一直从1打印到4。而当i=5后,if语句里的break语句触发,这时候直接跳出while循环,程序也就只打印了1-4,并且成功结束。
运行结果:
在这里插入图片描述

(5)介绍getchar和putchar

getchar 从键盘上获取一个字符
putchar 打印一个字符到屏幕上

举一个简单的例子让大家感受一下

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int ch = getchar();
	putchar(ch);
	return 0;
}

分析:我们用getchar从键盘上获取一个字符赋值给变量ch,再用putchar将变量ch打印到屏幕上
运行结果:
在这里插入图片描述
好,接下来我们看几个代码来更加深刻的了解getchar和putchar
代码一:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h> 
int main()
{
	int ch = 0;
	//EOF  ===>  -1
	while ((ch = getchar()) != EOF)
	{
		putchar(ch);
	}
	return 0;
}

分析:这个程序很简单,从键盘上获取一个字符,只要它不等于EOF就用putchar将它打印到屏幕上。
运行结果:
在这里插入图片描述
我们看到当我们输入一个字符,屏幕上就会跟着打印出来
而当我们输入EOF的时候,程序并没有结束,那是因为程序判断输入了E、O、F三个字符,并将它们打印了出来。
这里介绍一下EOF
EOF end of file
文件结束标志
想要输入它在键盘上按Ctrn加z就可以了

代码2:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int ch = 0; 
	while ((ch = getchar()) != EOF)
	{
		if (ch < '0' || ch>'9')
			continue;
		putchar(ch);
	}
	return 0;
}

分析:这个程序就是打印0-9之间的数,如果不在这个范围内,就会执行continue语句回到循环前,不会执行putchar语句。
运行结果:
在这里插入图片描述
我们看到,当我们输入0-9之间的数字时,会被打印出来,而输入其他字符的时候则什么都打印不出来。

for循环

(1)语法

for(表达式1;表达式2;表达式3
    循环语句;

表达式1 表达式1为初始化部分,用于初始化循环变量的。
表达式2 表达式2为条件判断部分,用于判断 循环时候终止。
表达式3 表达式3为调整部分,用于循环条件的调整。

(2)for循环的执行流程图:

在这里插入图片描述

(3)对比for循环和while循环

分别用for循环和while循环在屏幕上打印数字1-10
首先是while循环:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 0;//初始化部分
	while (i<10)//判断部分
	{
		printf("%d ", i);
		i++; //调整部分
	}
	return 0;
}

再看for循环:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 0;//初始化部分
	for (i = 0; i < 10; i++)
	{
	   printf("%d ", i);
	}
	return 0;
}

可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离 较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹。 for循环使用的频率也最高。

(4)for循环中的break和continue

我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的。 但是还是有些差异:
代码1:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 0;//初始化部分
	for (i = 0; i < 10; i++)
	{
		if (i == 5)
			break;
		printf("%d ", i);
	}
	return 0;
}

分析:i从0打印到4,当5进入循环后,break语句直接跳出循环,程序结束,所以输出的结果应该是将0-4打印到屏幕上。
运行结果:
在这里插入图片描述
我们可以看到break语句的用法基本没有太大变化。
代码2:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 0;//初始化部分
	for (i = 0; i < 10; i++)
	{
		if (i == 5)
			continue;
		printf("%d ", i);
	}
	return 0;
}

分析:程序前面从0打印到4没什么变化,这次等5进入循环后,执行continue,使得下面的打印函数没有执行,直接跳到表达式3中去,接下来从6打印到9,所以程序运行的结果应该是0 1 2 3 4 6 7 8 9
运行结果:
在这里插入图片描述
我们可以和前面switch语句里的continue对比一下,由于while循环中调整部分一般都是放在循环体的最后,所以当出现if(!0)的判断条件是,变量i不能调整,容易陷入死循环。而for语句的continue执行后直接回到调整部分,这样就不容易产生死循环。

(5)用for循环打印数组

直接看代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	//0-9
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

写法相信大家一眼就能看懂,这里提一点注意的地方:
注意:数组的下标是从0开始的,所以我们打印十个数的时候要定义初始值为0-9
接下来我们看一下运行结果:
在这里插入图片描述

(6)for语句的循环控制变量

不可在for循环体内修改循环变量,防止for循环失去控制。
看这样一组代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	for ( ; ; )
	{
		printf("hehe\n");
	}
	return 0;
}

我们直接看运行结果:
在这里插入图片描述
可以看到,程序直接陷入了一直打印hehe的死循环,那么为什么会陷入死循环呢?
原因:因为当for循环的判断部分省略掉的时候,默认表示恒为真
for里的三个表达式都没有,那么语句判断恒为真,就会陷入死循环了

再看两个例子:
例1:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 0;
	int j = 0;
	int count = 1;
	for (i = 0; i < 10; i++)
	{
		for (j = 0; j < 10; j++)
		{
			printf("hehe:%d\n", count);
			count++;
		}
	}
	return 0;
}

这是一个很简单的循环嵌套程序,这个程序我们可以很清楚的判断出它循环运行了100次,为了方便起见,我们定义了一个变量count来看它一共能够打赢多少hehe
接下来我们看运行结果:
在这里插入图片描述
我们可以很清楚的判断出程序一共运行了100次
那么我们再来看下一个例子
例2:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()

{
	int i = 0;
	int j = 0;
	int count = 1;
	for (; i < 10; i++)
	{
		for (; j < 10; j++)
		{
			printf("hehe:%d\n", count);
			count++;
		}
	}
	return 0;
}

我们再看一下这个代码,把例1代码中两个for循环的表达式1都没写,我们直接来看一下运行结果:
在这里插入图片描述
可以看到,这次的程序只打印了十个hehe,那么为什么会这样呢,我们来分析一下原因
原因分析:
i和j的初始化的值都是0,i进入第一个for语句,表达式1没写恒为真,表达式2,i<10成立,进入到第二个for循环
j进入第二个for语句,表达式1没写恒为真,表达式2,j<10成立,进入循环体,成功循环十次,打印10个hehe,j=10的时候跳出第二个循环又回到第一个循环
接下来i+1=2,第一个for语句表达式1和表达式2依旧成立,进入第二个for循环,这个时候表达式1肯定成立,但表达式j=10不成立又跳到第一个for循环,一直反复进行,直到i=10,跳出第一个循环,循环结束。最终结果就是只打印了十个hehe简单概括:由于表达式1没有初始化,导致循环失去了控制
所以再次强调,不要在for循环体内修改循环变量

建议for语句的循环控制变量的取值采用“前闭后开区间写法”
前开后闭的写法:

int i=0for(i=0;i<10;i++);
  {}

这种写法可以给循环赋予可读性,增加某种意义
比如这个循环我们可以清楚地看出我们需要循环执行10次
若是其他循环,把两个常量一减就可以清楚地看出循环次数个人认为养成这种写法习惯还是比较重要的

两边都是开区间:

 for(i=0;i<=9;i++{}

再来看一道笔试题:
请问循环要循环多少次?

 #include <stdio.h>
  int main() 
  {    
      int i = 0;    
      int k = 0;    
      for(i =0,k=0; k=0; i++,k++)        
      k++;    
      return 0; 
  }

分析:i和k的初始值都为1
进入for循环后,表达式1给两个变量都赋值为0,表达式2是一个赋值语句,把0的值赋给k,这时候表达式2为0并且判断0为假,跳出循环,所以该循环循环了0次。

do…while()循环

(1)do语句语法:

do
   循环语句;
while(表达式)

注意:while语句结束后要加一个分号;

(2)执行流程

在这里插入图片描述

(3)do语句的执行特点

循环至少执行一次,使用的场景有限,所以不是经常使用。
例:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 10;
	do
	{
		printf("%d\n", i);
	} while (i < 10);
	return 0;
}

分析一下do语句的执行特点,先执行循环体的内容,在进入while的判断语句判断表达式是否为真,所以说循环至少执行一次。
就像本例中,i的初始为10不满足while的判断条件,如果是在while循环或者for循环中,循环次数肯定为0,但由于do…while语句先执行循环体,所以循环还是执行了一次后才结束的
所以运行结果是只打印了一个10
运行结果:
在这里插入图片描述

(4)do while循环中的break和continue

代码1:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (i == 5)
			break;
		printf("%d ", i);
		i++;
	}
	while (i<=10);
	return 0;
}

分析:i先从1加到4,成功的打印出1-4,4打印完后,i加一变成5,break语句执行直接跳出循环,所以运行结果是打印数字1-4
运行结果:
在这里插入图片描述
代码2:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (i == 5)
			continue;
		printf("%d ", i);
		i++;
	} while (i <= 10);
	return 0;
}

分析:i从1执行到4,依旧没有什么变化,成功在屏幕上打印出1-4
当i=5时,continue语句触发,continue下面的语句(continue后大括号前)将不再执行,然后再次进入while语句里判断5,重复刚才的操作,陷入死循环。
所以程序的运行结果是打印1-4,然后陷入死循环。
运行结果:
在这里插入图片描述

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页