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

目录

前言

1.大致思路

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

2.1函数

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

2.1.2 C语言函数的定义

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

库函数

2.开始菜单

自定义函数

最后


前言

  想玩一个数字范围在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函数:

2e7b9f90dabf459eb36ae9546c853e07.png

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

上图中我们计算的是两个数的和,需要返回整数,所以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切换到旧版本,在搜索框中输入函数名称查找)

49f381eea6ee45219548fa36e2dfca1a.png

接下来我们用一下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;
}

第一次运行结果:

b311b35014c347f395af5da53c2b7bdf.png

 第二次运行结果:

b1122c96f1d74684b303020bd9dd80d2.png

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

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

2558e9944b1a44eb82d207daaae26a48.png

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

dd822946d3704d94892f17829733e41b.png

 e535189910f240288bb6506b2b3d77b0.png

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

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

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

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

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

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

ce7d9c0f1701483c863f56582bde065f.png

 什么是时间戳?见下图:

8b2d2afeb3ba41e2922abba2790716b3.png

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

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

结果展示:

22ed1ee476734bf1bf8eccd2552934d9.png

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函数:

52fe8be39dc546fbbc0e007ad5a5eed6.png

 完整代码:

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

最后

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

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值