数组

数组

1.数组的定义

在程序中,经常需要对一批数据进行操作,例如,统计某个公司100个员工的平均工资。如果使用变量来存放这些数据,就需要定义100个变量,显然这样做很麻烦,而且很容易出错。这时,可以使用x[0]、x[1]、x[2]……x[99]表示这100个变量,并通过方括号中的数字来对这100个变量进行区分。

在程序设计中,使用x[0]、x[1]、x[2]……x[n]表示的一组具有相同数据类型的变量集合称为数组x,数组中的每一项称为数组的元素,每个元素都有对应的下标(n),用于表示元素在数组中的位置序号,该下标是从0开始的。

2.一维数组

1)一维数组的定义与初始化

一维数组指的是只有一个下标的数组,它用来表示一组具有相同类型的数据。在C语言中,一维数组的定义方式如下所示:

类型说明符  数组名[常量表达式];

在上述语法格式中,类型说明符表示数组中所有元素的类型,常量表达式指的是数组的长度,也就是数组中存放元素的个数。

例如:

int array[5];

上述代码定义了一个数组,其中,int是数组的类型,array是数组的名称,方括号中的5是数组的长度。

完成数组的定义后,只是对数组中的元素开辟了一块内存空间。这时,如果想使用数组操作数据,还需要对数组进行初始化。数组初始化的常见的方式有三种,具体如下:

(1)直接对数组中的所有元素赋值,示例代码如下:

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

(2)只对数组中的一部分元素赋值,示例代码如下:

   int i[5]={1,2,3};

在上述代码中,定义了一个int类型的数组,但在初始化时,只对数组中的前三个元素进行了赋值,其它元素的值会被默认设置为0。

(3)对数组全部元素赋值,但不指定长度,示例代码如下:

   int i[]={1,2,3,4};

在上述代码中,数组i中的元素有4个,系统会根据给定初始化元素的个数定义数组的长度,因此,数组i的长度为4。

注意:

1、数组的下标是用方括号括起来的,而不是圆括号。

2、数组名的命名同变量名的命名规则相同。

3、数组定义中,常量表达式的值可以是符号常量,例如下面的定义是合法的。

2)一维数组的引用

在程序中,经常需要访问数组中的一些元素,这时可以通过数组名和下标来引用数组中的元素。一维数组元素的引用方式如下所示:

数组名[下标];

在上述方式中,下标指的是数组元素的位置,数组元素的下标是从0开始的。例如,引用数组x的第三个元素的方式x[2]。

例5-1
 #include<stdio.h>
 void main(int argc,char *argv[])
 {
 	int x[5] = { 2, 3, 1, 4, 6 };
 	int i;
 	for ( i= 0; i < 5; i++)
 	{
 		printf("%d\n",2*x[i]);
 	} 

在例5-1中,首先定义了一个数组x,然后通过下标的形式获取到数组中的元素,最后将元素乘以2后输出。

注意:

数组的下标都有一个范围,即“0~[数组长度-1]”,假设数组的长度为6,其下标范围为0~5。当访问数组中的元素时,下标不能超出这个范围,否则程序会报错。

  • 一维数组定义与使用

    	int array[10];//定义一个一维数组,名字叫array,一共有10个元素,每个元素都是int类型的
    
    	array[0] = 20;
    	array[1] = 30;
    	array[9] = 80;
    	//array[10] = 100;//错误,没有 array[10]这个元素
    
  • 数组在内存的存储方式
    数组在内存中是一段连续的空间,每个元素的类型都是一样的.

  • 一维数组初始化

    int array[10] = { 100, 1, 5, 3, 4, 5, 6, 7, 8, 0 };//定义数组的同时为数组的成员初始化值
    int array[10] = { 3, 7, 9 };//将数组的前三个元素赋值,其余元素置为0
    int array[10] = { 0 };//将数组所有的元素都置为0
    	int i;
    	for (i = 0; i < 10; i++)
    	{
    		array[i] = 0;//通过循环遍历数组的每个元素,将元素的值置为0
    	}
    
3)一维数组的常见操作

数组在编写程序时应用非常广泛,如经常需要对数组进行遍历、获取最值、排序等操作,灵活地使用数组对实际开发很重要。接下来针对一维数组的常见操作进行详细地讲解,具体如下:

(1)一维数组的遍历

在操作数组时,经常需要依次访问数组中的每个元素,这种操作称作数组的遍历。接下来使用for循环依次遍历数组中的元素,如例5-2所示。

例5-2
 1#include <stdio.h>
 2void main(int argc, char* argv[])
 3{
 4	int x[5] = { 1, 2, 3, 4, 5 };
 5	int i = 0;
 6	for (i = 0; i < 5; i++)
 7	{
 8		printf("x[%d]:%d\n", i, x[i]);
 9	} 
 10}

在例5-2中,首先定义了一个长度为5的数组x,然后定义了一个变量i,由于数组的下标范围为0~4,因此可以将i的值作为下标,依次去访问数组中的元素,并将元素的值输出。

(2)一维数组的最值

在操作数组时,经常需要获取数组中元素的最值。接下来通过一个案例来演示如何获得数组中的最大值,如例5-3所示。

例5-3
 1#include <stdio.h>
 2int main(int argc, char* argv[])
 3{
 4	int x[5] = {1,2,3,4,5};
 5	int nMax = x[0];
 6	int i = 0;
 7	for (i = 1; i < 5; i++)
 8	{
 9		if (x[i] > nMax)
 10		{
 11			nMax = x[i];
 12		}
 13	}
 14	printf("max:%d\n", nMax);
 15	return 0;
 16}

在例5-3中,实现了获取数组x最大值的功能。在第7行代码中假定数组中的第一个元素为最大值,并将其赋值给nMax,在第7~13行代码对数组中的其他元素进行遍历,如果发现比nMax值大的元素,就将最大值nMax设置为这个元素的值,这样,当数组遍历完成后,nMax中存储的就是数组中的最大值。

(3)一维数组的排序

在操作数组时,经常需要对数组中的元素进行排序。接下来为大家介绍一种比较常见的排序算法—冒泡排序。在冒泡排序的过程中,不断地比较数组中相邻的两个元素,较小者向上浮,较大者往下沉,整个过程和水中气泡上升的原理相似,接下来,分步骤讲解冒泡排序的整个过程,具体如下:

第一步,从第一个元素开始,将相邻的两个元素依次进行比较,直到最后两个元素完成比较。如果前一个元素比后一个元素大,则交换它们的位置。整个过程完成后,数组中最后一个元素自然就是最大值,这样也就完成了第一轮的比较。

第二步,除了最后一个元素,将剩余的元素继续进行两两比较,过程与第一步相似,这样就可以将数组中第二大的数放在倒数第二个位置。

第三步,依次类推,持续对越来越少的元素重复上面的步骤,直到没有任何一对元素需要比较为止。

了解了冒泡排序的原理之后,接下来通过一个案例来实现冒泡排序,如例5-4所示。

例5-4
 1#include <stdio.h>
 2void main(int argc, char ** argv[])
 3{
 4	int x[5] = { 9, 8, 3, 5, 2 };
 5	int m = 0, n = 0;
 6	int nTemp = 0;
 7	int i = 0;
 8	printf("冒泡排序前:\n");
 9	for (i = 0; i < 5; i++)
 10	{
 11		printf("%d	", x[i]);
 12	}
 13	printf("\n");
 14	for (m = 0; m < 5 - 1; m++)
 15	{
 16		for (n = 0; n < 5 - 1 - m; n++)
 17		{
 18			if (x[n] > x[n + 1])
 19			{
 20				nTemp = x[n];
 21				x[n] = x[n + 1];
 22				x[n + 1] = nTemp;
 23			}
 24		}
 25	}
 26	printf("冒泡排序后:\n");
 27	for (i = 0; i < 5; i++)
 28	{
 29		printf("%d	", x[i]);
 30	}
 31	printf("\n");
 32}
运行结果:
    冒泡排序前:
    9 8 3 5 2
    冒泡排序后:
    2 3 5 8 9
    

在例5-4中,通过嵌套for循环实现了冒泡排序。其中,外层循环用来控制进行多少轮比较,每一轮比较都可以确定一个元素的位置,由于最后一个元素不需要进行比较,因此,外层循环的次数为数组的长度-1,内层循环的循环变量用于控制每轮比较的次数,在每次比较时,如果前者小于后者,就交换两个元素的位置。当元素交换时,会通过一个中间变量temp记住arr[j],然后将arr[j+1]赋给arr[j],最后再将temp赋给arr[j+1

3.二维数组

1)二维数组的定义与初始化

在实际的工作中,仅仅使用一维数组是远远不够的,例如,一个学习小组有5个人,每个人有三门课的考试成绩,如果使用一维数组解决是很麻烦的。这时,可以使用二维数组,二维数组的定义方式与一维数组类似,其语法格式如下:

类型说明符 数组名[常量表达式1][常量表达式2];

在上述语法格式中,“常量表达式1”被称为行下标,“常量表达式2”被称为列下标。

例如,定义一个3行4列的二维数组,具体如下:

 int a[3][4];

在上述定义的二维数组中,共包含3*4个元素,即12个元素。

二维数组a是按行进行存放的,先存放a[0]行,再存放a[1]行、a[2]行,并且每行有四个元素,也是依次存放的。

完成二维数组的定义后,需要对二维数组进行初始化,初始化二维数组的方式有四种,具体如下:

(1)按行给二维数组赋初值。例如:
int a[2][3] = {{1,2,3},{4,5,6}};

在上述代码中,等号后面有一对大括号,大括号中的第一对括号代表的是第一行的数组元素,第二对括号代表的是第二行的数组元素。

(2)将所有的数组元素按行顺序写在一个大括号内。例如:
int a[2][3] = {1,2,3,4,5,6};

在上述代码中,二维数组a共有两行,每行有三个元素,其中,第一行的元素依次为1、2、3,第二行元素依次为4、5、6。

(3)对部分数组元素赋初值。例如:
int b[3][4] = {{1},{4,3},{2,1,2}};

在上述代码中,只为数组b中的部分元素进行了赋值,对于没有赋值的元素,系统会自动赋值为0。

(4)如果对全部数组元素置初值,则二维数组的第一个下标可省略,但第二个下标不能省略。

例如:

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

可以写为

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

系统会根据固定的列数,将后边的数值进行划分,自动将行数定位2。

  • 二维数组定义与使用

    int array[2][3];//定义了一个二维数组,有两个array[3]
    
  • 二维数组初始化

    int a[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
    
    2)二维数组的引用

二维数组的引用方式同一维数组的引用方式一样,也是通过数组名和下标的方式来引用数组元素,其语法格式如下:

数组名[下标][下标];

在上述语法格式中,下标值应该在已定义的数组的大小范围内,例如下面这种情况是错误的。

int a[3][4];  // 定义a为3行4列的二维数组
a[3][4]=3;    // 对数组a第3行第4列元素赋值,出错

在上述代码中,数组a可用的行下标范围是02,列下标是03,a[3][4]超出了数组的下标范围。

为了帮助读者更好地掌握二维数组的引用,接下来,通过一个案例来演示二维数组的遍历,如例5-5所示。

例5-5
 1#include<stdio.h>
 2void main()
 3{
 4	//声明并初始化数组
 5	int array[3][4] = { {1,2,3,4 }, {5,6,7,8}, {9,10,11,12} };
 6	for (int i = 0; i < 3; i++) //循环遍历行
 7	{
 8		for (int j = 0; j < 4; j++) //循环遍历列
 9		{
 10			printf("[%d][%d]: %d ", i, j, array[i][j]);
 11		}
 12		printf("\n");//每一行的末尾添加换行符
 13	}
 14}

在例5-5中,定义了一个二维数组array,该数组有3行4列。当使用嵌套for循环遍历二维数组元素时,外层for循环用于变量数组的行元素,内层for循环用于遍历数组的列元素。从图5-10中可以看出,程序依次将数组array中的元素输出了。

3)二维数组的引用

熟悉了二维数组的定义和引用,接下来定义一个二维数组StuScore[5][3],用来存放5名同学3门课程的成绩,并定义变量m表示学生,n表示第几门成绩,aver表示每名同学3门课程的平均成绩,sum表示每名同学3门课的总成绩,具体如例5-6所示。

例5 - 6
1#include <stdio.h>
2void main(int argc, char * argv[])
3{
	int StuScore[5][3] = {
			//张同学
			{ 88, 70, 90 },
			//王同学
			{ 80, 80, 60 },
			//李同学
			{ 89, 60, 85 },
			//赵同学
			{ 80, 75, 78 },
			//周同学
			{ 70, 80, 80 }
	 };
		int m = 0, n = 0;
		int nStuTotalScore;
	int nMathTotalScore = 0;
		int nChineseTotalScore = 0;
		int nEnglishTotalScore = 0;
	printf("个人总成绩:\n");
		for (m = 0; m < 5; m++)
			{
				nStuTotalScore = 0;
			for (n = 0; n < 3; n++)
			{
					nStuTotalScore += StuScore[m][n];
					switch (n)
					{
					case 0:
								{
									nMathTotalScore += StuScore[m][0];
									}
					case 1:
								{
										nChineseTotalScore += StuScore[m][1];
								break;
								}
					case 2:
								{
									nEnglishTotalScore += StuScore[m][2];
								}
							}
					}
				switch (m)
					{
				case 0:
						{
								printf("张同学:%d\n", nStuTotalScore);
							break;
							}
				case 1:
						{
								printf("王同学:%d\n", nStuTotalScore);
								break;
							}
				case 2:
			{
							printf("李同学:%d\n", nStuTotalScore);
								break;
							}
				case 3:
						{
								printf("赵同学:%d\n", nStuTotalScore);
								break;
						}
				case 4:
						{
								printf("周同学:%d\n", nStuTotalScore);
						break;
							}
					}
			}
		printf("小组数学总分:%d	小组数学平均分:%.2f\n",
		76		nMathTotalScore, (double)nMathTotalScore / 5);
		printf("小组语文总分:%d	小组语文平均分:%.2f\n",
				nChineseTotalScore, (double)nChineseTotalScore / 5);
		printf("小组英语总分:%d	小组英语平均分:%.2f\n",
				nEnglishTotalScore, (double)nEnglishTotalScore / 5);
	}

例5-6中实现了计算小组各科平均分的功能。其中,第415行代码定义了一个二维数组,用来存储小组中每个成员的各科成绩。第2545行代码通过遍历列下标获取每个小组不同学科的总分,第46~74行代码通过遍历行下标获取每个小组成员的总分,最后将小组不同学科的总分和平均分输出。

4.多维数组

在计算机中,除一维数组和二维数组外,还有三维,四维,……等多维数组,它们用在某些特定程序开发中,多维数组的定义与二维数组类似,其语法格式具体如下:

数组类型修饰符 数组名 [n1][n2]…[nn];

定义一个三维数组的示例代码如下:

int x[3][4][5];

上面的这个例子,定义了一个三维数组,数组的名字是x,数组的长度为3,每个数组的元素又是一个二维数组,这个二维数组的长度是4,并且这个二维数组中的每个元素又是一个一维数组,这个一维数组的长度是5,元素类型是int。

posted @ 2020-09-27 20:29  星卅  阅读(369)  评论(0)    收藏  举报