
C语言程序设计第8章数组.ppt
49页第第第第8 8 8 8章章章章 数组数组数组数组整理课件2024/9/182/49本章学习内容本章学习内容 对数组名特殊含义的理解对数组名特殊含义的理解 数组类型,数组的定义和初始化数组类型,数组的定义和初始化向函数传递一维数组和二维数组向函数传递一维数组和二维数组排序、查找、求最大最小值等常用算法排序、查找、求最大最小值等常用算法 2024/9/183/49为什么使用数组为什么使用数组(Array)?【【【【例例例例8.18.1】】】】要读入要读入要读入要读入1010人的成绩,然后求平均成绩人的成绩,然后求平均成绩人的成绩,然后求平均成绩人的成绩,然后求平均成绩 需定义需定义需定义需定义1010个不同名整型变量,需要使用多个个不同名整型变量,需要使用多个个不同名整型变量,需要使用多个个不同名整型变量,需要使用多个scanf()scanf() int score1,score2,…score10;int score1,score2,…score10; scanf("%d",&score1); scanf("%d",&score1); scanf("%d",&score2);scanf("%d",&score2); ...... ...... 而用数组,可共用一个而用数组,可共用一个而用数组,可共用一个而用数组,可共用一个scanf()scanf()并利用循环语句读并利用循环语句读并利用循环语句读并利用循环语句读取取取取 int score[10],i;int score[10],i; for (i=0; i<10; i++)for (i=0; i<10; i++) { { scanf("%d",&score[i]); scanf("%d",&score[i]); } }保存大量保存大量同类型的同类型的相关数据相关数据2024/9/184/49一维数组的定义和初始化一维数组的定义和初始化 一维数组的定义一维数组的定义一维数组的定义一维数组的定义 存储类型存储类型存储类型存储类型 数据类型数据类型数据类型数据类型 数组名数组名数组名数组名 [ [ [ [整数整数整数整数1] [1] [1] [1] [整数整数整数整数2] 2] 2] 2] ………… [ [ [ [整数整数整数整数n];n];n];n];a[9]a[8]a[7] a[1]a[0]…数组首地址数组首地址intint a[10]; a[10]; 定义一个有定义一个有定义一个有定义一个有1010个个个个intint型元素的数组型元素的数组型元素的数组型元素的数组– –系统在内存分配连续的系统在内存分配连续的系统在内存分配连续的系统在内存分配连续的1010个个个个intint空间给此数组空间给此数组空间给此数组空间给此数组 直接对直接对直接对直接对a a的访问,就是访问此数组的首地址的访问,就是访问此数组的首地址的访问,就是访问此数组的首地址的访问,就是访问此数组的首地址基类型基类型下标从下标从0开始开始2024/9/185/49一维数组的定义和初始化一维数组的定义和初始化a[9]a[8]a[7] a[1]a[0]…intint a[10]; a[10]; 数组大小必须是值为正的常量,不能为变量数组大小必须是值为正的常量,不能为变量数组大小必须是值为正的常量,不能为变量数组大小必须是值为正的常量,不能为变量– –一旦定义,不能改变大小一旦定义,不能改变大小一旦定义,不能改变大小一旦定义,不能改变大小 数组大小最好用宏来定义,以适应未来可能数组大小最好用宏来定义,以适应未来可能数组大小最好用宏来定义,以适应未来可能数组大小最好用宏来定义,以适应未来可能的变化的变化的变化的变化#define#define SIZESIZE 10 10 intint a[ a[SIZESIZE];]; 一维数组的定义一维数组的定义一维数组的定义一维数组的定义 存储类型存储类型存储类型存储类型 数据类型数据类型数据类型数据类型 数组名数组名数组名数组名 [ [ [ [整数整数整数整数1] [1] [1] [1] [整数整数整数整数2] 2] 2] 2] ………… [ [ [ [整数整数整数整数n];n];n];n];2024/9/186/49一维数组的定义和初始化一维数组的定义和初始化 数组定义后的初值仍然是随机数数组定义后的初值仍然是随机数 一般需要我们来初始化一般需要我们来初始化 int int a[5] = { 12, 34, 56 ,78 ,9 }; a[5] = { 12, 34, 56 ,78 ,9 }; int int a[5] = { 0 }; a[5] = { 0 }; int int a[] = { 11, 22, 33, 44, 55 }; a[] = { 11, 22, 33, 44, 55 };2024/9/187/49一维数组的定义和初始化一维数组的定义和初始化 数组的引用数组的引用 数组名数组名数组名数组名 [ [ [ [下标下标下标下标] ] ] ] 数组下标数组下标数组下标数组下标(index)(index)都是从都是从都是从都是从0 0开始开始开始开始 使用使用使用使用a[a[0 0] ]、、、、a[1]a[1]、、、、a[2]a[2]、、、、…………、、、、a[9]a[9]这样的形式这样的形式这样的形式这样的形式访问每个元素访问每个元素访问每个元素访问每个元素 下标既可是常量,也可是整型表达式,允许快速下标既可是常量,也可是整型表达式,允许快速下标既可是常量,也可是整型表达式,允许快速下标既可是常量,也可是整型表达式,允许快速随机访问,如随机访问,如随机访问,如随机访问,如a[i]a[i]–可以像使用普通变量一样使用它们可以像使用普通变量一样使用它们可以像使用普通变量一样使用它们可以像使用普通变量一样使用它们2024/9/188/49如何使两个数组的值相等?如何使两个数组的值相等?main(){ int a[4] = {1,2,3,4}, b[4]; b = a; }解决方法解决方法•方法方法1:1:逐个元素赋值逐个元素赋值 b[0]=a[0]; b[1]=a[1]; b[2]=a[2]; b[3]=a[3];•方法方法2:2:通过循环赋值通过循环赋值 int i; for (i=0;i<4;i++) { b[i] = a[i]; }原因原因: :数组名表示数组的首地址数组名表示数组的首地址, ,其值不可改变其值不可改变! !2024/9/189/49一维数组的定义和初始化一维数组的定义和初始化 【【【【例例例例8.28.2】】】】编程实现显示用户输入的月份(不包括编程实现显示用户输入的月份(不包括编程实现显示用户输入的月份(不包括编程实现显示用户输入的月份(不包括闰年的月份)拥有的天数闰年的月份)拥有的天数闰年的月份)拥有的天数闰年的月份)拥有的天数 2024/9/1810/49一维数组的定义和初始化一维数组的定义和初始化 下标越界是下标越界是大忌大忌!!–编译程序不检查是否越界编译程序不检查是否越界编译程序不检查是否越界编译程序不检查是否越界–下标越界,将访问数组以外的空间下标越界,将访问数组以外的空间下标越界,将访问数组以外的空间下标越界,将访问数组以外的空间–那里的数据是未知的,不受我们掌控,可能带那里的数据是未知的,不受我们掌控,可能带那里的数据是未知的,不受我们掌控,可能带那里的数据是未知的,不受我们掌控,可能带来严重后果来严重后果来严重后果来严重后果2024/9/1811/49b[0]b[0]b[1]b[1]b[2]b[2]b[3]b[3]b[4]b[4]b[5]b[5]b[6]b[6]b[7]b[7]b[8]b[8]b[9]b[9]c ca a【【例例8.3】】当下标值小于当下标值小于0或超过数组长度时或超过数组长度时 会出现什么情况?会出现什么情况?运行程序或单步执行观察变量变化情况可以看到,运行程序或单步执行观察变量变化情况可以看到,变量变量c c和和a a的值因数组越界而被悄悄破坏了的值因数组越界而被悄悄破坏了12345612078910114040444448484c4c5050545458585c5c6060646468686c6c2024/9/1812/49二维数组的定义和初始化二维数组的定义和初始化 一维数组一维数组一维数组一维数组– –用一个下标确定各元素在数组中的顺序用一个下标确定各元素在数组中的顺序用一个下标确定各元素在数组中的顺序用一个下标确定各元素在数组中的顺序– –可用排列成一行的元素组来表示可用排列成一行的元素组来表示可用排列成一行的元素组来表示可用排列成一行的元素组来表示 如如如如 int a[5]; int a[5]; 二维数组二维数组二维数组二维数组– –用两个下标确定各元素在数组中的顺序用两个下标确定各元素在数组中的顺序用两个下标确定各元素在数组中的顺序用两个下标确定各元素在数组中的顺序– –可用排列成可用排列成可用排列成可用排列成i i行,行,行,行,j j列的元素组来表示列的元素组来表示列的元素组来表示列的元素组来表示 如如如如 int b[2][3]; int b[2][3]; n n维数组维数组维数组维数组– –用用用用n n个下标来确定各元素在数组中的顺序个下标来确定各元素在数组中的顺序个下标来确定各元素在数组中的顺序个下标来确定各元素在数组中的顺序 如如如如 int c[3][2][4];int c[3][2][4];– –n≥3n≥3时,维数组无法在平面上表示其各元素的位置时,维数组无法在平面上表示其各元素的位置时,维数组无法在平面上表示其各元素的位置时,维数组无法在平面上表示其各元素的位置a[0]a[0]a[1]a[1]a[2]a[2]a[3]a[3]a[4]a[4]b[0][0]b[0][0]b[0][1]b[0][1]b[0][2]b[0][2]b[1][0]b[1][0]b[1][1]b[1][1]b[1][2]b[1][2]2024/9/1813/49【【【【例例例例】】】】以下程序的运行结果是什么?以下程序的运行结果是什么?以下程序的运行结果是什么?以下程序的运行结果是什么?int main()int main(){ { int a[][3]={{1,2,3},{4,5},{6},{0}}; int a[][3]={{1,2,3},{4,5},{6},{0}}; printf("%d,%d,%d\n",a[1][1],a[2][1],a[3][1]); printf("%d,%d,%d\n",a[1][1],a[2][1],a[3][1]); return 0; return 0;} }1 2 34 5 06 0 00 0 0结果:结果:5, 0, 0【【例例】】若若int a[ ][3]={1, 2, 3, 4, 5, 6, 7},,则则a数组的第一维大小是多少?数组的第一维大小是多少? 1 2 34 5 67 0 0二维数组的初始化二维数组的初始化2024/9/1814/49数组的数据类型和存储类型数组的数据类型和存储类型 根据数组的根据数组的根据数组的根据数组的数据类型数据类型数据类型数据类型,为每一元素安排相同长度的存储单元,为每一元素安排相同长度的存储单元,为每一元素安排相同长度的存储单元,为每一元素安排相同长度的存储单元 根据数组的根据数组的根据数组的根据数组的存储类型存储类型存储类型存储类型,将其安排在内存的动态存储区、静态,将其安排在内存的动态存储区、静态,将其安排在内存的动态存储区、静态,将其安排在内存的动态存储区、静态存储区或寄存器区存储区或寄存器区存储区或寄存器区存储区或寄存器区 用用用用sizeofsizeof(a)(a)来获得数组来获得数组来获得数组来获得数组a a所占字节数所占字节数所占字节数所占字节数shortshort2024/9/1815/49short int a[2][3];a[0]a[1]a[1][0] a[1][1]a[1][2]a[0][0] a[0][1]a[0][2]存放顺序:存放顺序:存放顺序:存放顺序:按行存放按行存放按行存放按行存放先顺序存放第先顺序存放第先顺序存放第先顺序存放第0 0行元素,再存放第行元素,再存放第行元素,再存放第行元素,再存放第1 1行元行元行元行元素素素素a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]需知道数组每行列数才能从起始地址开始正确读出数组元素需知道数组每行列数才能从起始地址开始正确读出数组元素二维数组的存储结构二维数组的存储结构二维数组的存储结构二维数组的存储结构2024/9/1816/49二维数组实例二维数组实例 【【【【例例例例8.48.4】】】】从键盘输入某年某月(包括闰年),编程输出该年从键盘输入某年某月(包括闰年),编程输出该年从键盘输入某年某月(包括闰年),编程输出该年从键盘输入某年某月(包括闰年),编程输出该年的该月拥有的天数的该月拥有的天数的该月拥有的天数的该月拥有的天数2024/9/1817/49 向函数传递一维数组向函数传递一维数组 传递传递传递传递整个数组整个数组整个数组整个数组给另一个函数,可给另一个函数,可给另一个函数,可给另一个函数,可将数组的将数组的将数组的将数组的首地址首地址首地址首地址作为参数传过去作为参数传过去作为参数传过去作为参数传过去–用用用用数组名数组名数组名数组名作函数参数作函数参数作函数参数作函数参数–只复制一个地址只复制一个地址只复制一个地址只复制一个地址自然比复制全部数自然比复制全部数自然比复制全部数自然比复制全部数据效率高据效率高据效率高据效率高–由于首地址相同,故实参数组与形由于首地址相同,故实参数组与形由于首地址相同,故实参数组与形由于首地址相同,故实参数组与形参数组参数组参数组参数组占用同一段内存占用同一段内存占用同一段内存占用同一段内存–在该函数内,不仅可以在该函数内,不仅可以在该函数内,不仅可以在该函数内,不仅可以读读读读这个数组这个数组这个数组这个数组的元素,还可以的元素,还可以的元素,还可以的元素,还可以修改修改修改修改它们它们它们它们2024/9/1818/49 简单变量和数组作函数参数简单变量和数组作函数参数的区别的区别2024/9/1819/49【【例例8.5】】计算平均分计算平均分 计数计数计数计数控制的循环控制的循环控制的循环控制的循环2024/9/1820/49【【例例8.5】】计算平均分计算平均分 计数计数计数计数控制的循环控制的循环控制的循环控制的循环2024/9/1821/49【【例例8.6】】计算平均分计算平均分当输入负值时,表示输入结束当输入负值时,表示输入结束 标记标记标记标记控制的循环控制的循环控制的循环控制的循环————负值作为输入结束标记负值作为输入结束标记负值作为输入结束标记负值作为输入结束标记2024/9/1822/49【【例例8.6】】计算平均分计算平均分当输入负值时,表示输入结束当输入负值时,表示输入结束 标记标记标记标记控制的循环控制的循环控制的循环控制的循环————负值作为输入结束标记负值作为输入结束标记负值作为输入结束标记负值作为输入结束标记2024/9/1823/49【【例例8.7】】计算最高分计算最高分#include
