[C语言]C语言基础学习第四篇:分支循环语句

作者前言

哦哈哟,大家们!!不知不觉已经来到第四篇了,在不断的学习中我发现我的c语言功底还是十分的不牢固啊,看到一些之前的题目都全忘记了┭┮﹏┭┮。太难了。。。不过在不断地复习中我也渐渐地放平心态得心应手,慢慢地给大家写到了这里。

 今天我们就来学习c语言里面的分支语句

分支语句:

  • if
  • switch

循环语句:

  • while
  • for
  • do while

分支语句

分支语句就是有着不同的选择

if else:

// 单分支
if (条件):
{
    语句;
}
else:
{
    语句;
}
// 多分支
if (条件)
{
    语句;
}
else if (条件)
{
    语句;
}
else:
{
    语句;
}

 当我们的条件表达式的结果是0,那么这条分支就走不下去失败了,如果我们的结果不是0(非0),那么结果是真,可以继续运行。

int main()
{
    int age = 60;
    if (age < 18)
    {
        printf("青少年");
    }
    else if (age >= 18 && age < 30)
    {
        printf("年轻人");
    }
    else if (age >= 30 && age < 60)
    {
        printf("中年人");
    }
    else
    {
        printf("老年人");
    }
    return 0;
}

 当我们想写一个范围的时候我们不能写 18<= age < 30。 我们要写成 age>=18&&age<30。

int main()
{
    int a = 0;
    int b = 2;
    if (a == 1)
        if (b == 2)
            printf("hehe\n");
    else
        printf("haha\n");


        return 0;
}

对于在这个题大部分人会下意识认为,答案是haha,因为if里面的语句为假,所以下面的语句不运行,运行else里的语句。但实际上c语言跟python不一样,不是按照缩进来分配代码的,最下面的else 实际上是和最近的一个if连接。

当你在visual studio打代码的时候,你会发现IDE会自动将第二个if和最后一个else拼在一起。

int main()
{
    int a = 0;
    int b = 2;
    if (a == 1)
        if (b == 2)
            printf("hehe\n");
        else
            printf("haha\n");


        return 0;

所以结果是什么都不打印。

所以我们可以用{}来方便我们正确的看代码的运行。

int test()
{
	if (1)
		return 0;
	return 1;
}

int main()
{
	test();
	return 0;
}

我们看这个例子,主函数运行test函数,然后if(1)运行return0后,就不会再运行了,我们的所有函数都只能return一个值。所以当return0的时候就不再运行了。

int main()
{
    int num = 3;
    if (num = 5)
    {
        printf("hehe\n");
    }
    return 0;
}

这里也是非常容易错的地方,会有人认为,3不等于5,所以最后什么都不运行,但你仔细看,if里的分支条件是num赋值3,实际上条件为真,打印hehe。

好!我们现在来写几个练习:

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

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

int main()
{
	int a = 0;
	scanf("%d", &a);
	if (a % 2)
	{
		printf("结果为奇数");
	}
	else
	{
		printf("结果为偶数");
	}
	return 0;
}
int main()
{
	int i = 0;
	for (i = 0; i <= 1000; i++)
	{
		if (i % 2)
		{
			printf("%d\n", i);
		}
	}
	return 0;
}

switch:

当我们想要输入像

输入1,输出星期一

输入2,输出星期二

输入3,输出星期三

输入4,输出星期四

输入5,输出星期五

输入6,输出星期六

输入7,输出星期日

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

我们用case +不同的数字来形成多个类似的分支,但是加入我们原代码里没有break,那么当我们输入1,他会从case 1进入,然后打印星期一,但是他没有跳出循环的标志,那么他就会继续运行,到case 2输出星期二,直到最后。

 case + 整型常量

 当我们设定1-5是工作日,6-7是休息日我们就会发现其实不是每个case都一定要加break

int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日\n");
		break;
	case 6:
	case 7:
		printf("休息日\n");
	}

	return 0;
}

当我们输入1 或者 6 的时候 就会输出 工作日 和 休息日。

 但是对于我们最后一个break,我们会认为没有必要,但是如果我们未来需要填入新的分支就会方便和易读。

但是我们故意打1-7之外的东西怎么办呢?

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

 我们的default 语句就会在所有前面的语句都没实现的时候输出。我们的default的语句可以放在switch语句内部的任意地方。

循环结构

while:

while(条件)

{

        循环语句;

}

当我们的条件一直满足就会导致出现死循环。

int main()
{
	while (1)
	{
		printf("hehe\n");
	}
	return 0;
}

所以我们就需要一些语句来防止这个死循环的发生:

int main()
{
	int i = 0;
	while (i < 10)
	{
		printf("hehe\n");
		i++;
	}
	return 0;
}

i++, 不断自增来使得i的大小大于等于10。突破循环。

如果我们加入if和break的组合会发生什么。

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

 当我们的if语句成立的时候,break的效果是直接把一整个循环给跳出去了直接从if语句里调到return 0。

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

 虽然也是打印出5个hehe,但是你会看到光标一直在跳动,代表的意思是程序一直在运行。我们的continue是跳过本次循环。

int main()
{
	int ch = 0;
	while ((ch = getchar()) != EOF)//从键盘中一个一个读取信息然后获取
		putchar(ch);
	return 0;
}

我们会看到两个新的函数:getchar 和 putchar

getchar的定义:

Get character from stdin

Returns the next character from the standard input (stdin).

putchar的定义:

Write character to stdout

Writes a character to the standard output (stdout).

【C语言】C语言学习整理-putchar,printf,getchar,scanf定义及区别_getchar()与scanf()的区别,putchar()和printf()的区别?-CSDN博客

这一片博客讲的非常的详细,可以看一看。

当我们输入abc的时候,实际上我们的缓存区里存放着abc\n,应为你的结束必须是回车才能运行。

 我们想要退出的时候只要输入ctrl+z就行,但是我看弹幕有说别的键位,可能是版本不同。

int main()
{
    char password[20] = { 0 };
    printf("请输入密码:>");
    scanf("%s", password);
    //这里没有&是因为,数组名本身就是地址。
    int ch = getchar();
    if (ch == 'Y')
    {
        printf("确认成功\n");
    }
    else
    {
        printf("确认失败\n");
    }

    return 0;
}

这里假如我们输入了1234,我们会发现结果会直接“确认失败”。

 我们可以这么理解,当我们把114514输入的时候,我们按下了回车。这个时候我们的printf从缓冲区里面拿去了114514,但是没有拿走\n(换行),所以我们的getchar就直接从缓冲区里把\n拿走当做变量ch的值。所以直接错误。

那我们就可以在printf后,用getchar将\n拿走,清空我们的缓冲区。

int main()
{
    char password[20] = { 0 };
    printf("请输入密码:>");
    scanf("%s", password);
    //这里没有&是因为,数组名本身就是地址。
    getchar();
    int ch = getchar();
    if (ch == 'Y')
    {
        printf("确认成功\n");
    }
    else
    {
        printf("确认失败\n");
    }

    return 0;
}

或者

int main()
{
    char password[20] = { 0 };
    printf("请输入密码:>");
    scanf("%s", password);
    //这里没有&是因为,数组名本身就是地址。
    // 清理缓冲区里面的内容
    int tmp = 0;
    while ((tmp = getchar()) != '\n')
    {
        ;
    }
    int ch = getchar();
    if (ch == 'Y')
    {
        printf("确认成功\n");
    }
    else
    {
        printf("确认失败\n");
    }

    return 0;
}

我们可以用while循环来一直取走缓冲区里的数据,直到‘\n’。 

for循环

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

        循环语句;

表达式1:初始化

表达式2:条件语句

表达式3:调整部分

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

 i = 1就是提前设定i的初始值为1;

i<=1就是我们循环的条件;

i++ 自增,就是我们跳出循环的方式。

 for循环中的一些建议:

1. 不可在for循环中修改循环变量,防止for循环失去控制

2. 建议for语句的循环控制变量的取值采用‘前闭后开区间’写法。

后开的数字可以代表着这个循环的次数,可读性更好。

for循环也有一些变种:

int main()
{
    for(;;)
    {
        printf("hehe\n");
    }
    return 0;
}

判断部分的省略,使得整个循环一直真,陷入了死循环。

int main()
{
    int i = 0;
    int j = 0;
    for(; i < 3 ; i ++)
    {
        for(; j < 3; j++)
        {
            printf("hehe\n");
        }
    }
    return 0;

}

这里我们的两个for循环都省略了初始化,所以当我们第一个for的第一个循环里j已经变成了3,所以2,3次循环的时候,第二个for循环就不再进行了。所以结果为3。

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

这里仔细看for循环的条件,是k = 0, 所以这个循环一直是假。 0次循环

do...while()语句

do

        循环语句;

while(条件);

与while的不同点在于,while是先判断后进行,do...while是先进行后判断。

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

 加上break和continue会怎么样呢?

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

 

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

 

 接下来我们来个练习。

1.求n的阶乘

2.求1! + 2! + 3!+.....+ n!

int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int a = 1;
	int b = 0;
	for (i = 1; i < n + 1; i++)
	{
		a *= i;// 求第n的阶乘
		b += a;// 求1!+ 2!+ 3!+.....+ n!
	}
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

 我们来个难一点的:

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

int main()
{
	int a = 8; // 我们设定的想要找到的数字
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 我们的数组
	int n = sizeof(arr) / sizeof(arr[0]); // 求出我们数组的大小
	int Left = arr[0]; // 最左端的元素
	int Right = arr[n - 1]; // 最右端的元素
	int Mid = (n - 1) / 2; // 中间的元素
	while (Left <= Right) // 二分法。
	{
		int Middle = arr[Mid];
		if (a < Middle)// 我们要找的数小于中间值
		{
			Right = arr[Mid - 1]; // 右端的最大值改变为中间元素的左边一个
			Mid = (Mid - 1 + 0) / 2; // 中间元素的下标改变
		}
		else if (a > Middle)// 我们要找的数大于中间值
		{
			Left = arr[Mid + 1]; // 我们左端的最小值改变为中间元素的右边一个
			Mid = (Mid + n) / 2; // 中间元素的下标改变
		}
		else
		{
			a = Middle; 
			printf("成功找到");
			break;
		}
	}
	if (Left > Right)
	{
		printf("找不到了");
	}
	return 0;
}

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

int main()
{
	char arr1[] = "welcome to osu";
	char arr2[] = "##############";
	int left = 0;
	int right = strlen(arr2) - 1;
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		Sleep (1000);
		system("cls");//清空屏幕
		left++;
		right--;
		printf("%s\n", arr2);
	}
	return 0;
}

 Sleep,system函数需要头文件<windows.h>,sleep就是相当于停止运行多少毫秒然后继续运行,有一种卡顿的没,system("cls")函数就是将终端内的内容清空。使得最后呈现的样子像是一行内两端逐渐出字。

5.编写代码实现,模拟用户登录的情景,并且只能登录三次。

int main()
{
	int i = 0;
	char password[20] = { 0 };
	for (i = 0; i < 3; i++)
	{
		printf("请输入你的六位密码\n");
		scanf("%s", password);
		if (strcmp(password, "123456") == 0)
		{
			printf("登录成功\n");
			break;
		}
		else
		{
			printf("密码输入错误\n");
		}
	}
	return 0;
}

 

 strcmp函数的用法可以在https://blog.csdn.net/weixin_65931202/article/details/133700063?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170521071816800192268116%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170521071816800192268116&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-133700063-null-null.142^v99^control&utm_term=strcmp&spm=1018.2226.3001.4187

这篇博客里看一下,这里的代码就是比较我们输入的密码和预设的密码“123456”之间是否相同,相同的时候就会输出0。

6.猜数字游戏:

这个我在之前就发了一篇博客,你可以直接点击标题进入那篇博客的链接。

我们将代码分为菜单,奖励,游戏和主函数四个部分:

菜单:

void menu()
{
    printf("********* guess game ********\n");
    Sleep(100);
    printf("*****************************\n");
    Sleep(100);
    printf("*********  1. play  *********\n");
    Sleep(100);
    printf("*********  0. exit  *********\n");
    Sleep(100);
    printf("*****************************\n");
    Sleep(100);
}// 打印出我们的菜单界面

这里我们设置了menu函数,

menu();// 打印菜单

 我们在主函数内部用这个就可以打印出我们菜单。

奖励:


void prize()
{
    printf("\n");
    printf("         ************        \n");
    printf("      ******************     \n");
    printf("  ***********   ************ \n");
    printf("*********           *********\n");
    printf("  ***********   ************ \n");
    printf("      ******************     \n");
    printf("         ************        \n");
    printf("\n");
}// 成功猜对数字获得奖励

我们自己随便花了个硬币的样子,当我们成功猜成功,我们就会显示一个硬币。

到我们最难的地方,游戏逻辑部分:

游戏

void game()
{
	//猜数字游戏的实现
	// 1. 生成随机数
	// rand函数返回从0到rand_max(32767)范围内的一个伪随机整数。
	// 主函数处使用srand函数对伪随机数生成器生成种子。
	int ret = rand() % 100 + 1;//范围就是100
	//printf("%d\n", ret);
	// 2. 猜数字
	int guess = 0;
	int i = 0;
	int a = 0;
	int b = 0;

	while (1)
	{
		//printf("猜数字");
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
			i++;
			a++;
			printf("第%d次guess\n", i);
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
			i++;
			b++;
			printf("第%d次guess\n", i);
		}
		else
		{
			printf("恭喜你,猜对了\n");
			i++;
			printf("第%d次guess\n", i);
			prize();
			printf("         获得第%d个硬币         \n", c_gol);
			break;
		}

	}
	printf("猜小%d次 猜大%d次 总共%d次\n", a, b, i);
}

 主函数:

int main()
{
	srand((unsigned int)time(NULL));//srand函数接受的是unsigned int类型,                    
	//time(null)/time(0)返回的就是现在的时间戳
	int input = 0;
	do
	{
		c_gol++;
		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;
}

srand是通过你输入的数字来生成种子,种子就有点想我的世界里的种子,所有的随机数都会按照不同的种子产生,所以我们不需要时时刻刻有着不同的种子来达到随机的可能。这时候我们可以用时间,我们的时间一直会改变,那么种子也会随时改变,达到随机。

srand((unsigned int)time(NULL));//srand函数接受的是unsigned int类型,   

时间我们就用time函数。因为我们的srand接受unsigned int类型,我们就强制类型转换。点击time你就能看到相关的函数意思。我们的游戏部分里我们用if语句来达到猜大猜小,主函数里我们用do..while加上switch分支来达到我们能够一直玩的目的。


第四期结束啦,我们结束了分支循环语句的旅程!!(*^▽^*)

参考:C 语言中的 time 函数总结

           strcmp函数详解:字符串【比较】的利器

        感谢这些大大!!!

  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值