初识C语言3——函数(以猜数字游戏为例)

简介: 初识C语言3——函数(以猜数字游戏为例)

前言

 想玩一个数字范围在1~100的猜数字游戏,根据自己浅薄的知识怎样把这个游戏写出来呢?

 一个简单的猜数字游戏是怎样构思又怎样逐步实现的呢?接下来请允许我为大家详细介绍一下吧!

1.大致思路

 想要实现一个猜数字游戏,说简单点,最核心的部分就是先让电脑生成一个随机数,然后再让玩家输入值猜这个随机数,程序再根据玩家输入的值与这个随机数进行比较,接着再反馈给玩家一定的提示,最终使其猜出正确的数字。

2.猜数字游戏的核心部分(生成随机数

2.1函数

 想要实现以上随机数的生成,我们必须要知道C语言中的函数。

2.1.1什么是函数?(初识C语言函数的概念)

 在数学中,我们已经知道函数的概念,简单点,假如题目中给了我们一个y=2x-1的函数,当我想知道y的值时,有了这个函数,我只需知道x的值就能得出y的值。

 C语言中的函数与数学中的函数大致相似,都是由一份数据经过一定的计算或规则得到另一份数据,为什么说大致相似,是因为它们确实又有着天壤之别。

 ‘函数’的英文为function,可是function翻译成中文又有‘功能’的意思,在C语言中,把function翻译为‘功能’或许更恰当。我们知道,一个程序的实现由多个函数组成,每一个函数负责实现一定的功能,一个程序由多个函数组成,也就是说:一个程序的实现由多个小的功能叠加而实现!

2.1.2C语言函数的定义

在C语言中,函数有以下4个组成部分:

先例举一个add函数:

返回类型:一个函数可以返回一个值。

上图中我们计算的是两个数的和,需要返回整数,所以int是函数返回的值的数据类型。有些函数在执行完毕后不需要返回值,在这种情况下,返回类型就用关键字 void(空类型);

函数名称:这是函数的实际名称。如上图的‘Add’,函数名可以由我们直接来命名;

参数:参数就像是占位符。当函数被调用时,向参数传递一个值,比如上图中我们传递给Add函数一个x和y的值,x和y就是我们的参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。

函数体:函数主体包含一组定义函数执行任务的语句。

 2.1.3 函数的分类(以随机数的生成为例)

 函数分为库函数自定义函数

 那么库函数和自定义函数又是什么呢?本文以猜数字游戏的实现为基础,首先讲解库函数的概念,再自然而然就会引出自定义函数。

库函数

 在初识C语言1中我们就已经提到过printf函数和scanf函数,这两个函数就是库函数,库函数就是由C语言为我们提供的现成的函数,可以直接使用。事实上,为了我们在编写程序时提高效率,C语言在发布时就为我们封装好了许多函数,这些函数就是库函数。

  引到本文主题,比如在猜数字游戏中想要生成一个随机数,怎么来实现呢?这就需要用到一个库函数rand了,登录网站https://cplusplus.com我们查询一下rand函数的用法,如下图所示:

(https://cplusplus.com网站查找库函数使用方法:在首页点击右上角Legacy version切换到旧版本,在搜索框中输入函数名称查找)

接下来我们用一下rand函数生成随机数看一下:

#include <stdio.h>
#include <stdlib.h>//函数rand的头文件为stdlib.h
int main()
{
  int input = 1;
  while (input)
  {
    scanf("%d", &input);
    printf("%d\n", rand());
  }
  return 0;
}

第一次运行结果:

第二次运行结果:

不难发现,我们每次程序运行生成的随机数都如出一辙,这要是玩猜数字游戏,我记住了第一次程序运行的数据,后面再玩我都知道了随机数是什么,那这游戏玩的还有什么意思呢?

 那问题出在哪里了呢?怎么才能保证我每次程序运行的结果都不一样呢?我们再返回去看一下rand函数的用法:

可见在使用rand函数时,我们必须先引用srand函数对rand初始化:所以我们再在此基础上引用一下srand函数:

观察以上两个图,这时候又有问题了:每次生成的随机数好像也并不随机呀!我只有每次给srand函数传递一个不同的参数(就是上图中括号中的1与2),程序才能每次生成不同的随机数,那我想达到目的还要每次给你传递一个不同的参数吗?

 可是这就很矛盾了啊,我用这个函数就是为了生成随机数的,你还要我给你传递一个随机数,那我干脆自己生成随机数好了,还要你这个函数干嘛呢?

 这是为什么呢?我们函数用错了吗?方法不对吗?

 其实不是的,我们的思路没有问题,函数也没有用错,我们的问题已经解决一大半了:想正常生成随机数,无非就是随机传递给srand函数一个参数罢了,那又怎么随机给srand函数传参呢?

 时光如剑,日月如梭!我们在思考问题,感叹人生时,时间都在一分一秒的过去,哎呀!我们的时间一直都在变化呀!那么我们能不能把时间作为参数传递给srand呢?答案当然是可以的!

 我们再打开网站https://cplusplus.com查询一下time函数:

什么是时间戳?见下图:

  这时候我们再重新整合生成随机数的代码:

#include <stdio.h>
#include <stdlib.h>//函数rand的头文件为stdlib.h
#include <time.h>//函数time的头文件为time.h
int main()
{
  int input = 1;
  srand((unsigned)time(NULL)); //srand函数所需参数是unsigned int(无符号整型)类型
  //time函数的返回类型为time_t类型,其实质也是整型;
  //所以time函数的返回值自然而然可以用于srand函数的参数;
  //在上图中我们知道time函数不使用参数仍可以返回我们想要的值。
  //故time函数的参数我们用NULL(空指针),NULL以后会再提到,此处不再深究。
    while (input)                      
  {
    scanf("%d", &input);
    int random_num = rand() % 100 + 1;//任意数模100,余数为0~99,再加1,余数为1~100//
    printf("%d\n", random_num);
  }
  return 0;
}

以上才是正确生成随机数的方法。

生成随机数的问题我们解决了,接着玩游戏,我猜数字一下子猜不对,程序总要给我反馈帮助我猜出正确答案吧,所以游戏主体部分我们可以这样写:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
  int input = 1;
  int random_num = rand() % 100 + 1;
  //注意要把此等式放在循环外部,否则我们猜一次随机数就会变一次,
  //永远无法根据程序的反馈信息猜出正确答案!
  srand((unsigned)time(NULL)); 
  printf("请输入你猜的数字:\n");
  while (1)
  {
    scanf("%d", &input);
    if (input > random_num)
    {
      printf("猜大了,请再输入一次:\n");
    }
    else if (input < random_num)
    {
      printf("猜小了,请再输入一次:\n");
    }
    else
    {
      printf("恭喜你,猜对了!\n");
      break;
    }
  }
  return 0;
}

结果展示:

2.开始菜单

  一个稍微上档次一些的游戏当然要有开始菜单吧,想玩就进入游戏,不想玩就直接退出。

 我们就可以这样想:想玩你就输入1,程序就继续进行;不想玩你就输入0,直接退出游戏。

所以开始菜单代码我们想这样展示:

    printf("这是一个猜数字游戏,数字范围是1~100\n");
  printf("******如果你想玩,请输入数字1******\n");
  printf("如果你不想玩,请输入数字0,退出游戏\n");

接下来玩家的选择代码我们就可以用switch语句来写:

    int input = 0;
  scanf("%d", &input);
  switch (input)
  {
  case 1:
    printf("游戏开始,请输入数字:\n");
  case 0:
    printf("退出游戏\n");
  default:
    printf("选择错误,请重新选择:\n");
  }

可是我们玩完一把后还想接着玩,怎么办呢?这时就可以在此基础上加上循环语句,观察以上代码,显然用do...while循环语句最合适,就可以接着这样写:

    int input = 0;
  do
    {
     scanf("%d", &input);
     switch (input)
     {
      case 1:
       printf("游戏开始,请输入数字:\n");
       break;
      case 0:
       printf("退出游戏\n");
       break;
      default:
       printf("选择错误,请重新选择:\n");
       break;
     }            
  } while (input);
  //当输入input≠0时,结果为真,打印完对应语句继续进入循环,程序继续运行;
  //当输入input=0时,结果为假,打印完“退出游戏”直接退出循环,程序终止运行;
    //开始菜单那里为什么用1和0,最重要的用处也体现在这里了

自定义函数

上面提到了库函数的查询,那么什么是自定义函数呢?

顾名思义,自定义函数当然是我们自己来设计的函数,自定义函数和库函数一样,有函数名,返回值类型和函数参数。

当我们写一个程序需要频繁的使用一个功能,或者为了实现一个功能需要写的代码量太多了,我们不希望主函数中的代码看起来繁琐杂乱无章,这时候我们完全可以把这段代码分装成函数,每次用到这个功能时只需调用函数即可。

比如以上的生成随机数和开始菜单我们就可以分装成game函数和menu函数:

完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
{
  printf("这是一个猜数字游戏,数字范围是1~100\n");
  printf("******如果你想玩,请输入数字1******\n");
  printf("如果你不想玩,请输入数字0,退出游戏\n");
}
void game()
{
  int random_num = rand() % 100 + 1;
  int input = 0;
  while (1)
  {
    scanf("%d", &input);
    if (input > random_num)
    {
      printf("猜大了,请再输入一次:\n");
    }
    else if (input < random_num)
    {
      printf("猜小了,请再输入一次:\n");
    }
    else
    {
      printf("恭喜你,猜对了!\n");
      break;
    }
  }
}
int main()
{
  int input = 0;
  srand((unsigned)time(NULL));
  //把此句写在主函数里是为了一次程序运行只调用一次time函数,
  //无需一直给srand传参
  do
  {
    menu();//函数的调用:调用menu函数。
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      printf("游戏开始,请输入数字:\n");
      game();//调用game函数。
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,请重新选择:\n");
      break;
    }
  } while (input);
  return 0;
}

最后

函数的知识还有很多,比如函数的递归与迭代,传值调用和传址调用,本文中的猜数字游戏没有用到,先不提。后续再总结。

相关文章
|
1天前
|
C语言 开发者
C语言实现猜数字小游戏(详细教程)
C语言实现猜数字小游戏(详细教程)
|
1天前
|
存储 算法 安全
C语言实现扫雷游戏
C语言实现扫雷游戏
|
3天前
|
算法 搜索推荐 C语言
【C语言篇】深入理解指针4(模拟实现qsort函数)
【C语言篇】深入理解指针4(模拟实现qsort函数)
11 2
|
1天前
|
C语言
用C语言写定积分的通用函数:sin(x),cos(x),eX.
用C语言写定积分的通用函数:sin(x),cos(x),eX.
5 0
|
1天前
|
程序员 C语言
初识C语言之三子棋游戏
初识C语言之三子棋游戏
9 0
|
1天前
|
程序员 C语言
C语言内存函数精讲
C语言内存函数精讲
|
1天前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲
|
1天前
|
搜索推荐 C语言
深入浅出理解 C 语言中的 qsort 函数
深入浅出理解 C 语言中的 qsort 函数
|
3天前
|
存储 编译器 C语言
【C语言篇】数组和函数的实践:扫雷游戏(附源码)
【C语言篇】数组和函数的实践:扫雷游戏(附源码)
8 0
|
5月前
|
存储 C语言
C 语言函数完全指南:创建、调用、参数传递、返回值解析
函数是一段代码块,只有在被调用时才会运行。 您可以将数据(称为参数)传递给函数。 函数用于执行某些操作,它们对于重用代码很重要:定义一次代码,并多次使用。
148 3