C语言学习入门第二节————分支语句和循环语句

系列文章目录

C语言学习入门第一节——初识C语言
C语言学习入门第二节———分支语句和循环语句

分支语句和循环语句

 分支语句

if
switch

循环语句

while
for
do while

goto语句


一、语句的定义及分类

C语句可分为以下五类:

  1. 表达式语句
  2. 函数调用语句
  3. 控制语句

控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言由九种控制语句。

可分为以下三类:

1.条件判断语句也叫分支语句:if语句、switch语句;

2.循环执行语句:do while语句、while语句、for语句;

3.转向语句:break语句、goto语句、continue语句、return语句。

  1. 复合语句(一个大括号括起来的几条语句)
  2. 空语句(只有一个 ; 就是空语句)
//表达式
#include <stdio.h>
 
int main()
{	//一个大括号括起来的几条语句就是复合语句
 
	3 + 5; //这里的 3 + 5 就是表达式语句
 
	printf("hehe"); //这里的 printf() 就是函数调用语句
 
	; //只有一个 ; 就是空语句
 
	return 0;
}

二、分支语句(选择结构)

1.if语句:

语法结构:

单分支:

if (表达式)

{
语句;

}

双分支:

if (表达式)

{
语句1;

}

else

{
语句2; }

多分支:

if (表达式)

{
语句1;
}

else if (表达式2)
{
语句2;
}

else

{
语句3;
}

单分支:

#include <stdio.h>
 
int main()
{
	int age = 0;
	scanf("%d", &age);
	//单分支
	if (age < 18)
	{
		printf("未成年");
		//如果符合 表达式 ,则打印相应内容
		//如果不符合 表达式 , 什么都不打印
	}
 
	return 0;
}

在这里插入图片描述

双分支:

#include <stdio.h>
 
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("未成年");
	}
	else
	{
		//如果不符合 表达式 ,则执行else里的语句
		printf("已成年");
	}
 
	return 0;
}

在这里插入图片描述

多分支:

#include <stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{//<18 青少年
		printf("青少年\n");
	}
	else if (age >= 18 && age <=30)
	{//18~30 青年
		printf("青年\n");
	}
	else if (age >= 31 && age <= 50)
	{//31~50 中年
		printf("中年\n");
	}
	else if (age >= 51 && age <= 80)
	{//51~800 中老年
		printf("中老年\n");
	}
	else if (age >= 81 && age <= 100)
	{//81~100 老年
		printf("老年\n");
	}
	else
	{//100+ 寿星
		printf("寿星\n");
	}
 
	return 0;
}

在这里插入图片描述

容易出错的地方: * * *

1.写语句部分时,最好都加上{},即使用复合语句,不然不管if是否成立,第一条语句后面的语句都会执行。

#include <stdio.h>
int main()
{
	int age = 0;
 
	scanf( "%age", &age );
 
	if ( age > 18 )
		printf("已毕业");
		printf("上大学");
 
	return 0;
}

在这里插入图片描述
2.不加{}的话,else会和最近的if匹配,有时会判断不清else是属于哪个if语句的(else的匹配: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");//else是和它离的最近的if匹配的,所以结果什么也不打印
	return 0;
}

3.不同风格的写法会带来歧义

//补充3
#include <stdio.h>
 
int test1()
{
	//int n = 20;
	int n = 2;
	if ( n > 5 )
		return 1;
	return 2;
	printf("hehe\n");
}
 
int test2()
{
	//int n = 20;
	int n = 2;
	if (n > 5)
	{
		return 1;
	}
	else
	{
		return 2;
	}
 
}
 
int main()
{
	int m = test1();
	printf("%d\n", m);
 //test1与test2结果一致但test2更容易理解
	int n = test2();
	printf("%d\n", n);
	return 0;
}

在这里插入图片描述
3.if语句中的判断不要写成赋值。

#include <stdio.h>
int main()
{
	int n = 0;
		/*if (n == 5)
			printf("hehe\n");*/
		if (n = 5)
			printf("hehe\n");//无论n是否等于5,都会打印hehe
	return 0;
}
//解决少打一个=的方法,将常量放到左边

#include <stdio.h>
int main()
{
	int n = 5;
	if (5 == n)
	//if (5 = n)会报错
		printf("hehe\n");

	return 0;
}

在这里插入图片描述
在这里插入图片描述

2.switch语句:

witch语句也是一种分支语句,常常用于多分支的情况。
语法结构:

语法结构: switch (整型表达式)

{

case 整型常量表达式: // case相当于入口
语句;
break; // break相当于出口
case1 整型常量表达式: // case相当于入口
语句;
break; // break相当于出口
case2 整型常量表达式: // case相当于入口
语句;
break; // break相当于出口 } ```

//switch语句
#include <stdio.h>
 
int main()
{
	int day = 0;
	scanf("%d", &day);
 
	switch (day) // 得输入整型表达式
	{
	case 1: // case后写整形常量表达式
		printf("星期一\n"); //语句
		break; // 如果进入对应的case语句的话,退出switch语句,
			   // 否则之后的case语句也会被执行
	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;
}

在这里插入图片描述

//星期一 ~ 星期五打印"weekday",星期六 ~ 星期日打印”weekend“
#include <stdio.h>
 
int main()
{
	int day = 0;
	scanf("%d", &day);
 
	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;
}

在这里插入图片描述
编程好习惯: 在最后一个 case 语句的后面加上一条 break语句。 (之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break语句)。

default不用非得放在switch的最后,switch也允许嵌套使用,break只会跳出一层switch

三、循环语句 (循环结构)

1.while循环语句:

while - 语法结构:

while (表达式)

{

循环语句;

}

(循环语句执行完后,再判定表达式,若成立,再进入while循环)

#include <stdio.h> 
int main()
{
	int n = 0;
	//使用while循环打印 0~10
	while ( n <= 10 )
	{
		printf("%d ", n);
		n++;
	}
	return 0;
}

在这里插入图片描述

while语句中的break:

break在while循环中的作用: 其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。
所以:while中的break是用于永久终止循环的

//while循环
#include <stdio.h>
int main()
{
	int n = 0;
	//使用break终止while循环
	while (n <= 10)
	{
		if (n == 5)
		{
			break;//当n = 5时跳出循环,结束打印
		}
		printf("%d ", n);
		n++;
	}
	return 0;
}

while语句中的continue:

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

//while循环
#include <stdio.h>

int main()
{
	int n = 1;
	//使用continue跳过循环中continue后面的语句
	while (n <= 10)
	{
		if (n == 5)
		{
			continue;//当n = 5时,因为遇到continue跳过continue后面的语句
			//不再打印和++所以n永远为5,程序进入死循环
		}
		printf("%d ", n);
		n++;
	}
	return 0;
}

在这里插入图片描述

getchar()函数 和 putchar()函数:

#include <stdio.h>	   
int main()
{
	   
	int ch = getchar();// getchar()函数:接收一个字符
		// 如果接收失败的话,会返回EOF(即-1),
		// 所以,该函数的返回类型是 int,
		// 接收该函数返回值的变量也应该是int
		// 因为字符本质是ASCii码,所以也可以接收字符
	printf("%c\n", ch);
	putchar(ch);  // 跟getchar对应的还有putchar
	             // putchar()函数:打印字符,只能打印字符
	return 0;
}

在这里插入图片描述

利用while和getchar()函数来实现多组输入:

#include <stdio.h> 
int main()
{
	int ch = 0;
 
	// EOF - end of file - 文件结束标志
	// #define EOF    (-1)
	// 在函数读取失败的时候返回了 EOF
	// 之前介绍过利用 scanf函数 来实现多组输入 
	// scanf 函数读取成功,返回的是读取到的数据的个数
	// 读取失败返回 EOF
	// getchar 读取成功返回字符的ASCII码值
	// 读取失败返回EOF
	// 回车也会读取,先读输入的字符,在读回车
	// ctrl + Z - 会让 scanf 或者 getchar 返回 EOF
	while ( (ch = getchar()) != EOF )
	{
		putchar( ch );
	}
	return 0;
}

在这里插入图片描述

利用while和getchar清空缓冲区:

#include <stdio.h>
int main()
{
	//123456
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password); // 数组本身就是地址,所以这里不用加&(取地址符)重点!!
	printf("请确认密码(Y/N):");
	char input = 0;
	//getchar(); // 把键盘输入的 \n(回车) 取走 ,如果不清除缓冲区就会直接打印确认失败。
	//清理掉缓冲区中剩余的数据
	while (getchar() != '\n')//循环直到取走\n(回车)为止
	{
		;
	}
	scanf("%c", &input); // 因为input是变量,所以要加&(取地址符)
	if ('Y' == input)
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}

	return 0;
}

在这里插入图片描述

2.for循环语句

for循环语句格式:

for (表达式1; 表达式2; 表达式3)

{

循环语句;

}

表达式1:初始化部分,用于初始化循环变量的。

表达式2:条件判断部分,用于判断循环是否终止。

表达式3:调整部分,用于循环条件的调整。

#include <stdio.h>
 
int main()
{
	int i = 0;
	//表达式1的变量最好在for循环外部声明
	//在表达式1中声明可能会出问题,C++可以这么用(C99)
	for ( i = 0; i <= 10; i++)
	//	表达式1	 表达式2  表达式3
	{
		printf("%d ", i);
		//表达式4(循环语句)
		//程序执行顺序1->2->4->3,然后2->4->3循环
	}
	return 0;
}

在这里插入图片描述

for语句中的break:

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
		{
			break;//当i = 5时,break跳出循环。整个for循环结束
		}
		printf("%d ", i);
	} 
	return 0;
}

在这里插入图片描述

for语句中的continue:

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

在这里插入图片描述

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

建议:

  1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
  2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。
(1).不要在for循环体内修改循环变量,防止for循环失去控制:
#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 0; i <= 10; i++)
	{
		i = 4;//i永远为4,死循环打印4
		if (i == 5)
		{
			continue;
		}
		printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述

(2).建议for语句的循环控制变量的取值采用“前闭后开区间”写法:
#include <stdio.h>
 
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//下标:        0 1 2 3 4 5 6 7 8 9
 
	int i = 0; //[0 , 10)
	for ( i = 0; i < 10 ; i++)
// 这里 i = 0 是 闭区间,i < 10 是 开区间,即“前闭后开区间”写法,[0 , 10).
// 可以清楚地看到 循环次数是 10次
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在这里插入图片描述

一些for循环的变种:

1.for循环中的初始化部分(表达式1),判断部分(表达式2),调整部分(表达式3)是可以省略的,但是不建议初学时省略,容易导致问题.
2.省略掉初始化部分。
3.使用多于一个变量控制循环:

(1).省略for循环中的初始化部分(表达式1),判断部分(表达式2),调整部分(表达式3):
#include <stdio.h>
int main()
{
	//初始化和调整部分的省略就是啥都不做
	//判断部分省略了,意味着判断是恒为真的
  //建议不要随便省略
	for (;;)
	{
		printf("hehe\n");//死循环打印hehe
	}
	return 0;
}

在这里插入图片描述

(2).省略掉初始化部分:
#include <stdio.h>
int main()
{
	int i = 0;
	int j = 0;
	
	for ( ; i < 4; i++)//两个循环初始都省略
	{
		for ( ; j < 4; j++)//循环四次后,j 此时等于4,j < 4 不成立,跳出循环
		{
			printf("hehe\n");
		}
	}
 
	return 0;
}

在这里插入图片描述

(3).使用多于一个变量控制循环:
#include <stdio.h>
int main()
{
	int x, y;
	for ( x = 0, y = 0 ; x<2 && y<5 ; ++x, y++ )
	{
		printf("hehe\n");
	}
	return 0;
}

在这里插入图片描述

3…do while循环语句

do while循环语句的语法:

do

{
循环语句;
}

while (表达式);

注:无论是否满足条件,先执行一次循环语句,循环语句至少被执行一次是do while的特点

//使用do while语句打印1~10
#include <stdio.h>
int main()
{
	int i = 1;
	do
	{
		printf("%d ", i);
		i++;
	} while ( i <= 10 ); 
	return 0;
}

四、go to语句

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

某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程
goto语句真正适合的场景如下:

for(...)
{
    for(...)
    {
        for(...)
        {
            if(disaster)
            {
                goto error;
            }
        }
    }
}
....
error:
    if (disaster)
    {
        //处理错误情况
    }

1.goto语句和标记跳转的标号

C语言中提供了可以随意滥用的goto语句和标记跳转的标号

#include <stdio.h>

int main()
{
again://(顶格写)
	printf("hehe\n");
	goto again; //跳转到again的地方去
	//随意跳转的goto语句
	//标记跳转的标号:again

	//死循环打印hehe

	return 0;
}

在这里插入图片描述

2.使用goto语句完成关机小程序:( * * *

//关机程序
//1. 程序运行起来后,1分钟内电脑关机
//2. 如果输入:1 就取消关机(可修改)

#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 类似java的import进入需要用的类

int main()
{
	char input[20] = { 0 }; // 接收“1”
	//程序倒计时关机
	system("shutdown -s -t 60"); // 用system函数调用系统的倒计时关机命令
again:
	printf("请注意,你的电脑在1分钟内关机,如果输入:1 就取消关机\n");
	scanf("%s", input); // 数组名本来就是地址,不用加&

	if (strcmp(input, "1") == 0) // strcmp这里需要<string.h>头文件
	{
		system("shutdown -a"); // 调用系统的取消关机命令
		// system这里需要<stdlib.h>头文件
	}
	else
	{
		goto again;
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述

从理论上goto语句是没有必要的,实践中没有goto语句也可以很容易地写出该代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 类似java的import进入需要用的类

int main()
{
	char input[20] = { 0 }; // 接收“1”
	//程序倒计时关机
	system("shutdown -s -t 60"); // 用system函数调用系统的倒计时关机命令
	while (1) // 条件非0,一直为真,死循环
	{
		printf("请注意,你的电脑在1分钟内关机,如果输入:1 就取消关机\n");
		scanf("%s", input); // 数组名本来就是地址,不用加&

		if (strcmp(input, "1") == 0) // strcmp这里需要<string.h>头文件
		{
			system("shutdown -a"); // 调用系统的取消关机命令
			// system这里需要<stdlib.h>头文件

			break;
		}
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值