项目六 任务一 一维数组

项目六:数组

项目概述

在前面所学的任务中,所有的数据属于基本的数据类型,除此之外C语言还包含构造类型数据,构造类型的数据包含数组、以及后面我们学的结构体,本项目将要学到数组类型的讲解,将会讲解数组的概念,以及为什么会有数组类型,之后会讲解到一维数组的定义、初始化、引用以及二维数组的相关知识,最后会讲到字符数组,以及字符串的使用方式以及字符串相关的处理函数,学完本项目会对我们之后对数据处理上大大提高效率。

项目目标

掌握数组的概念

掌握一维数组的定义、初始化及使用

掌握二位数组的定义、初始化及使用

掌握字符数组和字符串的关系

掌握字符串相关的处理函数

任务一 一维数组

任务描述

在程序中,经常需要对一批数据进行操作,例如,统计我们班学生65名的总分。如果使用变量来存放这些数据,就需要定义65个变量,显然使用变量来定义的话很麻烦,让人头疼,估计半天的时间的都在定义变量了。这时,我们就可以使用数组来统一管理这些数据,及高效,又方便。那么我们的本任务就是来学习数组,这里我们将会学到数组的概念以及数组的创建、数组的初始化及一维数组的使用。

任务目标

理解数组的使用意义。

掌握一维数组的定义。

掌握一维数组的初始化。

掌握一维数组的引用。

掌握一维数组的遍历。

相关知识

6-1-1  数组的概念

在揭开数组这个什么的面纱之前,我们先来看一个这样的情形,一年2班三组有30名同学,它们的分数分别为88,53......。请问这六个人的总分是多少?平均分是多少? 请你编一个程序。

例如   一个班级30个学生,求某门课的平均分数

            float a0,a1,a2,a3,...,a29,average;

            average=(a0+a1+a2+a3+a4+...+a29)/30

用我们现有的知识肯定是要先定义一个变量然后对变量进行加法运算,传统的方案,不灵活,不能够完成数量大的需求,那么用什么之后来解决这样的问题,今天我来学习数组解决这个问题。

数组是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。

数组也是一种数据类型,是构造类型。每个数组都有一个名称,被称为数组名。数组中每个数据都有一个确定的编号,被称为数组下标(编号),通过数组名和下标就可以找到数组中指定的数据。

数组从维度上可以划分为一维数组和多维数组。在实际开发中,使用最多的是一维数组, 多维数组使用率不高。

上节提到如果改用数组,就可以这样做。

average= average+a[i];

i=0,1,2,…,29

程序得到简化

           float  a[30],average=0;

           for(i=0;i<30;i++)   average=average+a[i]

           average=average/30

其中  a是数组名,a[i]是数组元素,i是数组的下标,用下标表示数组元素之间的联系。这样使用数组来处理数据即简便又高效。

6-1-2  一维数组的定义及初始化

1.一维数组的定义(声明)

一维数组是 C 语言中最简单、常用的一类数组,与变量一样,如果想要使用一维数组那么就必须先来定义数组,在C语言中,一维数组的定义方式如下所示:

数据类型 数组名 [数组大小];

说明:

(1)其中数据类型表示数组中每个元素的数据类型。

(2)数组名,按标识符规则取名,必须符合 C 语言标识符命名规范。

(3)数组长度可以是常量、或常量表达式,例如:int a[10]和 int a[5+5]都是合法的。(4)数组的长度一旦确定,就不能修改。所以数组长度不能是变量、变量表达式。例如 int a[n]和 int a[n+10]都是错误写法。数组的元素个数,及元素的下标范围0到数组长度-1之间

例如:

int a [3];

上述代码定义了一个数组,其中,int是数组的类型,a是数组的名称,方括号中的3最多存放 3个int 数据。

以上我们完成数组的定义,并且在内存开辟了3个空间。这时,空间里还没有赋值,如果想使用数组操作数据,还需要对其进行初始化。

一维数组有两种初始化形式,静态初始化和动态初始化。

2.一维数组静态初始化

在定义数组的时候直接对数组进行赋值,这种方式叫做数组的静态初始化。

例如:

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

注意:在静态初始化话的过程中,可以只对数组的部分元素赋值,例如int a[3]={1,2},另外在 C 语言中,对数组进行静态初始化时,可以不指定数组长度,编译器会根据初始化列表计算出数组长度,例如:

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

可以写为:

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

[ ]中虽然没有指定数组长度,但系统会根据{ }中数据的个数确定数组a 长度为 5。    

3.一维数组动态初始化

先定义数组,然后分别对每个元素进行初始化,这种方式叫做数组的动态初始化。

例如:

int a[5]; //定义数组,数组的长度是5,但未直接初始化

a[0] =1; //初始化 a[0]

a[1] =2; //初始化 a[1]

a[2] =3; //初始化 a[2]

a[3] =3;    //初始化 a[3]

a[4] =3;  //初始化 a[4]

需要注意的是,数组元素下标从 0 开始,0-4 一共是 5 个元素,不存在 a[5]元素,初学者比较容易犯这个错误。这 5个数组元素可以等价看作 5 个 int 类型变量。

4.一维数组元素在内存的分布情况

数组本质上是一片连续的内存空间,每个数组元素都对应一块独立的内存空间。例如数组 a,在声明的过程中,就会在内存中占据一片空间,因为数组的长度是5所以这片空间又分为5块。紧接着我们又对数组进行了初始化,不论是静态初始化还是动态初始化,也就是把分配的空间进行赋值。内存模型如图所示6-1所示:

图6- 1 数组内存结构图

说明:

(1)数组名代表该数组的首地址,即 a[0]地址。 

(2)数组的各个元素是连续分布的,每一个元素都对应一个地址,就好比每个房间都有都有一个具体位置,假如 a[0] 地址 0x1122, a[1] 地址= a[0]的地址+int字节数(4) = 0x1122 + 4 = 0x1126,后面 a[2] 地址 = a[1]地址 + int 字节数(4) = 0x1126 + 4 = 0x112A。

5.数组使用需要注意事项和细节

(1)数组是多个相同类型数据的组合,一个数组一旦声明/定义了,其长度是固定的, 不能动态 变化。

(2) 数组创建后,如果没有赋值,则遵守如下规则全局数组默认值0 非全局数组初值是机器垃圾值(即:原来系统分配给这块空间的值)

6-1-3 一维数组引用

在程序中,使用数组时,经常需要访问数组中的一些元素,那么如何引用数组,访问数组元素:

数组的元素是引用是通过下标来实现的。

数组名[下标]

在这里再次强调一下下标,引用的下标可以是整型常量、变量、表达式,但是下标值必须在定义的取值范围 ,即0-数组长度-1之间。

例如:int a[4],表示数组 a 由 4个 int 类型数组元素组成。接下来引用数组分别为:a[0]、a[1]、a[2]、a[3]。a[0]是数组 a 第一个元素,也被称为数组 a 首元素。接下来通过一个案例来了解一下如何访问数组的运算。

实例6- 1求出数组的每一个元素。

#include <stdio.h>

int main()

{

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

int i;

printf("数组的运算为:\n");

for ( i= 0; i < 5; i++)

{

printf("%3d\t",arr[i]);

}

   getchar();

   return 0;

}

案例运行的结果如图6-2所示。

图6- 2 实例6-1运行结果

j数组使用之前必须先定义,只能引用单个的数组元素,不能一次引用整个数组,数组元素下标不要越界。

6-1-4  一维数组的应用

一维数组在实际开发中应用比较广泛,如数组进行遍历、获取最值、排序等操作,接下来针对一维数组的常见操作进行详细地讲解:

1.一维数组的遍历

在 C 语言中,数组元素下标从 0 开始,依次递增 1,到数组长度减 1 停止。例如:int a[5], 数组 a 有 5 个元素,元素下标依次为 0、1、2、3、4。由于数组下标是有规律的递增,因此, 可以使用 for 循环对数组元素进行遍历。

 

在数组遍历的过程中,我们可以使用sizeof来求数组的长度,格式如下:

数组长度=数组总字节数 /单个元素字节数。

int length=sizeof(a)/sizeof(int)或int length=sizeof(a)/sizeof(a[0]);

遍历数组的时候使用 sizeof 计算数组长度,会比直接写死更好,比如说int arr[]={12,34.......},数组的长度是根据数组元素确定,但是数组的元素的个数又比较多,使用sizeof 计算数组长度,就不用关心数组的个数了,既省时、又省力。

实例6- 2我们就可以定义一个数组来装配6名同学的分数,经过数组遍历求出平均成绩。

#include <stdio.h>

int main()

{

        int a[6]={11,82,83,94,95,100};//六名同学的分数

int len = sizeof(a)/sizeof(int); //求数组的长度

printf("遍历数组的元素 \n");

int i;

int sum;

for(i=0;i< len;i++)

{

  sum+=a[i];  //计算出六名同学的总成绩

  printf("%d  ",a[i]);

}

int  avg=sum/6;//计算六名同学的平均成绩

printf("\navg=%d ",avg);

    getchar();

    return 0;

}

运行结果如图 6-3所示。

图6- 3 实例 6-2运行结果

在上述案例中,我们在遍历数组元素的过程,求出元素之和,然后求出平均数。

2.获取一维数组的最值

在操作数组时,经常需要获取数组中元素的最值。接下来我们演示一个数组获取最大值。

实例6- 3获取数组元素的最大值

#include <stdio.h>

int main()

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

   int max= 0;

   int i = 0;

   printf("遍历数组的元素 \n");

   for (i = 1; i < 5; i++)

   {  if (arr[i] > max)

      {

         max= arr[i];

      }

      printf("%d  ",arr[i]);//遍历数组元素

   }

      printf("\n最大值是=%d\n", max);

getchar();

      return 0;

}

运行结果如图 6-4

图6- 4 实例 6-3运行结果

如上的代码,在对数组遍历的过程中如果数组元素比我们定义好的变量大,我们就把最大值赋值给max,这样遍历完成之后max就是我们求出的最大数值。

代码执行的流程如下图6-5所示。

图6- 5 实例 6-3代码执行流程

 

3.数组的排序

在操作数组时,经常需要对数组中的元素进行排序。接下来为大家介绍一种比较常见的排序算法—冒泡排序。

何为冒泡法排序呢?总得来说,就是按照一定顺序两两比较,不符合想要的顺序就交换两个数的位置,直到没有需要两两交换的为止。之所以叫“冒泡法”,因为这个算法的规律是最大(或最小)总是慢慢“浮”到顶端而得名。

如将序列10  4  1  9  2 的方式进行排序。排序流程如下图6-6所示。

图6- 6 冒泡排序

 

这样一来,元素10作为数组最大的元素就冒出到最右面,这时,冒泡排序的第一轮就结束了,依次进行排序,最后所有的元素,就都变成了有序的数列了。

实例6- 4将5个无序的数 使用冒泡排序法将其排成一个从小到大的有序数列。

#include <stdio.h>

int main()

{

int arr[5] = { 10,4, 1,9, 2 };//   定义数组为基本整型并且初始化数据

int m = 0, n = 0;

int temp = 0;

    int i = 0;

   printf("冒泡排序前:\n");

   for (i = 0; i < 5; i++)   

   {  

      printf("%5d", arr[i]);

}

    printf("\n");

    for (m = 0; m < 5 - 1; m++)   //变量m代表比较的趟数

    {   

  for (n = 0; n < 5 - 1 - m; n++)////变最n代表每趟两两比较的次数

  {  

  if (arr[n] > arr[n + 1])

     {

  temp = arr[n];  // 利用中间变童实现两值互换

arr[n] = arr[n + 1];

arr[n + 1] = temp;

}

}

}

  printf("冒泡排序后:\n");

for (i = 0; i < 5; i++)

{

   printf("%5d", arr[i]);

}

         printf("\n");

    return 0;

}

运行结果:如图 6-7所示。

图6- 7 实例 6-4运行结果

上述代码通过嵌套for循环实现了冒泡排序。其中,外层循环用来控制进行多少轮比较,每一轮比较都可以确定一个元素的位置,由于最后一个元素不需要进行比较,因此,外层循环的次数为数组的长度-1,内层循环的循环变量用于控制每轮比较的次数,在每次比较时,如果前者小于后者,就交换两个元素的位置。

猜你喜欢

转载自blog.csdn.net/qq_27248989/article/details/106109177