今天我们来讲解C语言中的数组。
什么是数组所谓数组,就是相同数据类型的元素按一定顺序排列的集合,把有限个类型相同的变量用一个名字命名,然后用编号区分他们。这个名字称为数组名,编号称为下标。
——摘自百度百科
说到数组,我们很容易联想到数学中的数列问题。我们知道,一个数列,就是一个一个数字依次排列而成的数据集合,例如:
整数数列A:
1,3,5,7,9
我们给这个数列的数字依次编号:
A0,A1,A2,A3,A4
编号Ax,对应的就是这个数列第x个位置的数据:
A0=1,A1=3,A2=5,A3=7,A4=9
通过数列的例子,我们可以简单的理解什么是“数组”——有限数量的、按编号依次存放的、相同类型的数据集合。这里有几个关键点:
①有限数量:一个数组的数据数量是有限的,在建立一个数组时,我们需要规定它的数据数量,这样电脑才知道要分配多大的空间来存放这些数据。
②按编号依次存放:就像刚刚的数列一样,我们要给数组中的每个数据依次编号“0,1,2,3……”,特别要注意的是,数组的编号一定是从“0”开始。
③相同类型:一个数组里的数据,类型一定是相同的。例如一个int型的数组,里面的数据必须都是int类型。
数组是一种基础的、常见的数据结构,当我们在处理相同类型的大量数据时,使用数组能够方便代码编写,提高程序的执行效率。
一维数组的操作物理学上有“一维空间”、“二维空间”、“三维空间”,数学上也有“数列”、“矩阵”等等。数组也一样,可以有“一维数组”、“二维数组”甚至更高维的数组。
我们今天先学习最简单的一维数组。掌握了它,后面再学习多维数组,就更容易理解了。
刚才在理解数组时,我们举了数列的例子。
整数数列A:
1,3,5,7,9
我们发现,这个数列由5个整数构成。如果我们使用“数组”这种数据结构来存储这个数列,应该怎么做呢?先来看代码:
//定义一个长度为5的整型数组
inta[5];
//分别给数组里的每个元素赋值
a[0]=1;
a[1]=3;
a[2]=5;
a[3]=7;
a[4]=9;
①定义数组
定义数组,就是告诉计算机“我需要创建一个什么类型的数组,它的名字是什么,有多少个元素,并且给它分配足够的内存空间”。在我们使用一个数组前,必须经过这一步,才能把数组给建立起来。
格式:
数据类型数组名称[数组大小];
数据类型,就是基本的变量类型,例如int、float、doubul、char等等。
数组名称,就像是变量名称一样,是我们给数组取的名字。
英文中括号里的数组大小,是一个正整数,代表了这个数组拥有多少个元素。
例如我们刚才的“inta[5];”就是创建了一个名叫“a”的数组,它的数据类型是int,元素数量是5。执行了这句代码,电脑就在内存中划出了5个连续的格子,编号分别是0、1、2、3、4,我们可以往里面存入int类型的数据。
a[0]
a[1]
a[2]
a[3]
a[4]
②数组元素的赋值:往数组的具体某个格子中存放数据
经过第一步,我们建立了一个数组,但电脑只是划分了这么几个格子给我们,它们里面还没有任何数据(甚至有可能存在以前残留的垃圾数据),这时我们就需要往这些格子里放入我们想存放的内容。
这一步,和之前普通变量的赋值很相似。
以前我们学到,普通变量的赋值是这么做的:
intx;
x=1;
具体某个数组元素的赋值,只不过是把“变量名”,换成了“数组名[下标]”而已。
例如:
a[0]=1;
所谓的下标,就是数组元素的编号,从0开始,不能超出数组的范围。例如刚才a数组有5个元素,下标就是0,1,2,3,4。如果我们试图操作a[5],超出了它的范围,程序就崩溃了。
不仅是赋值,数组元素的使用,和变量的使用完全相似,我们可以把任何“数组名[下标]”当作单个的变量一样去操作。
举例如下(随意举的例子,主要看书写格式,代码无实际意义):
intx=a[0]+a[4];
scanf("%d",a[0]);
if(a[0]0){
printf("%d",a[0]);
}
③数组的数据初始化的简便方法
在之前的例子中,我们用了五行代码,分别给a数组的五个元素进行赋值。看起来很麻烦。有没有更简便的方法呢?
当然有。我们可以在定义数组的同时,进行数组的初始化。如:
inta[5]={1,3,5,7,9};
此处将各个元素的初始值,按顺序放在花括号里面,数据间用英文逗号隔开。这一句代码,就相当于刚才那一长串样例代码的效果,使得a[0]=1;a[1]=3;a[2]=5;a[3]=7;a[4]=9;
一维数组的应用我们同样可以使用循环来进行数组的赋值。
假设我们要得到长度为10的整型递增数列:
0,1,2,3,4,5,6,7,8,9
可以用循环实现:
inti;
inta[10];//定义一个长度为10的int数组
//让i从0循环到9
for(i=0;i10;i++){
a[i]=i;//给第i个元素赋值
}
此处的i,依次从0循环到9,而a[i]=i;这句代码,就分别代表了“a[0]=0;”、“a[1]=1;”、“a[2]=2;”……“a[9]=9;”。使用循环来操纵数组,更加简便、直观。假如我们有成千上万个数据需要处理,肯定需要借助循环的力量。
接下来再看一道例题,用数组来处理斐波那契(Fibonacci)数列问题:
斐波那契数列,首先规定a[0]=0,a[1]=1。此后每个数据分别是前两个数据之和。
a[2]=a[1]+a[0]=1+0=1
a[3]=a[2]+a[1]=1+1=2
a[4]=a[3]+a[2]=2+1=3
代码可以这么处理:
inti;
inta[30];//假设我们需要计算斐波那契数列的前30位
//规定前两个数字是0和1
a[0]=0;
a[1]=1;
//从2循环到29
for(i=2;i30;i++){
//根据规则计算第i个元素的值
a[i]=a[i-1]+a[i-2];
}
//从0循环到29
for(i=0;i30;i++){
//输出每个元素的值
printf("%d",a[i]);
}
在这两个例子中,假如我们不使用数组,其实也能计算出需要的数列,但会更加麻烦,并且无法在内存中保存这些数据。使用了数组,能使我们处理问题更加方便,并且能把数据储存在内存中,以供后续使用。
接下来再看一个例子,让用户输入五个数字,我们根据这五个数字,分别输出五排星星,每排星星的数量和输入的数字相同。这个问题更清晰的体现出数组的价值:把用户输入的五个数字存起来,后续再读取这五个数字,输出对应的星星。
intnum[5];
inti,j;
//从0循环到4,让用户输入每个元素的值
for(i=0;i5;i++){
scanf("%d",num[i]);
//读取第i个数据
}
//从0循环到4,根据每个元素的值输出星星
for(i=0;i5;i++){
//输出num[i]里的数据值
printf("%d",num[i]);
//循环的次数就是num[i]里的数据值
for(j=0;jnum[i];j++){
printf("*");
//输出一个星星
}
printf("\n");//换行
}
今天的内容就是这些,我们学习了数组的概念,以及一维数组的定义和应用。接下来小编要布置作业啦:
①定义一个长度为50的整型数组,存入数列2、4、6、……、98、,然后输出。
②让用户输入3个数字,分别用星号打印出3个对应边长的正方形。