初识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语言之斗地主游戏
该代码实现了一个简单的斗地主游戏,包括头文件引入、宏定义、颜色枚举、卡牌类、卡牌类型类、卡牌组合类、玩家类、游戏主类以及辅助函数等,涵盖了从牌的生成、分配、玩家操作到游戏流程控制的完整逻辑。
75 8
|
23天前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
47 10
|
23天前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
43 9
|
23天前
|
存储 Unix Serverless
【C语言】常用函数汇总表
本文总结了C语言中常用的函数,涵盖输入/输出、字符串操作、内存管理、数学运算、时间处理、文件操作及布尔类型等多个方面。每类函数均以表格形式列出其功能和使用示例,便于快速查阅和学习。通过综合示例代码,展示了这些函数的实际应用,帮助读者更好地理解和掌握C语言的基本功能和标准库函数的使用方法。感谢阅读,希望对你有所帮助!
33 8
|
23天前
|
C语言 开发者
【C语言】数学函数详解
在C语言中,数学函数是由标准库 `math.h` 提供的。使用这些函数时,需要包含 `#include <math.h>` 头文件。以下是一些常用的数学函数的详细讲解,包括函数原型、参数说明、返回值说明以及示例代码和表格汇总。
43 6
|
23天前
|
存储 C语言
【C语言】输入/输出函数详解
在C语言中,输入/输出操作是通过标准库函数来实现的。这些函数分为两类:标准输入输出函数和文件输入输出函数。
159 6
|
23天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
52 6
|
23天前
|
C语言 开发者
【C语言】断言函数 -《深入解析C语言调试利器 !》
断言(assert)是一种调试工具,用于在程序运行时检查某些条件是否成立。如果条件不成立,断言会触发错误,并通常会终止程序的执行。断言有助于在开发和测试阶段捕捉逻辑错误。
35 5
|
27天前
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
45 2
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
56 4