分支和循环语句(上)

什么是语句?

C语言是“结构话”的程序设计语言有顺序结构,选择结构和循环结构
这三种结构由语句来实现,顺序结构不需要特殊的语句,循环与分支需要用C语言提供的语句实现,那么什么是语句呢?
C语句可分为以下五类:

  1. 表达式语句
  2. 函数调用语句
  3. 控制语句
  4. 复合语句
  5. 空语句
    后面介绍的是控制语句。
    控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定语句定义符组成,C语言有九种控制语句。

控制可分成以下三类:

  1. 条件判断语句也叫分支语句:if语句、switch语句;
  2. 循环执行语句:do while语句、while语句、for语句;
  3. 转向语句:break语句、goto语句、continue语句、return语句

分支语句

在生活中处处遇到分支的情况,例如不同年龄是属于什么年龄段是青年中年还是老年?你遇到人生抉择时应该怎么选择择,分支语句也叫选择语句是专门处理这些问题。

if 语句

if语句有三种结构:
1.单分支结构

  • if(表达式)
    语句;

2.双分支结构

  • if(表达式)
    语句;
    else
    语句;

3.多分支结构

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

if语句中表达式为真,则执行语句。为假则不执行语句
0表示假,非0表示真

以不同年龄判断属于哪个年龄段为例,

1.单分支语句

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

这个单分支语句中if内部只有1条语句,那么要是有两条语句会怎末样呢?
让我们来实现一个未满十八岁不能饮酒的代码,

#include<stdio.h>
int main()
{
	int year = 0;
	scanf("%d", &year);
	if (year < 18)
		printf("未成年\n");
	printf("不能饮酒\n");
	return 0;
}

上面的这串代码无论输入年龄是多大都会输出”不能饮酒“这种解决的方式就是用{}来括着你想要在分支底下输出的代码块

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

当年龄大于等于18岁时输出成年,小于18随时输出未成年

3.多分支语句

#include<stdio.h>
int main()
{
	int age = 0;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("青少年\n");
	}
	else if(age>=18&&age<28)
	{
		printf("青年\n");
	}
	else if (age >= 28 && age < 40)
	{
		printf("中年\n");
	}
	else if (age >= 40 && age < 60)
	{
		printf("壮年\n");
	}
	else
	{
		printf("老年");
	}
	return 0;
}

在多分支语句中判断表达式(age >= 28 && age < 40)但是不能用28<=age<=40
。拿80来举例子,28<=age正确为1,1<=40正确,那么会输出中年但实际是老年。

悬空else

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
		if (b == 2)
			printf("test1\n");
	else
		printf("test2\n");
	return 0;
}

上面的代码最终输出结果什么也没有,相信很多人最初看的时候会以为是test2,但是为啥什么也没输出呢?
else优先与其最近的if语句匹配,在上面的程序中else是和if(b==2)匹配的,a == 1是错误的,所以就不进入语句内部。

要想实现我们最初的想法的代码应加{}

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

适当的使用{}可以使代码的逻辑更加清楚。
代码风格很重要

良好的代码风格:

  1. 变量的命名(有意义,规范)
    int age;就要比int a;更易懂。
  2. 空格,空行,换行
    int a = 10;就要比int a = 10;看着更加美观。

在这里插入图片描述

上述代码中代码1和代码2的效果是一样的,但是代码2理解起来更加清楚。

在这里插入图片描述

代码4比代码3更好一些,因为num == 5;很容易写成num = 5;写错了编译器不会警告,很难发现这个错误,但是我们把常量放前面5=num;变量不能赋值给常量,所以报错后会很容易找到。

例题

  1. 判断一个数是否为奇数
  2. 输出1-100之间的奇数

1

#include<stdio.h>
int main()
{
	int num = 0;
	scanf("%d", &num);
	if (num % 2 == 1)
	{
		printf("是奇数\n");
	}
	else
	{
		printf("不是奇数\n");
	}
	return 0;
}
#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 100; i++)
	{
		if (i % 2 == 1)
		{
			printf("%d ", i);
		}
	}
	return 0;
}

switch

switch语句常用在多分支语句中,例如分别输入1~7对应输出星期一 ~ 星期日。像这样的用if else if就会很复杂。
switch(整型表达式)
{
语句项;
}

()内部必须是整形表达式,浮点型是不行的。其中语句项的形式为
case 整形常量表达式:
语句;
这里也要特别注意case后不能跟浮点数
switch语句中的break就是结束该分支。

输入1~7对应输出星期一 ~ 星期日

#include<stdio.h>
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;
}

那么改变要求
1~5输出weekdey,
6~7输出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("weekdey\n");
		break;
	case 6:
	case 7:printf("weekend\n");
		break;
	}
	return 0;
}

这样直观感受没有break的1~4,如果day = 1,会一直向下运行直到case 5有break结束分支。break语句 的实际效果是把语句列表划分为不同的分支部分。

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

default子句

以输出是工作日为例,要是输入的数据不再题目要求怎么办?
在switch分支语句中没有该数据会直接跳出该分支语句,程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。但是你不想直接跳出分支语句,要输出一个提示
default可以出现在任意一个case可以出现的位置。
它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
default子句最多只能有一个。

在每个 switch 语句中都放一条default子句是个好习惯,甚至可以在后边再加一个 break 。

#include<stdio.h>
int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:printf("weekdey\n");
		break;
	case 6:
	case 7:printf("weekend\n");
		break;
	default:printf("输入数据错误\n");
	}
	return 0;
}

例题

请问下面程序输出结果(switch允许嵌套使用)

#include <stdio.h>
int main()
{
    int n = 1;
    int m = 2;
    switch (n)
    {
    case 1:m++;
    case 2:n++;
    case 3:
        switch (n)
        {
        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

循环语句

由于我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。
那我们怎么做呢?C语言为我们提供了while for 和 do while

while循环

while语句的格式类似于if语句.
满足表达式就会执行,不满足就不会执行
while(表达式)
循环语句;
循环语句和if中的语句类似,代码一行可写{}也可不写,多行及以上必须由{}括起来形成代码块

用while打印1~10

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

while语句中的break和continue

test1.c

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

test2.c

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

test1.c输出结果:1 2 3 4
test2.c输出结果:1 2 3 4 后面就无限循环但不输出数字

while循环中的
break是用于永久的终止循环
continue 跳过本次循环后面的代码,直接去判断部分,进行下一次循环的判断

例题

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

getchar();接收缓冲区的字符,返回值为字符对应的ASCII码值,接收错误或文件结束返回EOF(end of file)对应数值为-1;文件结束快捷键ctrl+z;
电脑不是键盘输入直接读取,键盘输入的数据存放在输入缓冲区,getchar()接收是输入缓冲区内的数据。输入一个字母加回车getchar()也会把回车接收掉要想结束就得按ctrl+z;接下来看一下上面代码的应用。

清空输入缓冲区

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%d", &password);
	char ch = 0;
	printf("请确认密码:>");
	int ret = getchar();
	if ('Y' == ret)
	{
		printf("YES\n");
	}
	else
	{
		printf("NO\n");
	}
	return 0;
}

上述代码有问题,你输入密码后自动确认为否,因为getchar()接收输入缓冲区中输入密码scanf函数为接受的‘\n’,ret就不等于Y’,

改进:

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%d", &password);
	char ch = 0;
	while ((ch = getchar()) != '\n');
	printf("请确认密码:>");
	int ret = getchar();
	if ('Y' == ret)
	{
		printf("YES\n");
	}
	else
	{
		printf("NO\n");
	}
	return 0;
}

为啥要有一个循环呢?直接getchar()不像吗?
答案是在有的条件下不行,像一串数字中间空格后面又一串数字,例如:12345 678 这样密码接受后输入缓冲区还剩下 678’\n‘,所以用循环。

另一个小应用:

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

只打印数字字符,跳过其他字符

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值