函数与数组

前言:今天我们来了解一下C语言中的函数。

先来做一个猜数字游戏吧。要想猜数字,就必须产生随机数,那么我们如何利用C语言来产生随机数呢?接下来就让我们来学习产生随机数的几个函数吧。

1 rand 函数

. C语言提供了一个rand函数可以产生随机数,但是rand函数产生的这个随机数是一个伪随机数,随机数的范围在0~RAND_MAX之间,RAND_MAX的大小是依赖于编译器实现的,大部分的编译器RAND_MAX为32767

. rand函数头文件stdlib.h

形式如下:

int rand(void);//int表示返回类型,void表示这个函数不需要参数

我们先来用这个函数演示一下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	return 0;
}

结果展示:
在这里插入图片描述
在这里插入图片描述
这里,我们将程序运行了两遍,可以清楚地看到,两次结果是一摸一样的,所以我们说这是一个伪随机数伪随机数不是真正的随机数,是依赖于某种算法实现的

这又是为什么呢?这是因为rand函数想生成真正的随机数是需要依赖于种子的,而rand函数默认种子是1。因此要想生成真正的随机数就要让种子发生变化。

2 srand 函数

. C语言又提供了一个srand函数,用来初始化随机数的生成器的,调用rand函数之前先调用srand函数,通过srand函数参数的seed来设置rand函数生成随机数时候的种子,也就是说只要种子是变化的,那么就能生成随机数了。可是我们本来就要生成随机数,现在又要让种子随机变化,这不是别扭了吗?

形式如下:

void srand(unsigned int seed);

3 time 函数

. 我们一般使用程序的运行时间作为种子,因为时间是一直在发生变化的。C语言中有一个time函数,就可以获得时间。time函数会返回当前的日历时间,其实返回的是1970年1月1日0时0秒到现在程序运行时间之间的差值,单位是秒,返回类型是time_t类型,time_t类型本质上是32位或者是64位的整型类型。

. time函数的参数如果是非NULL的话,函数会将返回的差值放在timer指向的内存中带回去

. 如果timer是NULL,就只返回这个时间的差值,time函数返回的这个时间差就叫做时间戳

. time函数头文件time.h

形式如下:

time_t time(time_t* timer);

现在我们就可以来实现猜数字游戏了。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define FIGURE 100
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	int guess = rand() % FIGURE + 1;
	int count = 5;
	while (count)
	{
		printf("你还有%d次机会\n", count);
		printf("请输入数字:>>");
		scanf("%d", &input);
		if (input == guess)
		{
			printf("恭喜你,猜对了\n");
			break;
		}
		else if (input < guess)
		{
			printf("猜小了\n");
		}
		else
		{
			printf("猜大了\n");
		}
		count--;
	}
	if (count == 0)
	{
		char ch[20] = { 0 };
		printf("请注意,你的电脑将在60秒后关机,如果想要取消关机,请输入我是猪\n");
		system("shutdown -s -t 60");
		while (1)
		{
			printf("请输入:>>");
			scanf("%s", ch);
			if (strcmp(ch, "我是猪") == 0)
			{
				system("shutdown -a");
				break;
			}
			else
			{
				printf("臭小子,乱输入什么呢!回去重新输入\n");
			}
		}
	}
	return 0;
}

4 一维数组

在学习一维数组之前,我们先来学习什么是数组

数组的概念一组相同类型元素的集合

. 数组元素的个数不能为0

. 数组中存放多个数据,类型是相同的

数组的分类:

一维数组type name[常量值](形式)

多维数组:多维数组一般比较常见的是二维数组
type name[常量值1][常量值2](形式)

. type指数组中存放数据的类型可以是float,int,char,short等。

. name指数组名,名字有意义就可以。

. 常量值指数组的大小,根据实际需求指定

比如说,我们想要存放20名同学的数学成绩,就可以创建一个数组

int math[20];

. 数组的初始化:有时候在创建数组的时候,我们需要给定一些初始值,这就叫做初始化

//完全初始化
int arr1[5]={1,2,3,4,5};
//不完全初始化,第一个元素初始化为10,剩余元素默认为0
int arr2[5]={10};

. 数组的类型:数组也是有类型的,算是一种自定义类型,去掉数组名剩下的就是数组类型

int arr[10]={1,2,3,4,5};//int [10]就是数组类型

. 数组下标

C语言规定数组是有下标的下标从0开始,假设数组有n个元素,最后一个元素的下标是n-1

int arr[10]={1,2,3,4,5,6,7,8,9,10};

在这里插入图片描述
数组的访问提供了一个操作符[ ],这个操作符叫做:下标引用操作符

这样我们就可以访问数组了。

#include<stdio.h>
int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	printf("%d\n",arr[5]);
	return 0;
}

运行结果

6

. 一维数组在内存中的存储

#include<stdio.h>
int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	int i = 0;
	for(i=0;i<10;i++)
	{
		printf("&arr[%d]=%p\n",i,&arr[i]);
	}
	return 0;
}

在这里插入图片描述

数组随着下标的增长,地址由低到高,并且每相邻的两个元素之间相差4(因为一个整形是4个字节),所以数组在内存中是连续存放的,这就为我们后期使用指针访问数组奠定了基础

5 sizeof 计算数组大小

#include<stdio.h>
int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	printf("%d\n",sizeof(arr));
	return 0;
}

运行结果

40

这里计算的是数组所占空间的总大小,单位是字节。又因为数组中数组元素的类型是一样的,那么只要计算出一个数组元素占几个字节,数组元素的个数就可以计算出来

#include<stdio.h>
int main()
{
	int arr[10]={0};
	int sz=sizeof(arr)/sizeof(arr[0]);
	printf("%d\n",sz);
	return 0;
}

运行结果

10

6 二维数组

形式:type name[常量值1][常量值2]

int arr[3][5];

3表示数组有3行;
5表示每行有5个元素;
int表示每个元素都是整型类型;
arr表示数组名

. 二维数组的初始化

. 不完全初始化

int arr1[3][5]={1,2};
int arr2[3][5]={0};

在这里插入图片描述
在这里插入图片描述

. 完全初始化

int arr3[3][5]={1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};

在这里插入图片描述

. 按照行初始化

int arr4[3][5]={{1,2},{3,4},{5,6}};

在这里插入图片描述
注意:二维数组初始化时可以省略行但不可以省略列

. 二维数组的下标

C语言规定二维数组的行是从0开始的,列也是从0开始的

#include<stdio.h>
int main()
{
	int arr[3][5]={1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};
	printf("%d\n",arr[2][3]);
	return 0;
}

运行结果

6

. 二维数组在内存中的存储

#include<stdio.h>
int main()
{
	int arr[2][3]={1,2,3,4,5,6};
	int i = 0;
	for(i=0;i<2;i++)
	{
		int j = 0;
		for(j=0;j<3;j++)
		{
			printf("&arr[%d][%d]=%p\n",i,j,&arr[i][j]);
		}
	}
	return 0;
}

在这里插入图片描述
可以看到,每一行内部的每个相邻元素之间差4个字节,跨行位置处的元素也是差4个字节。所以二维数组在内存中也是连续存放的有利于后期使用指针访问数组

7 变长数组

在C99标准之前,C语言在创建数组的时候,数组大小的指定只能使用常量,常量表达式。但是这样不够灵活。C99中给一个变长数组,允许使用变量来指定数组大小

. 变长数组的根本特征数组长度只有在运行时才能确定,所以变长数组不能初始化

. 变长数组的意思是数组的大小是可以使用变量来指定的,在程序运行的时候根据变量的大小来指定数组元素的个数,而不是说数组的大小是可变的。数组的大小一旦确定就不能再变化了。

形式

int arr[n];//这里n是一个变量

练习:演示多个字符从两边向中间汇聚

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[]="******************";
	char arr2[]="welcome to bite!!!";
	int left = 0;
	int right = (int)strlen(arr2)-1;
	while(left<=right)//当left<=right时,说明还有字符需要移动,因此作为循环条件
	{
		arr1[left]=arr2[left];
		arr1[right]=arr2[right];
		printf("%s\n",arr1);
		left++;
		right--;
	}
	return 0;
}

运行结果

在这里插入图片描述

  • 29
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值