C语言分支和循环语句


在这里插入图片描述

语句的分类

条件判断语句(分支语句)
if语句,switch语句

循环执行语句:
do-while语句,while语句,for语句

转向语句:
break语句,goto语句,continue语句,return语句

if语句

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int age = 10;
	scanf("%d", &age);
	if (age < 18)
	{
		printf("青少年\n");
	}
	else if (age >= 18 && age <= 28)
	{
		printf("青年\n");
	}
	else if (age > 28 && age <= 50)
	{
		printf("中年\n");
	}
	else
	{
		printf("老年\n");
	}
	return 0;
}

样例输入:45
输出:中年

注:
如果if内只有一个语句{}可以省略,多个语句则要加上{}

if语句条件判断的小细节

int a = 5;
//以下两种方法都可以
if (5 == a)
// 此方法便于提示,若不小心写成一个=,则会报错
if (a == 5)
// 此方法,若省略一个=,则不会报错

练习:
输出1~100之间的奇数:

第一种:

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int a = 0;
	while (a <= 100)
	{
		if (a % 2 == 1)
		{
			printf("%d\n", a);
		}
		a++;
	}
	return 0;
}

第二种:

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int a = 1;
	while (a <= 100)
	{
		printf("%d\n", a);
		a+=2;
	}
	return 0;
}

break语句

例题1:
按要求输出星期

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

例题2:
输入1~5, 输出weekday
输入6~7,输出weekend

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int day;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday");
		break;
	case 6:
	case 7:
		printf("weekend");
		break;
	default:
		printf("输入错误\n");
		break;
	}
	return 0;
}

循环语句

for

在这里插入图片描述
执行完循环体之后再去执行表达式3

若判断部分省略,意味着这个判断恒成立

嵌套理解:

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

i=0进入循环,j=0依次到j=10跳出内for循环,
然后i=1再次进入内for循环

省略的弊端:

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int i = 0, j = 0;
	for (; i < 3; i++)
	{
		for (; j < 3; j++) 
		 //没有初始化,j=3跳出循环后,再次进入循环,j=3不能进入循环了
		{
			printf("hh\n");
		}
	}
	return 0;
}

打印三次hh

试着判断以下代码循环几次【狗头】

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

答案是 0次,因为k=0不是判断,不进入循环

while

打印输出1~10

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

break用法

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

打印输出1~4,i==5时直接终止运行

continue用法

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (5 == i)
			continue; // 跳过此循环,进行下次循环
		printf("%d\n", i);
		i++;
	}
	return 0;
}

该代码进行死循环

若把i++提前

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

输出

2
3
4
6
7
8
9
10
11

getchar() putchar()

获取一个字符

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int ch = getchar();
	printf("%c\n", ch); // 第一种方法输出
	putchar(ch);   // 第二种方法输出
	return 0;
}

样例输入输出:

w
w
w

scanf读取的实质

scanf()不能读取空格

char password[20]={0};
scanf("%s",password);
printf("%s",password);

输入:sada aad
输出:sada

输入的时候按回车,在缓冲区内会有\n字符
在这里插入图片描述

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	char password[20] = { 0 };
	printf("请输入密码->");
	scanf("%s", password);
	printf("请确认密码Y\N->");
	int ret = getchar();
	if ('Y' == ret)
	{
		printf("Yes");
	}
	else
	{
		printf("No");
	}
	return 0;
}

在这里插入图片描述
直接输出No
原因

输入时,按回车,缓冲区内有asd\n,password只存储了asd,\n被getchar()获取,ret=\n,所以输出No

为了避免这种情况,同时避免scanf无法获取空格,可以再次利用getchar(),把其字符获取,消除
加上while(getchar())

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	char password[20] = { 0 };
	printf("请输入密码->");
	scanf("%s", password);
	int ch = 0;
	while (ch = getchar() != '\n')
	{
		;
	}
	printf("请确认密码Y\N->");
	int ret = getchar();
	if ('Y' == ret)
	{
		printf("Yes");
	}
	else
	{
		printf("No");
	}
	return 0;
}

只获取数字字符

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

在这里插入图片描述

do while

在这里插入图片描述
至少要循环一次哦,但使用场景有限,比较少用

例题解析:

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int i = 1;
	do
	{
		i++;
		if (5 == i)
		{
			break;
			//    跳出循环,下面不再执行
		}
		printf("%d", i);
	} 
	while (i <= 10);
	return 0;
}

打印 234

把break换成continue,会打印出什么结果呢?

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

打印1~11,没有5

例题

1 求1!+2!+…+10!

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

此方法用了两层for循环,效率不高,对此优化后为:

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

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

2 字符串逐渐输出

样例:
#########
w#######!
we#####x!
wes###ex!
wesx#aex!
wesxraex!
最后输出全部字符

注意的点

	int arr1[] = "abc";
	// “a,b,c,\0”  4个

*计算元素个数时的点 *

#include <stdio.h>

int main()
{
	int arr1[] = "abc";
	// “a,b,c,\0”  4个
	int c = strlen(arr1) - 1; // c下标
	//   strlen()计算的值为3 
	int c = sizeof(arr1) / sizeof(arr1[0]) - 2; // c下标
	//   这种方法算上了\0,这个元素
	return 0;
}

最终代码如下:

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
//  调用Sleep函数
int main()
{
	char arr1[] = "welcom to bit!!!";
	char arr2[] = "################";
	int left = 0;
	int right = sizeof(arr1) / sizeof(arr1[0]) - 2;
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		Sleep(1000);
		// 控制语句输出时间的函数,1000意为1000ms(1s)
		left++;
		right--;
	}

	return 0;
}

输出结果:

w##############!
we############!!
wel##########!!!
welc########t!!!
welco######it!!!
welcom####bit!!!
welcom ## bit!!!
welcom to bit!!!

若想让语句输出在一行(每次输出前清空语句)
使用system(“cls”)

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
int main()
{
	char arr1[] = "welcom to bit!!!";
	char arr2[] = "################";
	int left = 0;
	int right = sizeof(arr1) / sizeof(arr1[0]) - 2;
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		Sleep(1000);
		//清空屏幕
		system("cls");
		// system是个库函数,可以执行系统命令
		left++;
		right--;
	}
	return 0;
}

3 模拟用户登录(判断两个字符串是否相等,用strcmp函数)

题目:如果用户登录三次,还是错误则退出系统
strcmp函数返回值为0时,则两个字符串相等

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int i = 0;
	char password[] = { 0 };
	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:");
		scanf("%s", password);
		if (strcmp(password, "abcd") == 0)
		{
			printf("登录成功!\n");
			break;
		}
		else
		{
			printf("密码错误!!!\n");
		}
	}
	if (3 == i)
	{
		printf("退出程序\n");
	}
	return 0;
}

4 出生日期输入输出

题目:输入只有一行,例如:20020927
输出:
year = 2002
month = 09
date = 27

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int year = 0;
	int month = 0;
	int date = 0;
	scanf("%4d%2d%2d", &year, &month, &date);
	// %4d 四位字符为year
	printf("year = %d\n", year);
	printf("month = %02d\n", month);
	// %02d 输出有两位,未满两位的前面用0补齐
	printf("date = %02d\n", date);
	return 0;
}

5 猜数字游戏

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
//      初始化界面
{
	printf("***********************\n");
	printf("*******  1.play  ******\n");
	printf("*******  0.exit  ******\n");
	printf("***********************\n");
}

void game()
//  游戏操作
{
	int guess = 0;
	// 生成随机数 1~100
	int ret = rand() % 100 + 1;
	// rand() 范围:0~rand_max(32767)

	// 猜数字
	while (1)
	{
		printf("请猜数字:>\n");
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("猜对咯!!!\n");
			break;
		}
	}
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	// 使用time函数返回的时间戳,作为srand的起点
	do
	{
		menu();
		printf("请选择:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入有误!!!\n");
			break;
		}
	} while (input);
	//  input --- 
	return 0;
}

在这里插入图片描述

二分查找(折半查找)

条件:数值是有序的
举例,找出数组1~10,值为7的下标值

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;

	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid]> k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了,下标为%d", mid);
			break;
		}
	}
	if (left > right)
	{
		printf("找不到");
	}
	return 0;
}

goto语句

从理论上来说,goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码
但是某种场合goto语句还是用的着的,最常见的用法就是终止程序在某种深度嵌套的结构的处理过程;
例如:一次跳出两层或者多层循环
多层循环这种情况,break是无法达到目的的,它只能从最内层循环退出到上一层的循环
不能跨函数

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
again:
	printf("haha");
	goto again;
	// 死循环,跳到again
	return 0;
}

正确用法:

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	for (...)
	{
		for (...)
		{
			for (...)
			{
				goto diss;
				//  直接跳出多层循环
			}
		}
	}
diss:

	return 0;
}

搞怪,电脑关机

电脑将在60s内关机
若输入:我是猪
将取消关机

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
// system 函数
int main()
{
	char input[] = { 0 };
	system("shutdown -s -t -60");
again:

	printf("注意!!!电脑将在60s内关机,若输入:我是猪,则关机取消");
	scanf("%s", input);
	if (strcmp(input, "我是猪") == 0)
	{
		system("shutdown -a");
	}
	else
	{
		goto again;
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

汴京城下君

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

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

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

打赏作者

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

抵扣说明:

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

余额充值