C语言学习-002-分支和循环语句

目录

分支语句和循环语句 

什么是语句?

分支语句(选择结构)

if语句

悬空else

 练习

switch语句

循环语句

while循环

while语句执行的流程

while语句中的break

while语句中的continue

for循环

for循环的执行流程

 一道笔试题

do...while循环

do语句的语法

执行流程

do语句的特点

练习

1. 计算 n的阶乘

2. 计算 1!+2!+3!+……+10! 

3. 在一个有序数组中查找具体的某个数字n

4. 编写代码,演示多个字符从两端移动,向中间汇聚

5. 模拟用户登录情景

6.求两个数的最大公约数

7.打印1000-2000年之间的闰年

8.打印素数

9.分数求和

10.求最大值

11.在屏幕上输出乘法口诀表

猜数字游戏

goto语句


分支语句和循环语句 

分支语句

  • if
  • switch

循环语句

  • while
  • fot
  • do while 

 goto语句

什么是语句?

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

printf("Hello World!");

分支语句(选择结构)

如果你好好学习,高考后上个好大学

如果你不好好学习,去工地搬砖

这就是选择

if语句

if语句语法结构

#include<stdio.h>
int main()
{
	//语法结构
	if(表达式)
		语句;
	//if else
	if(表达式)
		语句1;
	else
		语句2;
	//多分支
	if(表达式1)
		语句1;
	else if(表达式2)
		语句2;
	else
		语句3;
	return 0;
}

代码示例:

//代码1
#include<stdio.h>
int main()
{
	int age = 0;
	printf("Please input your age:\n");
	scanf("%d", &age);
	if (age < 18)
	{
		printf("未成年!");
	}
	return 0;
}
//代码1
#include<stdio.h>
int main()
{
	int age = 0;
	printf("Please input your age:\n");
	scanf("%d", &age);
	if (age < 18)
	{
		printf("未成年!");
	}
	else
	{
		printf("已成年!");
	}
	return 0;
}
//代码3
#include<stdio.h>
int main()
{
	int age = 0;
	printf("Please input your age:\n");
	scanf("%d", &age);
	if (age < 18)
	{
		printf("未成年!");
	}
	else if (age >= 30 && age < 50)
	{
		printf("中年!");
	}
	else  if (age >= 50 && age < 80)
	{
		printf("老年!");
	}
	else
	{
		printf("太老咯!!!");
	}
	return 0;
}

悬空else

#include<stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
		if (b == 2)
			printf("b==2");
	//悬空else
	else
		printf("其它情况");
}

注意: else总是与最近的if配套

//改正悬空else
//适当的使用{}可以使代码的逻辑更加清楚
//代码风格很重要
#include<stdio.h>
int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
	{
		if (b == 2)
		{
			printf("b == 2");
		}
	}
	else
	{
		printf("其它情况");
	}
}

 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 更好,逻辑更加清晰,不容易出错

 练习

1.判断一个数是否为奇数

2.输出1-100之间的奇数

//1.判断一个数是否为奇数
#include<stdio.h>
int main()
{
	int input = 0;
	printf("Please enter a number:\n");
	scanf("%d", &input);
	if (input % 2 == 0)
	{
		printf("是偶数\n");
	}
	else
	{
		printf("是奇数\n");
	}
	return 0;
}
//2.输出1 - 100之间的奇数
#include<stdio.h>
int main()
{
	int i = 1;
	while (i <= 100)
	{
		if (i % 2 != 0)
		{
			printf("%d ", i);
		}
		i++;
	}
	return 0;
}

switch语句

switch语句也是一种分支语句。 常常用于多分支的情况。

比如:

输入  1,输出  星期一

输入  2,输出  星期二

输入  3,输出  星期三

输入  4,输出  星期四

输入  5,输出  星期五

输入  6,输出  星期六

输入  7,输出  星期日

switch(整型表达式)
{
    语句项;
}

语句项是什么?如下:

    //case语句
	case 整型常量表达式
		语句;
//switch代码示例
#include<stdio.h>
int main()
{
	int day = 0;
	printf("Please enter a number from 0 to 7:\n");
	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;
}

有时候我们的需求变了:

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

所以我们的代码就应该这样实现了:

break语句的实际效果是把语句列表划分为不同的部分。

当 switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。
所以,每个switch语句中只能出现一条default子句。

//switch代码示例
#include<stdio.h>
int main()
{
	int day = 0;
	printf("Please enter a number from 0 to 7:\n");
	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:
			//在每个 switch 语句中都放一条default子句是个好习惯
			//甚至可以在后边再加一个 break 。
			printf("input error");
			break;
	}
	return 0;
}

循环语句

  • while
  • for
  • do while

while循环

while语句执行的流程

 例如:在屏幕上打印1-10数字。

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

while语句中的break

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

 输出:1 2 3 4

 总结: break在while循环中的作用

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

while语句中的continue

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

输出结果:1 2 3 4 

//continue 代码示例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 6 7 8 9 10 11 

总结: continue在while循环中的作用

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

再试几个其它代码:

//代码1
#include<stdio.h>
int main()
{
	int ch = 0;
	//char c = getchar();//getchar()接收1个键盘输入的字符
	//putchar(c);//打印1个字符 等价于 printf("%c",c)
	//EOF(end of file)= -1 =Ctrl+Z
	while ((ch = getchar()) != EOF)
	{
		putchar(ch);
	}
	return 0;
}
//代码2
#include<stdio.h>
int main()
{
	int ch = 0;
	while ((ch = getchar()) != EOF)
	{
		//'0'的ASCII十进制值为48 '9'的ASCII十进制值为57
		//限制只能输入0-9数字
		if (ch < '0' || ch > '9') //ch<48  ch>57
		{
			//非0-9 进行下一次循环
			continue;
		}
		putchar(ch);
	}
	return 0;
}

for循环

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

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

表达式2为条件判断部分,用于判断循环时候终止。

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

使用for循环 在屏幕上打印1-10的数字。

//while 与 for 对比
#include<stdio.h>
int main()
{
	int i = 0;
	i = 1;
	while (i <= 10)
	{
		printf("%d ", i);
		i++;
	}
	printf("\n");
	for (i = 1; i <= 10; i++)
	{
		printf("%d ", i);
	}
	return 0;
}

for循环的执行流程

在for循环中也可以出现breakcontinue,他们的意义和在while循环中是一样的。 但是还是
有些差异

#include<stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
		{
			break;
		}
		printf("%d ", i);
	}
	printf("\n");
	//输出:1 2 3 4
	i = 1;
	while (i <= 10)
	{
		if (i == 5)
		{
			break;
		}
		printf("%d ", i);
		i++;
	}
	//输出:1 2 3 4
	return 0;
}

一些建议:

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

	int i = 0;
	//前闭后开的写法
	for (i = 0; i < 10; i++)
	{
	}
	//两边都是闭区间
	for (i = 0; i <= 9; i++)
	{
	}
#include <stdio.h>
int main()
{
	//变种1
	//1.for 循环的初始化、调整、判断 都可以省略
	//但是:for循环的 判断部分 如果省略,那判断条件就是:恒为正
	//2.如果不是非常熟练,建议大家不要随意省略
	for (;;)
	{
		printf("hehe\n");
	}
	//变种2
	int x, y;
	for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
	{
		printf("hehe\n");
	}
	return 0;
}

 一道笔试题

请问循环进行了几次(k=?)?

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

结果: 循环了0次(k=0)

do...while循环

do语句的语法

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

执行流程

使用do while循打印1-10

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

do语句的特点

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

练习

1. 计算 n的阶乘。
2. 计算 1!+2!+3!+……+10!
3. 在一个有序数组中查找具体的某个数字n。 编写int binsearch(int x, int v[], int n); 功能:在v[0]<=v[1]<=v[2]<= ….<=v[n-1]的数组中查找x.
4. 编写代码,演示多个字符从两端移动,向中间汇聚。
5. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成,如果三次均输入错误,则退出程序)

6.求两个数的最大公约数

7.打印1000-2000年之间的闰年

8.打印素数

9.分数求和:计算1/1-1/2+1/3-1/4+...+1/99-1/100

10.求最大值,求10个整数中的最大值

11.在屏幕上输出乘法口诀表

1. 计算 n的阶乘

//1.计算n的阶乘(1*2*3..*n)
#include<stdio.h>
int main()
{
	int i = 0, n = 0;
	int result = 1;
	printf("please enter a number:\n");
	scanf("%d", &n);
	if (n <= 0)
	{
		printf("Input must be an integer greater than 0\n");
	}
	else
	{
		for (i = 1; i <= n; i++)
		{
			result = result * i;
		}
	}
	printf("The factorial result of n is %d\n", result);
	return 0;
}

2. 计算 1!+2!+3!+……+10! 

//2. 计算阶乘之和 1!+2!+3!+……+10!
#include<stdio.h>
int main()
{
	int j = 0, i = 0, n = 0, result = 1;
	int sum = 0;
	printf("please enter a number:\n");
	scanf("%d", &n);
	if (n <= 0)
	{
		printf("Input must be an integer greater than 0\n");
	}
	else
	{
		//方法一
		//for (int j = 1; j <= n; j++)
		//{
		//	result = 1;
		//	//求n的阶乘
		//	for (i = 1; i <= j; i++)
		//	{
		//		result = result * i;
		//	}
		//	//累加 阶乘
		//	sum += result;
		//}
		//方法二
		for (int j = 1; j <= n; j++)
		{
			result = result * j;
			sum = sum + result;
		}

	}
	printf("The factorial result of n is %d\n", sum);
	return 0;
}

3. 在一个有序数组中查找具体的某个数字n

编写int binsearch(int x, int v[], int n); 功能:在v[0]<=v[1]<=v[2]<= ….<=v[n-1]的数组中查找x. 

//3. 在一个有序数组中查找具体的某个数字n。 
//编写int binsearch(int x, int v[], int n); 
//功能:在v[0]<=v[1]<=v[2]<= ….<=v[n-1]的数组中查找x.
//方法一:顺序查找
#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,22 };
	int k = 7;
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数
	for (i = 0; i < sz; i++)
	{
		if (k == arr[i])
		{
			printf("Eureka! The result subscript is :%d\n", i);
			break;
		}
	}
	if (i == sz)
	{
		printf("Can't find\n");
	}
	return 0;
}

//方法二:二分查找/折半查找
#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,22 };
	int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数
	int left = 0;//左下标
	int right = sz - 1;//右下标
	int k = 7;//要查找的数字
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else
		{
			printf("Eureka! The result subscript is :%d\n", mid);
			break;
		}
	}
	if (left > right)
	{
		printf("Cant't find");
	}
	return 0;
}

4. 编写代码,演示多个字符从两端移动,向中间汇聚

//4. 编写代码,演示多个字符从两端移动,向中间汇聚。
#include<stdio.h>
#include<string.h>
#include<Windows.h>//Sleep()需要
#include<cstdlib>//system()需要
int main()
{
	char arr1[] = "welcome to wh.....";
	char arr2[] = "##################";
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	int left = 0;
	int right = strlen(arr1) + 1;// =sz-2 字符串后面还有一个 \0 结尾的字符

	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		//休息1秒
		Sleep(1000);
		system("cls");//执行系统命令的函数,cls:清空屏幕
		left++;
		right--;
	}
	printf("结束...");
	return 0;
}

5. 模拟用户登录情景

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

//5. 编写代码实现,模拟用户登录情景,并且只能登录三次。
//(只允许输入三次密码,如果密码正确则提示登录成,
//如果三次均输入错误,则退出程序。
#include<stdio.h>
#include<string.h>
int main()
{
	int i = 0;
	char password[20] = { 0 };
	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:>");
		scanf("%s", password);
		//strcmp(str1,str2)字符串比较函数
		//如果返回值小于 0,则表示 str1 小于 str2
		//如果返回值大于 0,则表示 str1 大于 str2
		//如果返回值大于 0,则表示 str1 大于 str2
		if (strcmp(password, "123456") == 0)
		{
			printf("登录成功!!!\n");
			break;
		}
		else
		{
			printf("第%d密码错误!\n", i + 1);
		}
	}
	if (i == 3)
	{
		printf("三次密码均错误,推出程序!!!\n");
	}
	return 0;
}

6.求两个数的最大公约数

//6.求两个数的最大公约数  辗转相除法
#include<stdio.h>
int main()
{
	int m = 0;
	int n = 0;
	int r = 0;
	printf("Please enter two numbers separated by spaces:\n");
	scanf("%d %d", &m, &n);
	while (r = m % n)
	{
		//r = m % n;
		m = n;
		n = r;
	}
	printf("%d\n", n);
	return 0;
}

7.打印1000-2000年之间的闰年

//7.打印1000-2000年之间的闰年
#include<stdio.h>
int  main()
{
	int year = 0;
	int count = 0;
	for (year = 1000; year <= 2000; year++)
	{
		//判断year是否为闰年
		//1.能被4整除并且不能被100整除的是闰年
		//2.能被400整除是闰年
		if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
		{
			count++;
			printf("%d ", year);
		}
	}
	printf("\ntotal:%d\n", count);
	return 0;
}

8.打印素数

打印100-200之间的素数

//8.打印素数
//打印100 - 200之间的素数
#include<stdio.h>
#include<math.h>//数学库函数 sqrt()
int main()
{
	int i = 0;
	int count = 0;
	//for (i = 101; i <= 200; i+=2)
	for (i = 100; i <= 200; i++)
	{
		//判断i是否为素数
		//1.试除法1
		int j = 0;
		//for (j = 2; j < i; j++)
		//{
		//	if (i % j == 0)
		//	{
		//		break;
		//	}
		//}
		//if (j == i)
		//{
		//	count++;
		//	printf("%d ", i);
		//}
		//2.试除法2
		for (j = 2; j < sqrt(i); j++)
		{
			if (i % j == 0)
			{
				break;
			}
		}
		if (j > sqrt(i))
		{
			count++;
			printf("%d ", i);
		}
	}

	printf("\ntotal:%d\n", count);
	return 0;
}

9.分数求和

计算1/1-1/2+1/3-1/4+...+1/99-1/100

//9.分数求和
//计算1/1+1/2+1/3+1/4...+1/99+1/100
#include<stdio.h>
int main()
{
	int i = 0;
	double r = 0;
	int flag = 1;
	for (i = 1; i <= 100; i++)
	{
		r += flag * 1.0 / i;
		flag = -flag;
	}
	printf("%lf\n", r);
	return 0;
}

10.求最大值

求10个整数中的最大值

//10.求10个整数中的最大值
#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int max = arr[0];//最大值
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 1; i < sz; i++)
	{
		if (arr[i] > max)
		{
			max = arr[i];
		}
	}
	printf("The Maximum value is %d\n", max);
	return 0;
}

11.在屏幕上输出乘法口诀表

//11.在屏幕上输出乘法口诀表
#include<stdio.h>
int main()
{
	int i = 1, j = 1;
	for (i = 1; i <= 9; i++)
	{
		for (j = 1; j <= i; j++)
		{
			printf("%d*%d=%d\t", i, j, i * j);
			//\t为制表符
		}
		printf("\n");
	}
	return 0;
}

猜数字游戏

电脑生成一个随机数,猜数字。

//猜数字游戏
//1.电脑生成一个随机数
//2.猜数字
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void Menu()
{
	printf("*****************************\n");
	printf("********   1.play   *********\n");
	printf("********   2.exit   *********\n");
	printf("*****************************\n");
}

void Game()
{
	//printf("猜数字");
	int ret = 0;
	int guess = 0;
	//1.生成随机数(0-100)
	ret = rand() % 100 + 1;//RAND_MAX:32767--rand函数能返回随机数的最大值。
	//printf("%d\n", ret);
	//2.猜数字
	while (1)
	{
		printf("请猜数字->:");
		scanf("%d", &guess);
		if (guess > ret)
		{
			printf("猜大了\n");
		}
		else if (guess < ret)
		{
			printf("猜小了\n");
		}
		else
		{
			printf("恭喜你!猜对了,数字是:%d\n", ret);
			break;
		}
	}
}

int main()
{
	int input = 0;
	//时间戳:当前计算机时间-计算机的起始时间(1970.1.1.0:0:0)=xxx秒
	//用时间戳来设置随机数的生成起始点
	//time_t time(time_ *timer)
	srand((unsigned)time(NULL));
	do
	{
		Menu();
		printf("请选择->:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("即将开始游戏........\n");
			Game();//开始游戏
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

goto语句

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

#include<stdio.h>
int main()
{
	printf("hello wuhan!\n");
	goto again;//跳转至again位置
	printf("hello beijing!\n");
again:
	printf("hello shenzhen!\n");
	return 0;
}

示例结果 

hello wuhan!
hello shenzhen!

goto语言真正适合的场景如下:跳出多层嵌套循环

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值