【C语言】2.分支和循环

1. 分支和循环

C语言是一门结构化的程序设计语言

  1. 顺序结构
  2. 选择结构
  3. 循环结构

1.1 什么是语句?

C语言中由一个分号 ; 隔开的就是一条语句。

在这里插入图片描述

2. if语句 - 分支语句(选择结构)

语法结构:
	if (表达式)
		语句;
	if (表达式)
		语句1;
	else
		语句2;
多分支    
	if (表达式1)
		语句1;
	else if (表达式2)
		语句2;
	else
		语句3;

2.1 代码1

#include <stdio.h>

int main()
{
    int age = 0;
    scanf_s("%d", &age);
    if (age < 18)
    {
        printf("未成年\n");
    }
}

2.2 代码2

#include <stdio.h>
int main()
{
    int age = 0;
    scanf("%d", &age);
    if (age < 18)
    {
        printf("未成年\n");
    }
    else
    {
        printf("成年\n");
    }
}

2.3 代码3

#include <stdio.h>
int main()
{
    int age = 0;
    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");
    }

}

注:

  • 如果表达式的结果为真,则语句执行。
    • 在C语言中如何表示真假?
      • 0表示假,非0表示真。
    • 要执行多条语句,要用一对 { } 括起来,{ }就是一个代码块。
    • if…else语句控制多条语句时要用{ }的代码块

2.4 悬空else

2.4.1 错误代码

/**	悬空else
* 
* 错误代码
* 代码什么也没有显示,代码没错,只是else是属于第二个if语句的,
* 因为第一个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;
}

2.4.2 改正

/** 悬空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;
}

2.4.3 运算符不正确

#include <stdio.h>

int main()
{
	int num = 4;
	if (5 == num)
	{
		printf("hehe\n");
	}
	//if (num = 5)
	//{
	//	//= 赋值  == 判断相等
	//	printf("hehe\n");//运算符不正确 : 在 Boolean 上下文中执行了常量赋值。应考虑改用“ == ”

	//}

	return 0;
}

3. 循环语句

c语言循环语句
    while循环
    do..while循环
    for循环
循环语句三要素:
    1.循环变量的初始化;
    2.循环条件;
	3.循环变量的更新语句

4.switch语句

在switch语句中的 break

switch语句是一种分支语句。常常用于多分支的情况。
在switch语句中,我们没法直接实现分支,搭配break使用才能实现真正的分支。

4.1 语法形式

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

语句项:
case 整型常量表达式
	语句;

4.2 例子:

//	输入1,输出星期一
//	输入2,输出星期二
//	输入3,输出星期三
//	输入4,输出星期四
//	输入5,输出星期五
//	输入6,输出星期六
//	输入7,输出星期七

//switch (整型表达式)
//{
//	语句项;
//}
//
//语句项:
//case 整型常量表达式
//	语句;


#include <stdio.h>
int main()
{
    int day = 3;
    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;
    default :
        printf("输入错误");
        break;
    }
    return 0;
}

4.2.1 default子句

如果表达的值与所有的case标签的值都不匹配怎么办?

  • 其实也没什么,结构就是所有的语句都被跳过而已。

  • 程序并不会终止,也不会报错,因为这种情况在C中并不认为适合错误。

但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?

  • 你可以在语句列表中增加一条default子句

default: 可以写在任何一个case标签可以出现的位置。

  • 当 switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。

所以,每个switch语句中只能出现一条default子句。

  • 但是它可以出现在语句列表的任何位置,而且语句流会像贯穿一个case标签一样贯穿default子句。

编程习惯:

  • 在每个switch语句中都放一条default子句是个好习惯,甚至可以在后边再加一个break 。(之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break语句)。

4.2.2 练习

//练习
#include <stdio.h>

int main()
{
    int n = 1,m = 2;//开始:n =1,m =2
    switch (n)//因为 n=1 所以执行case 1
    {
    case 1:
        m++;
    case 2:
        n++;
    /*
        因为case 1没有加break,执行完case 1继续执行case 2
        所以m++ ==> 3 n++ ==>2
    */
    case 3://因为case 2也没有加break,继续执行
        switch (n)
        {//switch允许嵌套使用
        case 1:
            n++;
        case 2:
            m++;
            n++;
            break;
        }
        /*
            继续执行switch语句
            因为n = 2,所以执行case 2语句项m++ ==> 4 n++==>3
            break退出
            又因为case 3没有加break,继续执行case 4
        */
    case 4://执行case 4m++==> 5 遇到 break 退出
        m++;
        break;
    default:
        break;
    }
    printf("m = %d, n = %d\n", m, n);//打印m= 5, n = 3
    return 0;
}

代码步骤图解

在这里插入图片描述


5. while语句

5.1 while 语法结构

while (表达式)
	循环语句;
当条件满足的情况下,if语句后的语句执行,否则不执行。但是这个语句只会执行一次。
而且生活中很多的实际的例子是∶同一件事情我们需要完成很多次。
C语言中引入了 : while语句,可以实现循环。

在这里插入图片描述

5.2 Eg:在屏幕上打印1-10的数字

#include <stdio.h>

int main()
{
	int i = 1;
	while (i <= 10)
	{
		printf("%d ", i);
		i = i + 1;
	}

	return 0;
}

5.3 while语句中的break和continue

5.3.1 break介绍

/*	while语句中的break
* 
* 总结: 
*	break在while循环中的作用:
*	其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。 
*	所以:while中的break是用于永久终止循环的。
*/
#include <stdio.h>

int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (i == 5)//当i为5的时候终止循环
			break;
		printf("%d ", i);//1 2 3 4
		i = i + 1;
	}

	return 0;
}

5.3.2 continue介绍

/*while语句中的continue
* 
* 总结: 
*	continue在while循环中的作用就是:
*		continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,
*		而是直接跳转到while语句的判断部分。
*		进行下一次循环的入口判断。
*/




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

//改正
#include <stdio.h>

int main()
{
	int i = 0;
	while (i < 10)
	{
		i = i + 1;
		if (i == 5)//判断为5成立,跳出该次循环
			continue;
		printf("%d ", i);
	}
	return 0;
}

6. while 练习题

//介绍getchar()
//getchar()函数的功能是一个一个地读取你所输入的字符
#include <stdio.h>

int main()
{
	int ch = getchar();

	putchar(ch);//接受一个字符并打印输出
	printf("%c\n", ch);//将ch的字符打印输出

	return 0;
}

6.1 下面代码什么意思?

6.1.1 代码1

#include <stdio.h>

int main()
{
	int ch = 0;

	//ctrl + z  ==> EOF
	//EOF - end of file -> -1
	while ((ch = getchar()) != EOF)
	{
		putchar(ch);
	}
	
	//输入EOF还是不行,ctrl+z才可以停止循环,因为OF被放在缓冲区
	
	/*
        getchar输入字符,每次读取一个字符其他放入缓冲区
        
        OF放入缓冲区,留下E,E被putchar接收
        
        putchar接收到E <-- EOF --> OF放入缓冲区

	*/

	return 0;
}


//-----------------------出现问题-----------------------------------

//输入EOF还是不行,ctrl+z才可以停止循环,因为OF被放在缓冲区

//查看系统的EOF其实是 -1

//-----------------------出现问题-----------------------------------
输入EOF还是不行,ctrl+z才可以停止循环,因为OF被放在缓冲区

在这里插入图片描述

查看系统的EOF其实是 -1

在这里插入图片描述

6.1.2 getchar()的使用

//确认密码
#include <stdio.h>

int main()
{
	int ret = 0, ch = 0;
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);//输入密码,并存放在passsword数组中

	printf("请确认(Y/N):>");
	ret = getchar();//输入一个Y/N字符
	if (ret == 'Y')//判断是否输入的事“Y”
	{
		printf("确认成功\n");//如果输入“Y”字符则输出确认成功
	}
	else
	{
		printf("放弃确认\n");//否则输出确认成功
	}

	return 0;
}

//-----------------------出现问题-----------------------------------

//出现错误:运行程序,输入密码,确定后,没有下一步操作就直接放弃确认

/* - 分析步骤
	步骤1:经过输入函数,输入密码:1234
	步骤2:输入的密码放入缓冲区
	步骤3:因为输入1234的时候还有一个“\n”结束符,1234放入数组,但是“\n”还放在输入缓冲区,所以getchar()接受的是“\n”
	步骤4:getchar接收的“\n”赋值给ret
	步骤5:if语句判断ret的内容不为“Y",所以执行elsei语句操作

*/

//程序没有下一步操作就直接放弃确认

//-----------------------出现问题-----------------------------------

在这里插入图片描述

在这里插入图片描述

解决方法:缓冲区还有一个“\n”,可以再用getchar()读取一下“\n”
但是若输入的时候有空格,空格也是会停止输入数组
空格后面若很多字符,可以设置一个while循环把字符读取掉
//修改代码--确认密码
#include <stdio.h>

int main()
{
	int ret = 0, ch = 0;
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);//输入密码,并存放在passsword数组中

	//修改
	//缓冲区还有一个“\n”,可以再用getchar()读取一下“\n”
	//但是若输入的时候有空格,空格也是会停止输入数组
	//空格后面若很多字符,可以设置一个while循环读取字符掉
	while ((ch = getchar()) != '\n')
	{
		;//空语句,因为此处不需要有操作
	}


	printf("请确认(Y/N):>");
	ret = getchar();//输入一个Y/N字符
	if (ret == 'Y')//判断是否输入的事“Y”
	{
		printf("确认成功\n");//如果输入“Y”字符则输出确认成功
	}
	else
	{
		printf("放弃确认\n");//否则输出确认成功
	}

	return 0;
}

在这里插入图片描述

6.1.3 代码2

#include <stdio.h>
int main()
{
    int ch = 0;

    while ((ch = getchar()) != EOF)//遇到EOF停止循环
    {
        if (ch < '0' || ch > '9')//遇到不是数字的字符就跳出这次循环,回到while判断语句,继续循环
            continue;
        putchar(ch);//遇到数字字符就打印输出
    }
    return 0;
}

在这里插入图片描述

7. for循环

7.1 语法

在这里插入图片描述

7.1.1 用for循环打印1-10

//for循环

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

#include <stdio.h>

int main()
{
	int i = 0;
	//for(i=1/*初始化*/; i<=10/*判断部分*/; i++/*调整部分*/)
	for (i = 1; i <= 10; i++)
	{
		printf("%d ", i);
	}
	
	return 0;
}

7.2 for循环和while循环对比

//for循环
//可以发现在while循环中依然存在循环的三个必须条件,
//但是由于风格的问题使得三个部分很可能偏离较远,
//这样查找修改就不够集中和方便。
#include <stdio.h>

int main()
{
	int i = 0;
	int j = 0;//while初始化

	//初始化	判断	调整
	for (i = 1; i <= 10; i++)
	{
		printf("for:%d\n", i);
	}

	while (j < 10)//判断
	{
		printf("while:%d\n", j);
		j++;//调整
	}

	return 0;
}
//相同方法用while循环
#include <stdio.h>

int main()
{
	int i = 0;
	int j = 0;//while初始化

	//初始化	判断	调整
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			continue;
		printf("for:%d\n", i);
	}
	//因为循环到i=5的时候,if语句判断成立跳过循环,执行下一次循环

	//while (j < 10)//判断
	//{
	//	if (j == 5)
	//		continue;
	//	printf("while:%d\n", j);
	//	j++;//调整
	//}
	//因为j=5的时候判断跳过循环执行下一次循环,但是没有进行调整操作,还是等于5,继续就死循环

	return 0;
}

7.3 for语句的循环控制变量

7.3.1 建议1

//for语句的循环控制变量

//一些建议:
//1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
//2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。



//1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
//举例 - 错误代码 - 会出现死循环
//#include <stdio.h>
//
//int main()
//{
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		if (i = 5)
//			printf("haha\n");
//		printf("hehe\n");
//	}
//
//	return 0;
//}

在这里插入图片描述

7.3.2 建议2

//for语句的循环控制变量

//一些建议:
//1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
//2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。

//2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。
//举例
#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++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

7.4 一些for循环的变种

7.4.1 变种1

第一个例子
//一些for循环的变种
//变种1
/*
	1.for循环的初始化、调整、判断都可以省略
		但是∶
		for循环的额判断部分如果被省略,那判断条件就是:恒为正
	2.如果不是非常熟练,建议不要随便省略

*/
//以下代码出现死循环
//#include <stdio.h>
//
//int main()
//{
//	for (;;)
//	{
//		printf("hehe\n");
//	}
//
//	return 0;
//}
第二个例子
#include <stdio.h>

int main()
{
	int i = 0;
	int j = 0;

	//代码只打印10次 hehe ,因为j = 10(停止循环)回到第一个循环,
	//第一个循环进行判断成立,继续执行第二个循环
	//因为j在上一次循环已经等于10,并且第二个循环没有对j进行初始化
	//所以判断j = 10 不小于 10,判断不成立,循环不执行
	for (; i < 10; i++)
	{
		for (; j < 10; j++)
		{
			printf("hehe\n");//0 1 2 3 3 4 5 6 7 8 9 j = 10(停止循环)
		}
	}

	return 0;
}

7.4.2 变种2

//变种2
#include <stdio.h>

int main()
{
	int x, y;

	//第一次判断:x = 0,y = 0, x < 2 && y < 5判断成立,执行循环
	//第二次判断:x = 1,y = 1, x < 2 && y < 5判断成立,执行循环
	//第三次判断:x = 2,y = 2, x < 2 && y < 5判断不成立,不执行循环
	//因为&&:短路与,表示如果两个条件都成立则执行之后的逻辑
	//所以因为x=2,x<2的条件不成立,循环不执行
	for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
	{
		printf("hehe\n");
	}

	return 0;
}

7.5 面试题

请问下面代码循环要循环多少次?

//请问循环要循环多少次?
//循环0次,因为for循环的判断处事0赋值给k
//k恒为0,0为假,则循环条件不成立,循环0次
#include <stdio.h>

int main()
{
	int i = 0;
	int k = 0;
	for (i = 0, k = 0; k = 0; i++, k++)
		k++;

	return 0;
}

8. do…while语句

8.1 do语句的语法

在这里插入图片描述

//do..while循环

//	do语句的语法︰
//		do
//			循环语句; 
//		while (表达式);

#include <stdio.h> 

int main()
{
	int i =1;

	do
	{
		printf("%d ", i);
		i++;
	} while (i <= 10);

	return 0;
}

8.2 do…while的break和continue

8.2.1 break

//break
#include <stdio.h>

int main()
{
	int i = 0;
	do
	{
		if (i == 5)
			break;
		printf("%d ", i);//打印0 1 2 3 4
		i++;
	} while (i <= 10);

	return 0;
}

8.2.2 continue

//do..while循环的continue
//#include <stdio.h>
//
死循环
//int main()
//{
//	int i = 0;
//	do
//	{
//		if (i == 5)
//			continue;
//		printf("%d ", i);
//		i++;
//	} while (i <= 10);
//
//	return 0;
//}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值