0
点赞
收藏
分享

微信扫一扫

C语言初阶——分支和循环语句

前言:在上一篇文章里,我们对C语言大概念有了一个初步的了解。在接下来的《C语言初阶》系列的文章里我们将更近一步地走进C语言,看看我们到底能够搞出什么花样。就像学习驾驶机动车,我们已经知道了车是什么,它大概有哪些部件,以及一些必要的交通规则,接下来就让我们一起上车吧!

1.什么是语句?

在C语言中用一个分号 “ ”隔开的就是一条语句,比如:

printf("hehe");
1 + 2;

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

人生中处处充满了选择,高中分科时我们在选择,大学填报志愿时我们在选择,大三时该找工作还是考研我们在选择,拿到了offer该去哪个公司上班,我们还是在选择。现在的你还在选择吗?
在这里插入图片描述

2.1 if 语句

什么是if语句?它的语法结构是怎样的呢?
语法结构一:

语法结构二:

语法结构三:

下面我们通过几个实例,来看看if语句到底该怎么使用:

//代码1 —— 单分支
#include<stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("未成年\n");
	}
	return 0;
}
//代码2 —— 双分支
#include<stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("未成年\n");
	}
	else
	{
		printf("成年\n");
	}
	return 0;
}
//代码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");
	}
	return 0;
}

解释一下:如果表达式的结果为真,则语句执行。那在C语言中真假该如何表示呢?我们用0表示假,非0表示真。
根据语法,在表达式语句判断完之后我们只能执行一条语句,如果我们想要执行多条语句该怎么办呢?这里我们应该使用代码块,一对 { } 就是一个代码块,代码块里可以放多条语句。

#include<stdio.h>
int main()
{
	if (表达式1)
	{
		语句列表1}
	else
	{
		语句列表2}
	return 0;
}

2.1.1 悬空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;
}
改正:
//适当的使用{ }可以使代码逻辑更加清楚
//代码风格很重要
#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的匹配;else是和它离得最近的if匹配的

2.1.2 if 书写形式的对比

//代码1
if (condition) {
	return x;
}
return y;

//代码2
if (condition)
{
	return x;
}
else
{
	return y;
}

//代码3
int num = 1;
if (num == 5)
{
	printf("hehe\n");
}
//代码4
int num = 1;
if (5 == num)
{
	printf("hehe\n");
}
//显然代码2和代码4更好,逻辑更加清晰,不容易出错。

2.1.3 if循环小游戏
看到这里,if循环的语法想必大家已经了然于胸了,那就让我们一起看看下边这两个小题目。
1.判断一个数是否为奇数

#include<stdio.h>
int main()//我们输入一个整数,当这个数是奇数时,打印奇数,偶数时打印偶数
{
	int num = 0;
	printf("请输入:>");
	scanf("%d", &num);
	//printf("\n");
	if (1 == num % 2)
	{
		printf("奇数\n");
	}
	else
	{
		printf("偶数");
	}
	return 0;
}

在这里插入图片描述
你学会了吗?我们再看下一个题
2.输出1~100之间的奇数

#include<stdio.h>
int main()//输出1~100之间的奇数
{
	int num = 1;
	for (num = 1; num <= 100;num++)//先要产生1~100的数字
	{
		if (1 == num % 2)
		{
			printf("%d ", num);
		}
	}
	return 0;
}

在这里插入图片描述

2.2 switch 分支语句

switch语法非常直接,它尝尝用于多分支的情况,比如:
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期日
这就是switch语句,假若我们写成if分支语句,形式将会非常复杂
switch 语法:

switch (整型表达式)
{
	case 整型常量表达式:
		语句;//满足整型常量表达式即执行
}

switch就像一个开关,括号里面的整型表达式是多少,就从对应case后面的整型常量表达式后面的语句开始往下执行,那什么时候跳出来呢?还是说必须要执行到最后一个语句?这就需要我们利用 break 来加以控制。
2.2.1在switch语句中的break
在switch语句中,我们没法直接实现分支,搭配break才能实现真正的分支,比如:

#include<stdio.h>
int main()
{
	int day = 0;
	scanf("%d",&day);// 输入1到7之间的整数
	switch (day)//注意必须是整型表达式,不要忘记
	{
	case 1:
		printf("星期一\n");
		break;//遇到break就会跳出switch语句
	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、输入1~5之间的数字就打印“weekday”。
2、输入6或7就打印“weekend”。
这样我们的代码就应该这样实现了:

#include<stdio.h>
int main()
{
	int day = 0;
	scanf("%d",&day);// 输入1到7之间的整数
	switch (day)//注意必须是整型表达式,不要忘记
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday\n");
		break;
	case 6:
	case 7:
		printf("weekend\n");
		break;
	}
	return 0;
}

我们可以很清楚地感受到,break语句作为switch语句的出口,他的实际效果就是把语句列表划分为不同的部分。
在最后一个case语句的后面加上一条break语句是一个编程的好习惯。
2.2.2 default 子句
加入表达式的值与所有的case标签的值够不匹配怎么办?其实也没什么,结果就是所有的语句都被跳过而已,程序并不会终止,也不会报错。但是,如果我们并不想忽略不匹配所有标签的表达式的值时该怎么办?这里default 便可以派上用场。将default写在任何一个case标签可以出现的位置,当switch表达式的值不匹配所有case标签的值时,这个default子句后面的语句就会执行。所以每个switch语句中只能出现一条default子句。在每个switch语句中都放一条default语句是一个编程的好习惯,甚至可以在后面在加一个break。

3.循环语句

循环语句有三种类型:while循环、for循环和do while循环。
请添加图片描述
人生就是这样,日复一日的付出,终究会换来回报,只要你坚持下去。当然你必须要坚持下去,不能让人生变成一个死循环,你说呢?

3.1while 循环

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

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

while语句执行的流程:
请添加图片描述
我们可以实现在屏幕上打印1~10的数字:

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

3.1.1 while语句中的break和continue
我们已经了解了while语句的基本语法,下面我们再了解一下如何使用while语句中的break和continue
break介绍:

#include<stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (i == 5)
			break;
		printf("%d ", i);
		i = i + 1;
	}
	return 0;
}//代码输出的结果为1 2 3 4

总结:
break在循环中的作用:在循环中只要遇到break,就停止后期的所有循环,所以while中的break是用于永久停止循环的。
continue介绍

//代码1
#include<stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (i == 5)
			continue;
		printf("%d ", i);
		i = i + 1;
	}
	return 0;
}//代码输出的结果为1 2 3 4然而程序并没有要终止的意思,原因是进入了死循环
//代码2
#include<stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		i = i + 1;
		if (i == 5)
			continue;
		printf("%d ", i);
	}
	return 0;
}//代码输出的结果为2 3 4 5 6 7 8 9 10

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

//代码什么意思?
//代码1
#include<stdio.h>
int main()
{
	int ch = 0;
	while ((ch = getchar()) != EOF)//getchar():读取输入的字符
		putchar(ch);//putchar():输出读入的字符
	return 0;
}

3.2for循环

我们已经知道了while循环,接下来我们再认识一下for循环。
3.2.1for循环语法

实际应用:使用for循环在屏幕上打印1~10的数字

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

for循环的执行流程图:
请添加图片描述
现在我们对比一下for循环和while循环

int i = 0;//初始化部分
while (i <= 10)//判断部分
{
	printf("hehe\n");
	i = i + 1;//调整部分
}

//用for循环实现相同的功能
for (i = 1; i <= 10; i++)
{
	printf("hehe\n");
}//代码看上去更加的整洁

可以发现在while循环中依然存在for循环的三个必要条件,但是由于代码风格的问题使得三个部分可能偏离很远,这样查找和修改就不够直接和方便。所以for循环的风格更胜一筹,for循环的使用频率也是最高。
3.2.2for循环中的break和continue
break和continue在for循环中的意义和在while循环中是一样的,但是还是有些差异,仔细观察下面两端代码便可发现其中的差别:

代码1
#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			break;
		printf("%d ", i);
	}
	return 0;
}//打印结果为1 2 3 4
代码2
#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			continue;
		printf("%d ", i);
	}
	return 0;
}//打印结果为1 2 3 4 6 7 8 9 10

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

3.2.4 一些for循环的变种

#include<stdio.h>
int main()
{
	//变种1
	for (; ; )
	{
		printf("hehe\n");
	}//无限循环打印hehe
	//变种2
	int x, y;
	for (x = 0, y = 0; x < 2 && y < 5; x, y++)
	{
		printf("hehe\n");//打印两次hehe
	}
	return 0;
}

3.2.5一道笔试题
下面这段代码循环几次?

#include<stdio.h>
int main()
{
	int i = 0;
	int k = 0;
	for (i = 0, k = 0; k = 0; i++, k++)
		k++;
	return 0;
}//结果是执行0次

这个题看似简单,代码只有几行,但这时候我们往往要注意:问题往往隐藏在我们忽视的细节之中,仔细观察for循环中的判断语句:k = 0;这是一条赋值语句,计算机中0代表假,这就代表着判断条件永远为假,一次也循环。同理非0的数字就代表真,为了方便我们观察,我将代码改成下面的形式:

#include<stdio.h>
int main()
{
	int i = 0;
	int k = 0;
	for (i = 0, k = 0; k = 2; i++, k++)
		printf("hehe ");//死循环打印hehe
	return 0;
}//满屏的hehe你看到了吗?

3.3 do···while()循环

下面我们来介绍第三种循环:do···while()循环。它又有哪些不同寻常之处呢?
3.3.1 do···while语句的语法

3.3.2 执行流程
请添加图片描述
3.3.3do语句的特点
循环至少执行一次,使用的场景有限,所以不是经常使用。

#include<stdio.h>
int main()
{
	int i = 10;
	do
	{
		printf("%d\n", i);
	} while (i < 10);
	return 0;
}//程序只执行一次,打印10

3.3.4 do···while循环中的break和continue

#include<stdio.h>
int main()
{
	int i = 10;
	do
	{
		if (5 == i)
			break;//执行到这里就会跳出循环
		printf("%d\n", i);
	} while (i < 10);
 	//打印1 2 3 4 
	return 0;
}
#include<stdio.h>
int main()
{
	int i = 1;
	do
	{
		if (5 == i)
			continue;//程序会跳过后面的代码,从头开始执行
		printf("%d\n", i);
		i++;
	} while (i < 10);
	//打印1 2 3 4 然后程序进入死循环
	return 0;
}

3.4 循环小游戏

3.4.1折半查找:有一天我买了一双耐克,你好奇的问我多少钱,我说不超过500.你还是好奇,你想知道到底是多少,我就让你猜,每猜一次我都会给出相应的提示,告诉你猜大了还是猜小了,你会怎么猜?
答案;你每次猜中间数。
代码实现:

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;//数组下标是从零开始的
	int right = sizeof(arr) / sizeof(arr[0]) - 1;//数组最后一个元素的下标
	int key = 7;
	int mid = 0;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (arr[mid] > key)
		{
			right = mid - 1;
		}
		else if (arr[mid] < key)
		{
			left = mid + 1;
		}
		else
			break;
	}
	if (left <= right)
		printf("找到啦\n");
	else
		printf("找不到\n");
	return 0;
}

3.4.2 猜数字游戏
我让电脑随机生成一个一定范围内的数字,你来猜,每次猜完电脑都会给出相应的提示,你根据提示继续往下猜,直到猜中为止。
代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
	printf("********************************");
	printf("***********1 . play*************");
	printf("***********0 . exit*************");
	printf("********************************");
}
void game()
{
	int random_num = rand() % 100 + 1;//这样就可以产生0~100的数字
	int input = 0;
	while (1)
	{
		printf("请输入数字:>");
		scanf("%d", &input);
		if (input > random_num)
		{
			printf("猜大了\n");
		}
		else if (input < random_num)
		{
			printf("猜小了\n");
		}
		else
		{
			printf("恭喜你,猜对了!!!\n");
			break;
		}
	}
}
int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	//大家有兴趣可以了解一下时间戳的概念,这里我们通过时间戳来实现随机数的生成
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch(input)
		{ 
		case 1:
			game();
			break;
		case 0:
			break;
		default:
			printf("选择错误,请重新输入!\n");
			break;
		}
	} while (input);//只要input不是0,就不会跳出
	return 0;
}

4.goto 语句

C语言中提供了可以随意滥用的goto语句和标记跳转的标号,但从理论上来说goto语句是没有必要的,实践中没有goto语句也可以很容易地写出代码。但在某些场合下goto语句还是用的着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程,例如一次跳出两层或多层循环。这种情况使用break是达不到目的的,break一次只能跳出一层循环。
下面是使用goto语句的一个例子:一个关机程序

#include<stdio.h>
int main()
{
	char input[10] = { 0 };
	system("shutdown -s -t 60");
again:
	printf("电脑将在60s内关机,如果输入我是猪,就取消关机!\n请输入:>");
	scanf("%s", &input);
	if (0 == strcmp(input, "我是猪"))
	{
		system("shutdown -a");
	}
	else
	{
		goto again;
	}
	return 0;
}
//而如果不使用goto语句,则可以使用循环:
#include<stdio.h>
#include<stdlib.h>
int main()
{
	char input = { 0 };
	system(shutdown - s - t 60);
	while (1)
	{
		printf("电脑将在60s内关机,如果输入我是猪,就取消关机!\n请输入:>");
		scanf("%s", &input);
		if (0 == strcmp(input, "我是猪"))
		{
			system("shutdown -a");
			break;
		}
	}
	return 0;
}

而goto语句真正适用的场景如下:

好了,关于分支和循环的内容就写到这里,下一篇文章我们一起来学习一下函数的相关内容。

举报

相关推荐

0 条评论