从零开始C语言精讲篇2:分支与循环


前言

分支和循环不管是什么语言,都是必须掌握的重点内容,内容并不难懂,
大家认真学习一定会有所收获,有问题也随时欢迎读者来提问,与诸君共勉。


在这里插入图片描述

提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是语句

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

printf("hehe");
1+2;
;//空语句

二、分支语句

如果你好好学习,校招时拿一个好offer,走上人生巅峰。
如果你不学习,毕业等于失业,回家卖红薯。
这就是选择!

2.1if语句

2.1.1语法结构

if(表达式)
    语句;

if(表达式)
    语句1;
else
    语句2;

//多分支    
if(表达式1)
    语句1;
else if(表达式2)
    语句2;
else
    语句3;

举个例子:

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

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

//代码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");
   }
    
}

一些注意点:
if语句是可以默认控制下面一条语句的,也就是说,如果你的if里面只有一条语句,你也可以不用写{ }

int main()
{
	int age = 20;
	if (age > 18)
		printf("你已成年");
	return 0;
}

这样写,也是可以打印“你已成年”。
在这里插入图片描述
但是如果你想要if语句控制两条以上的语句,就必须加括号,否则就会报错,如下图
在这里插入图片描述
当我删掉if下第二个printf,报错就会消失了(if默认控制一条语句)
在这里插入图片描述

综上,如果你想if控制多条语句,加个大括号{ },笔者本人也很少遇到不加大括号的时候。反正加了不会有错,不加可能有错。建议大家写if别偷那个懒,加个大括号,逻辑也更清晰易懂。

2.1.2悬空else

大家来看下面这段代码,大家觉得会打印“hehe” 还是“haha”,又或者什么都不打印

#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匹配,也就是说,上面的代码结构应该是这样的:

#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;
}

因为a=0,所以a!=1,第一个if都进不去,更不要提后面的if和else了。
我们前面的代码是故意把else的位置挪前面,造成一个假象,好像else是与if(a==1)匹配,其实不是

这也是代码风格的问题,有的同学写代码就像下面,全部挪到一起,你能看清楚那个else对应哪个if?
你要是保持这种风格的代码,我保证你将来进公司,你同事不会打死你

#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.1.3相关练习

  1. 判断一个数是否为奇数
  2. 输出1-100之间的奇数
//判断一个数是否为奇数
int main()
{
	int a = 0;
	scanf("%d", &a);
	if (a % 2 == 1) {
		printf("%d是奇数", a);
	}
	else 
	{
		printf("%d不是奇数", a);
	}
	return 0;
}

在这里插入图片描述

//输出1-100之间的奇数
int main()
{
	int i = 0;
	while (i < 100)
	{
	    if (i % 2 == 1) {
		   printf("%d是奇数\n", i);
	    }
		i++;
	}
	return 0;
}

在这里插入图片描述
法二:

//输出1-100之间的奇数
int main()
{
	int i = 1;
	while (i < 100)
	{
		printf("%d是奇数\n", i);
		i+=2;
	}
	return 0;
}

在这里插入图片描述

2.2switch语句

switch语句也是一种分支语句。 常常用于多分支的情况。
比如:
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期七
那我没写成 if…else if …else if 的形式太复杂,那我们就得有不一样的语法形式。
这就是switch 语句。

2.2.1语法结构

switch(整型表达式)//switch后面的必须是整形表达式,你放个其他类型来就会报错
{
    case 整形常量表达式:
    //case后面也必须是整形常量表达式,你可以放1,2,3这种,也可以放1+2这种
    //你放1.0这种就会报错
    语句;
    case 整形常量表达式:
    语句;
    case 整形常量表达式:
    语句;
    ...
}

举个例子:

int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	   case 1:
		   printf("星期一\n");
	   case 2:
		   printf("星期二\n");
	   case 3:
		   printf("星期三\n");
	   case 4:
		   printf("星期四\n");
	   case 5:
		   printf("星期五\n");
	   case 6:
		   printf("星期六\n");
	   case 7:
		   printf("星期日\n");
	}
	return 0;
}

如果我们这里输入一个3,是不是就打印一个“星期三”呢?
在这里插入图片描述
事实上,是从星期三开始,一直打印到星期日结束。
为什么呢?switch中,如果没有自己加一个跳出的代码(出口),
你给一个值(入口),它会从那个值(入口),一直往后执行,直到结束。

那么我怎么样才能输入一个值,只执行那一个值的case呢?
很简单,在每个case中加入一个break(跳出)

int main()
{
	int day = 0;
	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;
}

在这里插入图片描述
可以看到,加入break后,就可以只执行一个case而不是一直往下了。
如果我们这里改一下需求,我们要求

  1. 输入1-5输出的是“weekday”;
  2. 输入6-7输出“weekend”

除了把每个case都改一遍的方法,
我们还可以利用switch没有break就会一直往下走的性质,进行代码简化,代码如下:

#include <stdio.h>
//switch代码演示
int main()
{
    int day = 0;
    scanf("%d", &day);
    switch(day)
   {
        case 1case 2:
        case 3:
        case 4:
        case 5:
            printf("weekday\n");
            break;
        case 6:
        case 7:
            printf("weekend\n");
            break;
   }
    return 0;
}

但是问题又来了,我这里只列举了1-7七种情况,万一有杠精,非要输入一个8、一个9…怎么办?
我们先来看一下不修改代码的情况下会发生什么:

在这里插入图片描述
如上图,是什么也不会打印(switch走了一圈发现没有对应值,就跳出来了)

如果我们想应对这种乱输入,或者输入错误的情况,我们可以在switch里面加一个default

int main()
{
	int day = 0;
	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;
	   default:
		   printf("输入错误,请重新输入");
	}
	return 0;
}

在这里插入图片描述
ps:习惯上是把default放在所有case后,如果你想,也可以放在case的前面,如下:

int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	   default:
		   printf("输入错误,请重新输入");
	   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;
}

switch中,默认都是先扫描一遍case,如果没有case才执行default
那我们这个代码就是单纯的打印“输入错误,请重新输入”吗?其实不是
在这里插入图片描述
可以看到,我们这里多打印了一个“星期一”,因为default进去后是没有break的,然后switch又往下走,打印了星期一之后,遇到break才跳出去。如果你想这样写,请你在default后面加一个break

ps:笔者一般都是把default写最后,也不用加什么break了,但是总是有杠精喜欢标新立异把default写前面。建议读者不要这样写,如果你忘记加break,就容易出错。

2.2.2相关练习

请大家计算一下,下面代码中最后打印的n和m的值

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
解释如下:
在这里插入图片描述

三、循环语句

3.1while循环

3.1.1语法结构

我们已经掌握了,if语句:

if(条件)
     语句;

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

//while 语法结构
while(表达式)
 循环语句;

在这里插入图片描述
大家不要背这个流程图啊,这个只是帮助你理解的,我简单给大家总结一下while循环
如果满足while循环的条件,进入循环,执行语句。
执行完语句后,再次判断while循环的条件,如果还满足,继续进行循环执行语句

当有一次不满足while循环的条件,跳出while循环(也可以你自己在while循环内部手动加break条件)

举个例子:在屏幕上打印1-10的数字。

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

在这里插入图片描述

3.1.2break

int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (i == 5) {
			break;
		}
		printf("%d", i);
		i++;
	}
	return 0;
}

在这里插入图片描述
我们的打印结果为1234,因为i==5时,就break了,
而break不是跳出if,而是跳出整个循环,所以也就没有机会打印5和5以后的数了。

注:如果是多层循环嵌套,break跳出的是包含它的那个循环(只跳一个)

3.1.3continue

我们把上面代码中的break换成continue会发生什么

#include<stdio.h>
int main()
{
	int i = 1;
	while (i < 10)
	{
		if (i == 5)
		{
			continue;//continue用于跳过本次循环continue后的代码
		}
		printf("%d", i);
		i++;
	}
	return 0;
}

在这里插入图片描述
为什么会这样?
解释如下:
continue用于跳过本次循环continue后的代码
也就是说,在i=5的时候,printf(“%d”, i);和i++;都被跳过了,

这就会导致,i并没有从5变成6,进行下一次循环的时候,i又是5,然后continue又跳过printf(“%d”, i);和i++,i仍然是5,然后再次进入循环…这就变成死循环了

3.2for循环

for循环也是笔者用的最多的,也是我们经常考察的

3.2.1语法结构

我们已经知道了while循环,但是我们为什么还要一个for循环呢? 首先来看看for循环的语法:

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

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

在这里插入图片描述
举个例子:使用for循环 在屏幕上打印1-10的数字。

#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;
}

在这里插入图片描述

3.2.2break和continue

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5) {
			break;//用于终止整个循环
		}
		printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述
for循环的break和while的没啥区别,都是遇到break就跳出整个循环

但是for循环的continue是和while循环有区别的

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

在这里插入图片描述
我们的for循环每一次循环都是必定执行i++的,虽然说你continue跳过了continue后面的printf部分,但是i++还是会执行的,所以这里不会变成死循环。

关于for循环的一些建议:

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

3.2.3for循环变种

int main()
{
	int i = 0;

	for (;;) {//这是一个死循环
		printf("hh");
	}
	//for循环的初始化,判断,调整都是可以省略的
	//判断部分如果省略,意味着判断条件恒为真,就会导致死循环
	return 0;
}

在这里插入图片描述
for循环的初始化,判断,调整都是可以省略的
判断部分如果省略,意味着判断条件恒为真,就会导致死循环

我们试题中可能会遇到这种题目,但是日常,非常非常非常不建议大家这样写!
我们就老老实实把“初始化”、“条件判断”、“调整”部分写上,出错率会大大降低,
不要为了装杯而装杯,你省略for循环的一些东西,出错了别来找我

然后,for循环也是可以嵌套使用的

int main()
{
	int i = 0;
	int j = 0;
	for (i = 0;i < 10;i++)
	{
		for (j = 0;j < 10;j++)
		{
			printf("hh\n");
		}
	}
	return 0;
}

上面这个代码一共会循环100次,一个10个i,每个i对应10个j,然后一共10*10=100次

如果我们省略掉初始化,一共只会打印10次hh

int main()
{
	int i = 0;
	int j = 0;
	for ( ;i < 10;i++)
	{
		for ( ;j < 10;j++)
		{
			printf("hh\n");
		}
	}
	return 0;
}

在这里插入图片描述
为什么呢?解释如下图:
在这里插入图片描述

3.2.4笔试题实战

//请问循环要循环多少次?
#include <stdio.h>
int main()
{
 int i = 0;
 int k = 0;
 for(i =0,k=0; k=0; i++,k++)
        k++;
 return 0;
}

这个题目只能说迷惑性很强,但是经常写代码的同学基本上一眼就看出来了
我们的for循环的判断条件是k=0,而不是k==0
我们把k=0(赋值),这个判断条件永远都是假,for循环根本进不去啊

所以是循环0次

3.3do…while循环

do while循环是三种循环里用的较少的,但是相关知识点还是要掌握的

3.3.1语法结构

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

在这里插入图片描述

3.3.2使用特点

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

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

在这里插入图片描述

3.3.break和continue

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

在这里插入图片描述
break依旧是没啥问题,和前面两个循环都差不多,一样是跳出整个循环

然而continue又出问题辣

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

在这里插入图片描述
可以看到,又陷入了死循环。我们来解释一下原因:
这个和while进入死循环差不多,i==5的时候,我们continue跳过了下面的i++,导致i仍然是5,然后重新进入循环,i又是等于5,又跳过下面i++,导致i仍然是5。。。这就死循环了

四、课后练习题

4.1求n!

int main()
{
	int i = 0;
	int n = 0;
	scanf("%d", &n);
	int tmp = 1;
	for (i = 1;i <= n;i++)
	{
		tmp *= i;
	}
	printf("%d", tmp);
	return 0;
}

示例如下:
在这里插入图片描述
在这里插入图片描述

4.2求1!+2!+3!+……+10!

我们4.1已经知道如何求n!了,那么我们把求n!做成一个函数,然后累加即可

int jc(int n)
{
	int i = 1;
	int tmp = 1;
	for (i = 1;i <= n;i++)
	{
		tmp *= i;
	}
	return tmp;
}
int main()
{
	int i = 1;
	int sum = 0;
	for (i = 1;i <= 10;i++)
	{
		sum += jc(i);
	}
	printf("%d", sum);
	return 0;
}

在这里插入图片描述

注:更简洁高级的写法

int main()
{
	int tmp = 1;
	int sum = 0;
	for (int n = 1;n <= 10;n++) {
		tmp *= n;
		sum += tmp;
	}
	printf("%d", sum);
	return 0;
}

4.3模拟用户登录

编写代码实现,模拟用户登录情形,并且只能登录三次,只允许输入3次密码。如果密码正确则提示登录成功,如果三次均输入错误,退出程序。

int main()
{
	//假设真实的密码是“123456”
	char password[20] = { 0 };
	int i = 0;
	for ( i = 0;i < 3;i++) {
		printf("请输入密码:>");
		scanf("%s", password);
		if (strcmp(password, "123456") == 0)//2个字符串比较不能使用==,而是使用strcmp
		{//如果比较下来是相等的,strcmp返回0
			printf("登录成功");
			break;
		}
		else {
			printf("输入错误\n");
		}
	}
	if (i == 3) 
	{
		//i==3说明是三次全输错了
		printf("三次密码错误,程序已退出");
	}
	return 0;
}

在这里插入图片描述


总结

我们今天学习了C语言的三种循环,其中语法规则是必须掌握的,第二个就是continue的陷阱还有变种for循环到底是怎么回事,熟练掌握这些,相信你在将来的写代码或者笔试题都会做的更好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

劲夫学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值