初阶C语言(3)-分支与循环

本文详细介绍了C语言的基本控制结构,如if-else、switch-case、while、for、do-while和goto,以及实战应用,包括二分查找、字符汇聚游戏、卡密验证和整蛊关机程序。通过实例演示了如何使用这些语句解决实际问题。
摘要由CSDN通过智能技术生成

目录

前言

if语句

switch语句

while循环

for循环

do while循环

goto语句

 二分查找法

字符从两端向中间汇聚

模拟卡密系统

 猜数字游戏实现

整蛊关机程序


前言

C语句可分为以下五类:
  1. 表达式语句
  2. 函数调用语句
  3. 控制语句
  4. 复合语句
  5. 空语句

C语言有9种控制语句

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

if语句

语法结构分为以下三种:

①if(表达式)  
语句;
if(表达式)
语句1;
else
语句2;
if(表达式1)//多分支
语句1;
else if(表达式2)
语句2;
else
语句3;

●C语言中,0表示假,1表示真。如果if内的条件判断为真值,则执行语句,否则不执行或执行else。
●if语句如果不加大括号{},就只能控制一条语句。
●if语句中的else只和最近的if匹配

if语句如何使用呢?写个简单的判断:

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

switch语句

语法结构:

switch(整型表达式)
{
case 整形常量表达式:
语句;
  • 在switch语句中,我们没办法直接实现分支,搭配break使用才能实现真正的分支。break语句的实际效果是把语句列表划分为不同的分支部分。
  • case即入口,整型表达式给出的常量等于多少,就进入对应的case入口
  • 如果表达的值与所有的case标签的值都不匹配,就可以定义一个default子句-default:它可以放在任何case可以出现的地方。当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。
  • 每个switch语句中只能出现一条default子句
  • break放在哪里,就在哪里结束switch语句
  • switch允许嵌套使用

 switch语句的使用:写个简单的判断输入的天数是工作日休息日

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

	return 0;
}

while循环

语法结构:

while(表达式)
循环语句;
  • 当while循环在执行过程中遇到break的时候,就永久终止循环
  • 当while循环遇到continue的时候,就终止本次循环,本次循环中continue后边的代码不会再执行,然后回到判断部分进行判断是否继续执行循环。

for循环

语法结构:

for(初始化部分; 条件判断部分; 调整部分)
  • for循环中也可以出现break和continue,它们的意义和在while循环中是一样的。
  • for循环中可以用多个变量控制循环。比如for (x = 0, y = 0; x<2 && y<5; ++x, y++)
  • for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题

do while循环

语法结构:

do
循环语句;
while(表达式);
  • 特点:循环至少执行1次,上来就干,所以不是经常使用
  • break和continue同样可以在这个循环中使用

goto语句

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

语法结构:

标签:
语句;
goto 标签;
  • goto语句最常见的用法就是终止程序在某些深度嵌套的结构的处理过程,比如一次跳出两层或多层循环。
  • 其余情况一般不常用,完全可以用其他循环替代它
  • goto语句不能跨函数跳转!

学习完了这些语句,接下来做一些实战。

 二分查找法

  • 问题描述:给定一个有序数组int arr[]={1,2,3,4,5,6,7,8,9,10};查找7在数组中的下标,找到了则输出下标,没找到则输出找不到。
  • 利用arr[0],arr[1],arr[2]…这样依次去进行数值大小判断,诚然可行,但是这是顺序排列的数组,显然效率不够高,这里就可以引入一个思想:二分查找法。
  • 假设你在进行猜数字的游戏,这个游戏不给出任何的提示,只告诉你数值在0~500之间,每次输入不正确,就告诉你这个值是大了还是小了。那怎么整呢?从1开始输入到500,一个个去判断吗?当然不,我们可以取出0~500的中位数,折半变成250,如果这个数大了,那就在左边再次折半变成125,然后125再判断…这样反复的折半,最终总会定位到一个数值。次数显然远远低于一个个去判断。有了这个思路,就简单了。

1.本题中arr中左极端下标left初始值为0,右极端下标right为(sizeof(arr)/sizeof(arr[0]))-1 (注:右极端下标求法是利用所占内存来计算元素个数,元素个数-1就是右极端的下标)
2.中间的下标mid=(left+right)/2=(0+9)/2=4,下标对应值5<7,也就意味着mid左边的值必然小了,则mid左边的值包括mid全部作废。right不动,mid向右边移一位,右移后的mid就当作新的left,即left=mid+1=5
3.新的mid=(left+right)/2=(5+9)/2=7,下标mid对应值8>7,也就意味着mid右边的值包括mid全部作废,则left不动,mid向左移一位,作为新的right,即right=mid-1=6然后继续求新的中间值mid。
4.新的mid=(left+right)/2=(5+6)/2=5,下标mid对应值是6<7,也就意味着mid左边的值包括mid全部作废,则right不动,mid向右边移一位当成新的left,即left=mid+1=6然后继续求新的中间值mid。
5.以上操作实际上就是一个循环。继续执行循环,新的mid=(left+right)/2=(6+6)/2=6,此时left=right,结束循环。
6.在循环的过程中,left始终向右靠近,而right始终向左靠近,当left>right的时候,也就无值可找了。于是跳出循环。

这样的描述太过抽象,搭配图解:

 于是程序代码如下:

#define _CRT_SECURE_NO_WARNINGS 1;
#include <stdio.h>
int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int k;
    printf("请输入要查找的数值k=");
    scanf("%d",&k);
    int sz = sizeof(arr) / sizeof(arr[0]);//求元素数量
    int left = 0;//首个下标
    int right = sz - 1;//最后一个元素的下标
    while (left<=right)//left和right是不断相互靠近的,left>right的时候,就说明已无值可查了
    {
        int mid = (left + right) / 2;//求二分平均值
        if (arr[mid] < k)//若arr[mid]比k小,则说明k在mid的右边,那么left就要等于mid+1(因为每次查找完,不应该按mid算,那样就重复了)
        {
            left = mid + 1;//left右移
        }
        else if (arr[mid] > k)//若arr[mid]比k大,则说明k在mid的左边, 那么right就要等于mid - 1;
        {
            right = mid - 1;//right左移
        }
        else//当arr[mid]=k的时候,就找到了
        {
            printf("找到啦,是下标为%d的元素", mid);
            break;//找到的时候就结束循环
        }
    }
    if (left > right)//当left和right交叉以后,也就无值可找了
    {
        printf("找不到");
    }
    return 0;
}

字符从两端向中间汇聚

●问题描述:有这样长度相等的两串字符串①welcome my code world②###############
程序执行的时候,先用①中的第一个字符和最后一个字符替换②中的第一个字符和最后一个字符,然后用①中第二个和倒数第二个替换②中对应位置的字符…从两边向中间靠拢,形成一个动态的效果。
●思路:1.首先定义两个字符串数组,利用下标的改变来进行对应的替换。2.定义两个变量作为下标,初始值分别为左右极端下标值。3.然后利用循环,对两个变量进行递增递减,左下标从0依次递增,右下标从右极端依次递减。从而实现左边的字符往右边靠拢,右边的字符往左边靠拢。4.这样循环执行n次,两边同时往中间靠拢,总会有一个界限,当左下标跟右下标交叉的时候,即左下标>右下标的时候,就无值可取了,终止循环。
于是源码如下:

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>
int main()
{
    char arr1[] = "welcome my code world";
    char arr2[] = "#####################";
    int left = 0;//左极端初始下标
    int right = strlen(arr1)-1;//右极端初始下标,strlen()是求字符串长度的函数,由<string.h>给出
    while (right >= left)//当右极端值大于左极端值的时候,就说明可以继续向中间靠拢
    {
        arr2[left] = arr1[left];//把字符串数组arr1[]左端的字符赋给arr2[]
        arr2[right] = arr1[right];//把字符串数组arr1[]右端的字符赋给arr2[]
        left++;//左下标+1,左端往右边靠拢
        right--;//右下标-1,右端往左边靠拢
        printf("%s\n", arr2);//输出arr2;
        Sleep(1000);//休息一秒钟,这个函数由<windows.h>给出,休息一秒钟能让动态效果更明显
        system("cls");//清空屏幕,这个函数由<stdlib.h>给出,清空屏幕才有动态的效果。
    }
    printf("welcome my code world");//程序到了循环的最后,会被cls清空屏幕,所以这个要加输出语句
    return 0;
}

模拟卡密系统

●问题描述:模拟用户输入卡密的程序,预设卡密为:woaixuexi,然后判断输入的内容是否为卡密。最多输错三次,三次以后,就结束程序。
程序较简单,就不写思路了,直接看源码的注释吧

#define _CRT_SECURE_NO_WARNINGS 1;
#include <stdio.h>
#include <string.h>
int main()
{
    char arr[20] = {0};//定义一个字符数组存放输入的卡密
    int i = 0;
    for (i=1;i<=3;i++)//给定3次循环
    {
        printf("请输入卡密\n");
        scanf("%s", &arr);
        if (strcmp(arr, "woaixuexi") == 0)  
        {
            printf("卡密正确,进入系统\n");
            break;
        }
        else
            printf("输入错误\n");
    }
    return 0;
}

值得一提的是:两个字符串的比较不能使用等号,应该使用strcmp()函数,strcmp判断两个字符串若相等,则返回0。

 猜数字游戏实现

●问题描述:
 ①自动产生一个1~100的随机数②输入一个数字,猜对了,游戏结束。猜错了,就告诉你猜大了还是猜小了,继续猜,直到猜对③游戏可以一直玩,除非退出程序

●思路:①执行程序,就进入游戏菜单,于是需要定义一个菜单函数。用do while语句非常合适,上来就干②输入1开始游戏,输入0结束程序,输入其他的内容就提示输入错误重新输入。于是在do while后面的while的中,就可以用这个输入的1与0来作为条件判断了,1为真,0为假,输入0,while循环就结束。③输入1,则执行游戏,于是我们还需要定义一个游戏函数。游戏函数首先要生成一个1~100的随机数,这是这个程序的关键点。怎样实现它呢?我们需要了解这样一个库函数:rand(),这个函数会返回一个0-32767之间的数字,它定义于头文件<stdlib.h>中。rand是随机数,模上100,得到的余数就是0~99,再加一个1,得到的就是1~100。但是我们发现,这个rand虽然每次生成的随机数不同,但是每次重新执行程序的时候,生成的数值都是固定不变的。玩家玩了第一次之后,关闭程序重新开始游戏,结果第二次的结果还是和第一次一样,这样的游戏玩下去还有什么意思呢?所以我们必须让这个rand每次关闭游戏后重新打开都会生成不一样的数值。于是我们使用库函数:srand(),它也定义于头文件<stdlib.h>中,它的作用是定义rand的随机数变化初始值,也就是说srand决定了rand()的变化。只要srand发生变化,rand()也就发生了变化。那么如何让srand发生变化呢?就要用到时间戳这个东西了,时间戳是1970年1月1日(00:00:00)至当前时间的总秒数,时间在时刻不断的发生变化,那么,我们只需要把时间戳作为srand的参数,那么每次关闭程序,时间都不同,那么rand的初始值也就不同了,于是棘手的问题就会迎刃而解了,时间戳可以用time()获取,time是由库函数<time.h>给出的。值得一提的是,srand应该只设置一次时间戳,如果每次答对了就重新设置一次srand,rand生成的数字加了几十秒然后取模100,可想而知,我们将会得到的初始值是会很相近的,那样随机度极大的减少了。④随机数的问题解决了,然后定义一个死循环,进行可以反复猜测的猜数字。然后就是简单的判断了,如果答对了,就break跳出循环,回到菜单。源码如下:

#define _CRT_SECURE_NO_WARNINGS 1;
#include <stdio.h>
#include<time.h>
#include<stdlib.h>
void menu()//菜单函数
{
    printf("**********************\n");
    printf("****** 1. play *******\n"); 
    printf("****** 0. exit *******\n");
    printf("**********************\n");
}
void game()//游戏函数
{
    //生成随机数
    int ret = rand()%100+1;
    int sum;//sum是输入的数字
    while (1)//定义一个死循环,可以反反复复猜数字
    {
        scanf("%d", &sum);
        if (sum > ret)//判断部分
        {
            printf("输入值过大\n");
        }
        else if (sum < ret)
        {
            printf("输入值过小\n");
        }
        else
        {
            printf("恭喜你,答对啦\n");
            break;//如果输入正确,就跳出本循环,重新执行switch语句
        }
    }
}
int main()
{
    srand((unsigned int)time(NULL));//时间戳作为srand的参数。srand是rand的初始值,数据类型为无符号整型,这个函数需要要在rand使用前定义。时间戳time(NULL)表示不储存。
    int  input = 0;
    do
    {
        menu();//打印菜单
        printf("请选择:>");
        scanf("%d",&input);
        switch (input)
        {
            case 1://输入1则进行游戏
                game();
                break;
            case 0://输入0则退出游戏
                printf("退出游戏\n");
                break;
        default:
                printf("输入错误,请重新输入\n");
            break;
        }
    } while (input);//如果输入1,则继续执行循环,如果输入0,则为假,结束循环。输入其他,则为真,提示输入错误
}

整蛊关机程序

●引子:如何做一个关机程序来整蛊你的朋友呢?首先要了解cmd命令。
在cmd中,shutdown -s是关机,shutdown -a是取消关机。
如何在C语言中实现cmd命令呢?C语言给出了一个特定的函数system(),这是执行cmd命令的函数,它包含在<stdlib.h>头文件中。有了它,就好整了。

●思路:开始执行程序就直接执行60秒钟关机,然后输出提示:叫爸爸就给你取消关机。如果他输入的是爸爸,就取消关机,这里就需要判断字符串了。判断他输入的字符串是否等于爸爸。两个字符串,要判断他们是否相等,不能使用等号,必须使用strcmp()函数,这个函数由<string.h>头文件给出,全称string comepare,如果strcmp里面的两个字符串相同,就返回一个0。
直接上源码!

#define _CRT_SECURE_NO_WARNINGS 1;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
	//60秒后关机 shutdonw -s -t 60
	//取消关机 shtudown -a
	//system() -执行系统命令
	char input[20] = { 0 };//用于存放输入的信息
	system("shutdown -s -t 60");//60秒后执行关机
again://goto语句的跳转部分
	printf("请注意,你的电脑在一分钟内将会关机,叫爸爸,就给你取消关机\n");
	scanf("%s", input);
	if (strcmp(input, "爸爸") == 0)//判断两个字符串是否相等
	{
		system("shutdown -a");//相等则取消关机
		printf("\n儿子真乖");
	}
	else
		goto again;//不相等则跳转到again部分,然后重新判断输入情况
	return 0;
}

 本章完,愿你有所收获,如果再也不能见到你,也祝你早安午安,还有晚安。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

叶轻衣。

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

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

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

打赏作者

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

抵扣说明:

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

余额充值