【初始C语言2】详细认识分支语句和循环语句以及他们的易错点,应用(猜大小游戏)

简介: 【初始C语言2】详细认识分支语句和循环语句以及他们的易错点,应用(猜大小游戏)

前言:      

      在上一章内,小编我带领大家进行进行了基础C语言的梳理和导航,希望大家要将第一章的内容好好利用起来!小编在这里谢谢大家了!      


      在这一章内,小编我会详细地为大家介绍分支语句与循环语句的,希望大家在看完之后,点个赞,支持一下博主,谢谢大家了!进行完分支语句和循环语句的学习后,小编自认为学的比较不错,但是在做题的过程中,我还是发现有一些容易错的地方,下面跟随小编的步伐进行学习吧!


      另外,还有大家最关心的事情——学了这一章内容,到底应该怎么利用所学知识运用到生活中呢?请看这一章最后的内容!


一、什么是语句?

      因为这里是C语言的详细讲解,所以我们要细细品味每一个名词、知识点。要学习分支语句和循环语句,就要先知道什么是语句?小编认为C语言中的语句就是我们平常说的话一样,用句号进行分割。而C语言类似,在大部分情况下,我们用分号进行分割。


      在C语言中,语句可以分为以下五类:1)表达式语句;  2)函数调用语句; 3)控制语句;4)复合语句;5)空语句。


下面进行每种语句的举例,来帮助你更好地了解他们:


1.1 表达式语句

      顾名思义,就是表达式加上分号。下面进行代码解释:

3 + 5;  //这就是表达式语句

1.2 函数调用语句

      函数调用语句,就是将函数进行使用时调用的语句。下面进行代码解释:

printf("%d\n", ans);  //进行调用库函数
ADD(3, 5);            //进行调用自定义函数

1.3 控制语句

      控制语句是用于控制程序的执行流程,以实现程序的各种结构方式(C语言是结构化的程序设计语言),他们由特定的语句定义符组成,C语言有九种控制语句。今天讲的分支语句与循环语句就是控制语句。


可分为以下三类:


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


2)循环执行语句:do while语句,while语句,for语句;


3)转向语句:break语句,goto语句,continue语句,return语句。


1.4 复合语句

      别被他这个名字吓一跳,小编我刚开始也认为复合语句很难,其实,复合语句就是多条语句用大括号进行包围起来。下面进行代码解释:

{
    int a = 0;
    int b = 0;
    printf("%d\n", a + b);
    return 0;
}

1.5 空语句

      空语句虽然很简单,但是其用途很大:有时候需要一条语句,但这条语句什么都不需要做。下面进行代码解释:

while(*dest++ = *src++)
{
    ;
}

进行完这几种语句的举例,那么我们接下来进行这篇博客的重点:分支语句。


二、分支语句(选择结构)

      在学习分支语句之前,我们需要知道一件事情:在C语言中,0为假,非0为真!(负数也是真)


分支语句分为两类:if语句,switch语句。


下面我们来看分支语句的流程图:


微信截图_20230911214706.png

2.1 if语句


那么if语句语法结构是怎么样的?下面进行代码解释:

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

  当然,这些语句仅限于在单语句中进行,那么何为单语句呢?就是只有一个语句

      如果条件成立,要执行多条语句,应该使用代码块。那么何为代码块呢?就是用大括号包围起来的语句。下面用代码进行解释:

#include <stdio.h>
int main()
{
    if(表达式)
    {
        语句列表1;
    }
    else
    {
        语句列表2;
    }
    return 0;
}

2.2 switch语句  

      switch语句也是一种分支语句,常常用于多分支情况!小编认为每一种分支语句的形式都是为了在不同情况中实现而生的。


      比如,输入1,输出星期一; 输入2,输出星期二;输入3,输出星期三;输入4,输出星期四;输入5,输出星期五;输入6,输出星期六;输入7,输出星期七。


      如果写成if...else if...else if...else的情况就很复杂,那我们需要有不一样的语法形式。


这就是switch语句(支持嵌套使用):

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

当大家看到语句项的时候,可能会小懵一手,那么语句项是什么呢?


语句项就是一些case语句,如下:


       case 整形常量表达式:


             语句;


三、分支语句(选择结构)易错点:

3.1  if和else的对应关系(悬空else):

看下面的这个代码:

//要有良好的代码风格
int main()
{
  int a = 0;
  int b = 2;
  if (1 == a)
    if (2 == b)
      printf("hehe\n");
  else
    printf("haha\n");
  return 0;
}

这样写代码是不正确的,要有良好的代码风格,不然会被喷成狗的。(小编建议看一下《高质量 C++/C 编程指南》这本书来养成良好的代码风格)所以适当的使用{}可以是代码的逻辑更加清楚。


易错点:else的匹配: else是和它里的最近的if匹配。


3.2  if语句的一些优化:

看下面的图片:

微信截图_20230911214911.png

微信截图_20230911214921.png

 在if语句中,如果写成了赋值,程序是不会报错的,而只是会有警告的,对以后的调试带来不好的结果。所以我们可以进行下面的操作:


      这种操作如果你少写了一个‘=’,程序会进行报错,不会出现上述情况。如果if括号里的是表达式而不是变量,则不需要进行这种操作。因为表达式不会被赋值。

#include <stdio.h>
int main()
{
  int num = 1;
  if (5 == num)
    printf("hehe");
  return 0;
}

3.3  switch语句中的break:

      在switch语句中,我们要时刻关心break语句,使得case与break配合使用;在switch语句中所有分支下都没有增加break语句,因此会从上往下顺序执行,最后执行default中语句返回。break语句的作用是:break实现了switch语句跳出分支的效果。


在这里小编提一个编程好习惯:


在最后一个case语句的后面加上一条break语句。


(之所以这么写是可以避免出现在以前的最后一个case语句后面忘了添加break语句)。


3.4 switch语句中的default子句:

      如果表达的值与所有的case标签的值都不匹配怎么办?其实也没什么,结构就是所有的语句都被跳过而已!程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。


      但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?你可以在语句列表中添加一条default语句。


default语句:


      这条语句可以写在任何一个case标签出现的位置。当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。所以,每一个switch语句中只会出现一条default子句。但是他可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default语句。


在这里小编再提一个编程好习惯:


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


四、循环语句

循环语句分为三类:while循环,for循环,do......while循环。


4.1 while循环

在前面,我们已经掌握了if语句:


if语句:当条件满足的情况下,if语句后的语句执行,否则不执行。但是这条语句只会执行一次。


      由于我们发现生活中很多实际的例子是:同一件事情我们需要完成很多次。所以C语言中给我们引入了:while语句,可以实现循环。


那么while语句的语法结构是怎么样的?下面进行代码解释:

while(表达式)
    循环语句;

while循环的执行流程:

微信截图_20230911215103.png

4.2 for循环


      在我的认知里,for循环将是你用的最频繁的循环了,所以for循环算是一个重点


4.2.1 语法


      当然,先来看一下for语句语法结构是怎么样的?下面进行代码解释:

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

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

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

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

for循环的执行流程:

微信截图_20230911215221.png

    现在,我们学习完了while循环for循环后,让我们进行对比一下这两个循环:

int i = 0;
//实现相同的功能,使用while
i = 1; //初始化部分
while(i <= 10) //判断部分
{
    printf("hehe\n");
    i = i + 1; //调整部分
}
//实现相同的功能,使用for
for(i = 1; i <= 10; i++)
{
    printf("hehe\n");
}

      通过上面的代码,可以发现在while循环中依然存在循环的三个必须条件,但是由于风格问题使得三个部分很可能偏离较远,这样查找修改不够集中和方便。


4.2.2 for语句的循环控制变量

在这一部分,小编有一些建议:


1)不可在for循环体内修改循环变量,防止for循环失去控制;


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


4.3 do......while()循环

       在小编看来,这个循环用的也是比较少的。


4.3.1 do语句的语法

      来跟随小编的脚步看一看do......while()语句的语法结构是怎么样的?下面进行代码解释:

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

do......while()循环的执行流程:

微信截图_20230911215347.png

4.3.2 do语句的特点

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

4.4 利用循环简答清理缓冲区(应用)

前言:

      在学习循环语句时,有几个例子:1.多组输入;2.清理缓冲区。希望能够将while循环与实际问题进行结合。下面我们就来进行一一展示:


4.4.1 多组输入

      在我们进行OJ题目的训练时,常常会看到以下的题目要求!这时,初学者会一脸懵逼!不要怕,下面我们就来消灭他:

微信截图_20230911215419.png

4.4.1.1 scanf函数的一些见解

      在进行多组输入的讲解前,我们需要进行介绍scanf函数,在下面的链接上有详细的介绍(要学会使用cplusplus) ——scanf函数介绍,下面是小编我自己的介绍:


1.第一个用法,有人可能是一脸懵的,小编刚学的时候也是不相信的,输入函数居然有返回值,大家还是要欣然接受,毕竟大千世界无奇不有。scanf函数的返回值是int类型的,返回的是读取数据的个数,下面用代码进行证明:

微信截图_20230911215447.png

微信截图_20230911215454.png

2.这是scanf函数与gets函数的区别,在一些OJ题中,有时需要输入有空格的字符串,而scanf函数在读取字符串时,遇到空格就不在读取了 ;这时我们需要使用gets函数来接收。

微信截图_20230911215547.png

总结:scanf函数是从缓冲区中的数据读取的,读取成功后,返回读取数据的个数;读取失败后,返回EOF(-1);其次在读取字符串时,遇到空格就不在读取了。


scanf函数的返回值是int类型的,返回的是读取数据的个数;

scanf函数在读取字符串时,遇到空格就不在读取了 。

4.4.1.2 多组输入的习题

下面进行一个简单的题目:


微信截图_20230911215601.png

4.4.2 清理缓冲区

      在这一部分,我们需要先了解什么是缓冲区,为什么要引入缓冲区,其次要学习一个新函数,最后模拟实现循环清理缓冲区。

4.4.2.1 什么是缓冲区(buffer)

      缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。


什么是输出缓冲区?


      在C语言中,很多输出函数(如printf,putchar)存在输出缓存,在windows系统中,使用printf()函数后,数据被写入输出缓冲区,随后立即刷新缓冲区,所有我们在使用printf()函数时,往往会很快就在控制台中打印出来(Linux操作系统略有不同,等小编学完Linux后,在来讲解)。


什么是输入缓冲区?


      同理得,输入函数(如scanf,getchar)也存在输入缓存,并且这些输入函数属于阻塞函数,当缓冲区没有内容时,程序将阻塞在输入函数中,等待用户从键盘输入内容,并按下回车键(即换行‘\n’)确认,之后,输入的字符将进入缓冲区,输入函数便从缓冲区获取字符,并且删除缓冲区中已经获得的字符,并解除阻塞状态继续执行代码。


下面举例一个十分经典的C语言代码来展示输入缓冲的存在:

  char str[10];
  int i;
  for(i=0;i<10;i++)
    scanf("%c",&str[i]);        
  for(i=0;i<10;i++)
    printf("%c",str[i]);

第一种情况:如果我们正常地输入10个字符,然后就会正常的输出10个字符,打印正常。

微信截图_20230911215712.png

第二种情况:如果我们输入a,然后回车;输入b,然后回车……结果只能输入5个字符便结束了程序,这也是我们要清理缓冲区的原因,在多组输入字符中,回车也是会被系统当成字符的,这样利用上面对整数的多组输入就不能使用,所以我们要清理缓冲区中的回车。

微信截图_20230911215740.png

4.4.2.2 为什么要引入缓冲区这个概念?

      在以前的时期,我们要用磁盘进行储存信息,我们可以先将数据放在缓冲区,等缓冲区的数据读取完后,再去磁盘中进行读取。这样减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。


4.4.2.3 介绍一个新函数——getchar()

      顾名思义,getchar()函数的功能是获取一个字符,而putchar()函数的功能是输出一个字符。


     下面,进行具体的getchar()函数的功能介绍:在下面的链接上有详细的介绍getchar函数。getchar()函数,读取成功后,返回读取到字符的ASCII值(为int);读取失败后或遇到文件末尾时,返回EOF(-1)。


4.4.2.4 模拟环境进行缓冲区的清理

      在下面的环境中——输入密码请确认是否正确,如果正确输出正确;如果错误输出失败。在这个过程中会出现一些问题:我们在输入完密码后,会敲一个回车,然后再输入(Y/N),但是在我们敲完回车后,程序直接结束了。


      因为缓冲区中会有回车这个字符,getchar()会接收回车而不是(Y/N),这个程序看着没有太大的问题,但我们需要利用循环进行缓冲区的清理,这样如果有特殊情况,我们也可以进行清空缓冲区。

  char arr[20];
  printf("请输入密码:>");
  scanf("%s", arr);  //scanf函数在读取字符串时,遇到空格就不再读取
//在这里插入清理缓冲区的代码
  printf("请确认(Y/N):>");
  int ch = getchar();
  if ('Y' == ch)
    printf("确认成功\n");
  else
    printf("确认失败\n");

微信截图_20230911215835.png

微信截图_20230911215855.png

微信截图_20230911215907.png

解决方法:

while ((ch = getchar()) != '\n')
    ;   //在这里,我们需要循环但不需要循环体,用空语句充当循环体,空语句的用法

五、循环语句的易错点:


5.1  while循环中的continue:


      while循环中continue的作用是:跳过本次循环后面的代码,直接去判断部分,看是否进行下一次判断。

下面来看一下这道题:

微信截图_20230911220008.png

这个代码主要是让我们注意一下边界,以免出现漏项。


5.2  while循环中的break:

      break在循环中不是很难,也不是很有诱惑性。读者们只需记住其在对应循环中的作用即可。


break在while循环中的作用:


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


5.3  for循环中的continue:

在for循环中,continue的作用是:跳过本次循环后面的代码,直接去循环的调整部分。

微信截图_20230911220023.png

5.4  for循环的变种:


      在for循环中,初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题。看下面两个代码:

#include <stdio.h>
int main()
{
  int i = 0;
  int j = 0;
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      printf("hehe");
    }
  }
  return 0;
}
//打印出100个hehe
#include <stdio.h>
int main()
{
  int i = 0;
  int j = 0;
  for (; i < 10; i++)
  {
    for (; j < 10; j++)  //因为初始化部分省略,没有给j赋初值
    {
      printf("hehe");
    }
  }
  return 0;
}
//打印出10个hehe

六、goto语句

      在小编看来,学校是不会讲goto语句的,因为如果goto语句用的不好,会导致程序跳来跳去的。但是这篇博客是分支语句和循环语句全详解,所以小编还是要讲一讲。


6.1 goto语句的作用

      C语言中提供了可以随意滥用的goto语句和标记跳转的标号。从理论上goto语句时没有必要的,实践中没有goto语句也可以很容易的写出代码。但是某些场合下goto语句还是用的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。


例如,一次跳出两层或多层循环。


多层循环这种情况使用break是达不到目的的,他只能从最内层循环退出到上一层的循环。


6.2 goto语句的使用场景

      在上面,小编为读者解释了goto语句的作用,那么下面小编将为读者们写下goto语句的代码:

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

6.3 goto语句的例子

这个是一个关机程序的例子,也是一个恶作剧,等读者学会后,读者可以去恶搞你的室友。

#include <stdio.h>
#include <windows.h>
#include <string.h>
int main()
{
    char input[10] = {0};
    system("shutdown -s -t 60");
again:
    printf("电脑将在1分钟内关机,如果输入:我是猪,就取消关机!\n请输入:>");
    scanf("%s", input);
    if(0 == strcmp(input, "我是猪“)
    {
        printf("shutdown -a");
    }
    else
    {
        goto again:
    }
    return 0;
}

七、 分支语句和循环语句的应用(猜数字),了解随机数(rand())和时间函数(time(NULL))

      Hello,各位!今天来通过一个小游戏引进一个知识点:生成随机数。下面进行介绍的所有概念都有对应的链接进行匹配,详细内容请点击链接进行观看。


7.1 生成随机数

      先来介绍一下随机函数rand():rand函数的介绍。返回值为0到RAND_MAX(32767)的一个伪随机数。在使用rand函数之前,要先使用srand函数,设置随机数的生成起点。(这句话可能有些小伙伴们不懂,但往下继续看。)


      在来介绍一下srand()函数:srand函数的介绍。函数的参数为:伪随机数字的种子生成。上述两个函数都有提到:伪随机数字,那么伪随机数字究竟是什么?下面来跟着小编来一起探索。


7.1.1 伪随机数字

      在计算机中不可能产生出完全随机的数,产生的是一个伪随机数。就比如,我们现在写一个程序要产生随机数,但理论上我们每一次去运行程序产生的随机数是一样的。代码如下:

  int i = 0;
  while (i < 3)
  {
    int ret = rand();
    printf("%d\n", ret);
    i++;
  }
  return 0;

微信截图_20230911220314.png

微信截图_20230911220322.png

所以光用一个rand()函数不能产生一个随机数的,为了每一次进行调用的时候,返回值都不一样,所以就有了种子的概念。


7.1.2 种子

     (种子,不是bt的种子。)在前面的时候,已经介绍过了srand函数的参数是种子,作用是:使每次调用函数后,参数不同,从而使返回值都不一样。


      下面来进行手撕代码:(我们要习惯于学习和适应手撕一些库函数,以至于我们能更好的地使用它们)


7.2 用C语言来实现rand()函数和srand()函数

先来看rand()函数:这个next的数据可以随便进行乘除,我感觉无所谓。

static unsigned long int next = 1;  //将数据放在静态区中
unsigned int randX() 
{
  next = next * 1103515245 + 12345;
  return (unsigned int)(next / 65536) % 32768;
}

再来看srand()函数:

void srandX(unsigned int seed)
{
  next = seed;
}

讲完上述两个函数,接下来,进行讲述如何在电脑上真正地打印出随机数。在前面,我们每一次进行更换srand()函数的种子时,我们会发现生成的随机数再不断发生变化。而我们知道,一个变化的srand值可以对应不同的随机数值,而在电脑中,时间就是那个一直在变化的值。对于每个变化的时间,我们都有唯一的数字可以表示它,这个数字叫做时间戳(时间戳)。


7.3 time函数

      简单介绍一下这个函数,详细内容在:time函数的介绍。该函数可以返回一个时间戳(当前机器的时间与计算机起始时间的一个差值)。


      time函数的参数是一个指针,如果你不想用的话,直接写成NULL即可。其返回类型为:time_t,所以在使用time函数时需要进行强制类型转换。


srand((unsigned int)time(NULL))

time_t 是什么类型呢?


微信截图_20230911220438.png

7.4 猜数字游戏的实现(含代码)

      在学完上面如何生成随机数后,接下来,我们要将今日所学的所有内容串起来,那么就请跟随我的脚步进行学习吧!在下面的教程中,我会采用分模块的方式进行每一步的讲解,想要代码的不用担心,我会在最后将代码放上去的。由于这个程序过于简单,我们就不分多文件进行编写。


7.4.1 猜数字游戏的主体

      首先,这个游戏——猜数字,不会只进行一遍,我们需要猜好几个数字,不然的话会很没意思,这里就需要我们今天学习的循环语句进行编写。循环语句有三个,我们需要选择哪一个语句进行编写呢?我们玩游戏肯定是需要先玩一下了,管他那么多干什么,所以我们用do……while语句进行编写。


      一个游戏他需要有菜单,菜单上有几个选择,根据选择不同的选项来进行功能的使用。这是不是很像今天我们学习的分支语句,像这种选择几,就进行哪一项功能,用switch()语句就好不过了,那么经过分析以后,我们来动手编写游戏的主体吧!


7.4.1.1 猜数字函数的主体  

int main()
{
    do
    {
    //……
    //菜单和选择功能的实现
    }while();
    return 0;
}

7.4.1.2 猜数字游戏的菜单

      为了使整个程序看起来不那么乱,我们需要进行函数的编写——自定义一个函数详细地介绍函数)。需要我们在主函数中声明一下,因为玩家每猜对一个数字都可以自行选择继续游戏还是退出游戏,所以要将菜单放入循环体,以便玩家进行自由选择。

void menu()
{
  printf("*****************************\n");
  printf("********* 1. play  **********\n");
  printf("********* 0. exit  **********\n");
  printf("*****************************\n");
}

7.4.1.3 猜数字游戏的选择部分

      在这一部分中,input的取值是关键,放在while中,如果想要退出,则需要条件为假,这种设计退出程序,我们要使input为0,刚好在while中表示假,一举两得。

    do 
  {
    menu();
    printf("请选择:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      printf("请开始你的表演\n");
      game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,请重新选择:>");
      break;
    }
  } while (input);

总结:

      这一部分要好好了解一下,因为这一结构是简单游戏设计的大致思路,在之后的游戏中,小编也会使用到这个结构的,请好好消化一下!通用代码如下:

void menu()
{
  printf("*****************************\n");
  printf("********* 1. play  **********\n");
  printf("********* 0. exit  **********\n");
  printf("*****************************\n");
}
int main()
{
  int input = 0;
  srand((unsigned int)time(NULL));
  do 
  {
    menu();
    printf("请选择:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      printf("请开始你的表演\n");
      game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,请重新选择:>");
      break;
    }
  } while (input);
  return 0;
}

7.4.2 猜数字的游戏函数实现

      猜数字怎么实现呢?猜数字的实质是比大小,所以有三种情况(使用分支语句if):情况一——两者相等;情况二——前者比后者大,需要我们重新输入;情况三——前者比后者小,需要我们重新输入。所以在游戏函数主体需要死循环(只能使用while循环),只有猜对之后,才会跳出循环。

void game()
{
  //猜数字游戏的关键是获得一个随机数,用rand()函数进行获得
  //但是如果光用一个rand()函数来获取一个随机数的话,每次运行程序获得的数字是一样的
  //所以将srand()和rand()混合使用
  int ret = rand() % 100 + 1;//为了获取1~100的随机数
  int secret = 0;
  while (1)
  {
    printf("请输入数字:>");
    scanf("%d", &secret);
    if (ret == secret)
    {
      printf("恭喜你猜对了!\n");
      break;
    }
    else if (ret > secret)
      printf("猜小了,请继续!\n");
    else if(ret <secret)
      printf("猜大了,请继续!\n");
  }
}

    在完成这个游戏后,我们可以将这个游戏的难度进行上升,就只能猜一定的次数,我们需要进阶函数代码。进阶代码如下:

void game()
{
    int count = 0;
  int ret = rand() % 100 + 1;
  int secret = 0;
  while (1)
  {
    printf("请输入数字:>");
    scanf("%d", &secret);
        if(count > 5)
        {
            printf("抱歉,次数已用完,请重新玩游戏!\n");
            count = 0;
        }
    if (ret == secret && count <= 5)
    {
      printf("恭喜你猜对了!\n");
      break;
    }
    else if (ret > secret)
        {
            count++;
      printf("猜小了,请继续!\n");
        }
    else if(ret <secret)
        {
            count++;
      printf("猜大了,请继续!\n");
        }
  }
}

7.4.3 猜数字游戏的所有代码

#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()
{
  //猜数字游戏的关键是获得一个随机数,用rand()函数进行//获得
  //但是如果光用一个rand()函数来获取一个随机数的话,每//次运行程序获得的数字是一样的
  //所以将srand()和rand()混合使用
  int ret = rand() % 100 + 1;
  int secret = 0;
  while (1)
  {
    printf("请输入数字:>");
    scanf("%d", &secret);
    if (ret == secret)
    {
      printf("恭喜你猜对了!\n");
      break;
    }
    else if (ret > secret)
      printf("猜小了,请继续!\n");
    else if(ret <secret)
      printf("猜大了,请继续!\n");
  }
}
int main()
{
  int input = 0;
  srand((unsigned int)time(NULL));
  do 
  {
    menu();
    printf("请选择:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      printf("请开始你的表演\n");
      game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,请重新选择:>");
      break;
    }
  } while (input);
  return 0;
}

总结:

      本次小编详细地介绍了分支语句和循环语句以及分支语句和循环语句的易错点,但分支语句和循环语句的易错点应该不是很完善,有详细的写出了猜数字游戏的代码,愿各位大佬进行批评和指正,请受下小弟一拜。

相关文章
|
14天前
|
C语言
【C语言程序设计——循环程序设计】枚举法换硬币(头歌实践教学平台习题)【合集】
本文档介绍了编程任务的详细内容,旨在运用枚举法求解硬币等额 - 循环控制语句(`for`、`while`)及跳转语句(`break`、`continue`)的使用。 - 循环嵌套语句的基本概念和应用,如双重`for`循环、`while`嵌套等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台将对编写的代码进行测试,并给出预期输出结果。 5. **通关代码**:提供完整的代码示例,帮助理解并完成任务。 6. **测试结果**:展示代码运行后的实际输出,验证正确性。 文档结构清晰,逐步引导读者掌握循环结构与嵌套的应用,最终实现硬币兑换的程序设计。
44 19
|
14天前
|
算法 C语言
【C语言程序设计——循环程序设计】求解最大公约数(头歌实践教学平台习题)【合集】
采用欧几里得算法(EuclideanAlgorithm)求解两个正整数的最大公约数。的最大公约数,然后检查最大公约数是否大于1。如果是,就返回1,表示。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。作为新的参数传递进去。这个递归过程会不断进行,直到。有除1以外的公约数;变为0,此时就找到了最大公约数。开始你的任务吧,祝你成功!是否为0,如果是,那么。就是最大公约数,直接返回。
67 18
|
14天前
|
Serverless C语言
【C语言程序设计——循环程序设计】利用循环求数值 x 的平方根(头歌实践教学平台习题)【合集】
根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码,求解出数值x的平方根;运用迭代公式,编写一个循环程序,求解出数值x的平方根。注意:不能直接用平方根公式/函数求解本题!开始你的任务吧,祝你成功!​ 相关知识 求平方根的迭代公式 绝对值函数fabs() 循环语句 一、求平方根的迭代公式 1.原理 在C语言中,求一个数的平方根可以使用牛顿迭代法。对于方程(为要求平方根的数),设是的第n次近似值,牛顿迭代公式为。 其基本思想是从一个初始近似值开始,通过不断迭代这个公式,使得越来越接近。
44 18
|
14天前
|
C语言
【C语言程序设计——循环程序设计】统计海军鸣放礼炮声数量(头歌实践教学平台习题)【合集】
有A、B、C三艘军舰同时开始鸣放礼炮各21响。已知A舰每隔5秒1次,B舰每隔6秒放1次,C舰每隔7秒放1次。编程计算观众总共听到几次礼炮声。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。开始你的任务吧,祝你成功!
44 13
|
14天前
|
存储 C语言
【C语言程序设计——循环程序设计】利用数列的累加和求 sinx(头歌实践教学平台习题)【合集】
项的累加和,一般会使用循环结构,在每次循环中计算出当前项的值(可能基于通项公式或者递推关系),然后累加到一个用于存储累加和的变量中。在C语言中推导数列中的某一项,通常需要依据数列给定的通项公式或者前后项之间的递推关系来实现。例如,对于一个简单的等差数列,其通项公式为。的级数,其每一项之间存在特定的递推关系(后项的分子是其前项的分子乘上。,计算sinx的值,直到最后一项的绝对值小于。为项数),就可以通过代码来计算出指定项的值。对于更复杂的数列,像题目中涉及的用于近似计算。开始你的任务吧,祝你成功!
31 6
|
14天前
|
C语言
【C语言程序设计——循环程序设计】鸡兔同笼问题(头歌实践教学平台习题)【合集】
本教程介绍了循环控制和跳转语句的使用,包括 `for`、`while` 和 `do-while` 循环,以及 `break` 和 `continue` 语句。通过示例代码详细讲解了这些语句的应用场景,并展示了如何使用循环嵌套解决复杂问题,如计算最大公因数和模拟游戏关卡选择。最后,通过鸡兔同笼问题演示了穷举法编程的实际应用。文中还提供了编程要求、测试说明及通关代码,帮助读者掌握相关知识并完成任务。 任务描述:根据给定条件,编写程序计算鸡和兔的数量。鸡有1个头2只脚,兔子有1个头4只脚。
40 5
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
89 5
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
63 1
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
83 1

热门文章

最新文章