第4章数组、指针_第1页
第4章数组、指针_第2页
第4章数组、指针_第3页
第4章数组、指针_第4页
第4章数组、指针_第5页
已阅读5页,还剩86页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、上海师范大学 计算机系2022年6月22日星期三第4章 数 组第1页高级语言程序设计高级语言程序设计 (C语言描述)语言描述)陆黎明陆黎明 朱媛媛朱媛媛 蒋蒋 培培 编著编著科学出版社科学出版社 2013.1上海师范大学 计算机系2022年6月22日星期三第4章 数 组第2页4.1.1 一维数组的定义一维数组的定义 前面章节中所使用的基本数据类型变量称为前面章节中所使用的基本数据类型变量称为简单变量简单变量。但在。但在实际编程时往往需要处理大量具有相同性质的数据实际编程时往往需要处理大量具有相同性质的数据,这时仅,这时仅用简单变量处理实际问题就显得很不方便。例如,输入用简单变量处理实际问题就显

2、得很不方便。例如,输入50个个学生的学号和某门课程的成绩,输出低于平均分的学生的学学生的学号和某门课程的成绩,输出低于平均分的学生的学号和成绩。号和成绩。 要想如数学中使用下标变量要想如数学中使用下标变量ai形式存放这形式存放这50个成绩,则可以个成绩,则可以引入引入下标变量下标变量ai。这些。这些按序排列的同类数据元素的集合称按序排列的同类数据元素的集合称为数组为数组。 使用数组必须先进行定义,一维数组使用数组必须先进行定义,一维数组定义的一般形式为定义的一般形式为: 类型标识符类型标识符 数组名数组名常量表达式常量表达式; 其中,其中,类型标识符类型标识符可以是任一种基本数据类型或构造数据

3、类可以是任一种基本数据类型或构造数据类型。型。数组名数组名是用户定义的数组标识符。方括号中的是用户定义的数组标识符。方括号中的常量常量表达表达式表示数据元素的个数式表示数据元素的个数,也称为,也称为数组的长度数组的长度。例如:。例如: int a10; float b10,c20; char ch20;上海师范大学 计算机系2022年6月22日星期三第4章 数 组第3页4.1.1 一维数组的定义一维数组的定义 关于数组定义还有关于数组定义还有以下几点需要说明以下几点需要说明:(1) 数组的类型数组的类型实际上是实际上是指数组元素的取值类型指数组元素的取值类型。 (2) 允许在同一个变量定义中,

4、定义多个数组和多个变量,但允许在同一个变量定义中,定义多个数组和多个变量,但数数组名不能与其它变量名相同组名不能与其它变量名相同。例如:。例如:int a,b,c,d, a10,b20; 是非法的是非法的(3) 方括号中方括号中常量表达式必须是整型常量表达式必须是整型,如,如aN表示数组表示数组a有有N个个元素。但是其元素。但是其下标从下标从0开始计算,下标范围为开始计算,下标范围为0N-1,N个元个元素可分别通过为素可分别通过为a0、a1.、aN-2、aN-1形式访问。形式访问。(4) 不能不能在方括号中在方括号中用变量来表示元素的个数用变量来表示元素的个数,但是可以是符号,但是可以是符号常

5、数或常量表达式。例如:常数或常量表达式。例如:int n=5; 非法非法int an;#define N 5 合法合法int a3+2,bN+1;上海师范大学 计算机系2022年6月22日星期三第4章 数 组第4页4.1.1 一维数组的定义一维数组的定义(5) 定义了一维数组以后,定义了一维数组以后,每个数组元素都有确定每个数组元素都有确定的内存单元,它们的内存单元,它们按元按元素下标顺序排列素下标顺序排列。要得。要得到某一元素的内存单元到某一元素的内存单元地址同简单变量一样,地址同简单变量一样,可用可用&运算符,如运算符,如&a0,&a3等。而等。而数组名数组名a是是

6、整个数组的整个数组的首地址常量首地址常量,与元素与元素a0的地址相同,的地址相同,见右图。见右图。a或&a0,2000a0&a1,2004a1&a2,2008a2&a3,2012a3&a4,2016a4上海师范大学 计算机系2022年6月22日星期三第4章 数 组第5页4.1.2 一维数组的初始化一维数组的初始化 在数组定义时给数组元素赋予初值可实现在数组定义时给数组元素赋予初值可实现数组初始化(与变数组初始化(与变量初始化类似)量初始化类似)。因为数组初始化在编译阶段进行,将减少。因为数组初始化在编译阶段进行,将减少运行时间,提高效率。数组运行时间,提

7、高效率。数组初始化的一般形式初始化的一般形式: 类型标识符类型标识符 数组名数组名常量表达式常量表达式=值,值,值,值,值,值;例如:例如:int a5= 3,4,5,6,7 ; 相当于相当于a0=3; a1=4; a2=5; a3=6; a4=7;语言对数组的语言对数组的初始化赋值还有以下几点规定初始化赋值还有以下几点规定:(1) 可以可以只给部分元素赋初值只给部分元素赋初值。例如:。例如:int a5=3,4; 表示表示a0=3,a1=4,其他元素自动赋初值其他元素自动赋初值0。 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第6页4.1.2 一维数组的初始化一维数组的初始

8、化(2) 只能给元素逐个赋初值,只能给元素逐个赋初值,不能给数组整体赋初值不能给数组整体赋初值。例如:。例如:int a5=1,1,1,1,1; 而不能写为:而不能写为:int a5=1;(3) 若给全部元素都赋初值若给全部元素都赋初值,则在数组定义时可以不给出数组的则在数组定义时可以不给出数组的长度长度。例如:。例如:int a5= 3,4,5,6,7 ; 等价于等价于 int a = 3,4,5,6,7 ;(4) 若在数组定义时若在数组定义时没有给数组赋初值,则全部元素的初值不确没有给数组赋初值,则全部元素的初值不确定定,而不是为,而不是为0。 上海师范大学 计算机系2022年6月22日星

9、期三第4章 数 组第7页4.1.3 一维数组元素的引用一维数组元素的引用 数组元素也是一种变量,其引访问的一般形式为:数组元素也是一种变量,其引访问的一般形式为: 数组名数组名下标表达式下标表达式 其中的其中的下标表达式只能为整型常量或整型表达式下标表达式只能为整型常量或整型表达式,不能为小,不能为小数。例如,数。例如,a3,ai+j,ai+都是合法的数组元素,而都是合法的数组元素,而a3.6则是非法的。则是非法的。在在C语言中称下标运算符语言中称下标运算符,其内部的整数表示,其内部的整数表示离开数组名(首地址)几个元素,例如,离开数组名(首地址)几个元素,例如,a1离开数组名离开数组名1个个

10、元素(相隔元素(相隔a0)。)。 在语言中,在语言中,数组不能作为一个整体参加输入、输出等操作,数组不能作为一个整体参加输入、输出等操作,只能对单个数组元素进行处理只能对单个数组元素进行处理。例如,若要输出有。例如,若要输出有10 个元素个元素的整型数组需通过循环语句逐个输出各数组元素:的整型数组需通过循环语句逐个输出各数组元素:for (i=0; i10; i+) printf(%d, ai); 而而不能用一句语句不能用一句语句“printf(%d, a);”输出整个数组输出整个数组。 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第8页4.1.3 一维数组元素的引用一维数组

11、元素的引用 数组元素通常也称为下标变量数组元素通常也称为下标变量。必须先定义数组,才能使用。必须先定义数组,才能使用下标变量。下标变量。下标变量的使用规则等同于相同类型的简单变量下标变量的使用规则等同于相同类型的简单变量。 要特别强调的是要特别强调的是,在程序的编译和运行过程中,在程序的编译和运行过程中,系统并不会系统并不会自动检查数组元素的下标是否越界自动检查数组元素的下标是否越界。因此这种错误不易发现,。因此这种错误不易发现,需要程序员自行保证下标不越界。需要程序员自行保证下标不越界。例例4.1 用数组来输出用数组来输出Fibonacci数列的前数列的前20个数。个数。 分析分析:Fibo

12、nacci数列的定义为:当数列的定义为:当n=1或或2时时fib1=fib2=1,当当n3时时fibn= fibn-1+ fibn-2 。用数组中的下标变量来表示数。用数组中的下标变量来表示数学中的下标变量显得直接而方便。学中的下标变量显得直接而方便。 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第9页4.1.3 一维数组元素的引用一维数组元素的引用#include int main() int i; long f20=1,1; /* 数组部分元素初始化数组部分元素初始化 */ for (i=2; i20; i+) fi=fi-2+fi-1; for (i=0; i20; i

13、+) printf(%6ld, fi); if (i+1)%5=0) printf(n); /* 每行输出每行输出5个数个数 */ return 0;例例4.2 输入输入8个数,输出其中的最大值以及它的下标。个数,输出其中的最大值以及它的下标。 分析分析:本例中不但要找出最大值,还要记住它的下标本例中不但要找出最大值,还要记住它的下标,因此,因此要增加一个变量来保存当前最大值所在的下标。要增加一个变量来保存当前最大值所在的下标。 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第10页4.1.3 一维数组元素的引用一维数组元素的引用#define N 8#include int

14、main() int i,pmax; float aN,max; /* pmax存放最大值的下标存放最大值的下标 */ printf(请输入请输入%d个数:个数:n, N); for (i=0; iN; i+) scanf(%f, &ai); max=a0; pmax=0; /* 首先假定第首先假定第1个数个数a0是最大的是最大的 */ for (i=1; imax) max=ai; pmax=i; /* 必须同时记住它的下标必须同时记住它的下标 */ printf(最大值:最大值:a%d=%fn, pmax,max); return 0;运行结果:运行结果:请输入请输入8个数:个数:

15、71 64 82 77 83 76 95 78最大值:最大值:a6=95.000000上海师范大学 计算机系2022年6月22日星期三第4章 数 组第11页4.1.4 一维数组应用举例一维数组应用举例 合理利用数组也可以起到简化程序、便于编程等其他作用合理利用数组也可以起到简化程序、便于编程等其他作用,下面将通过几个例子来说明如何合理利用数组。下面将通过几个例子来说明如何合理利用数组。例例4.3 输入年份和月份,输出该月的天数。输入年份和月份,输出该月的天数。 分析分析:一个月的天数有:一个月的天数有28或或29(闰年)或(闰年)或30或或31四种情况,四种情况,如果不用数组如果不用数组,就要

16、用到,就要用到if语句或语句或switch语句来区分这四种语句来区分这四种情况,情况,程序显得长且繁程序显得长且繁。如果。如果事先将每个月的天数放到数组事先将每个月的天数放到数组中,月份作为下标直接去读取,程序就显得非常简洁且易读中,月份作为下标直接去读取,程序就显得非常简洁且易读。由于月份从由于月份从1开始,而数组的下标从开始,而数组的下标从0开始,所以程序中的数开始,所以程序中的数组多定义了组多定义了1个元素(个元素(还可以如何解决这个问题?还可以如何解决这个问题?),以方),以方便读取天数。便读取天数。 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第12页4.1.4 一

17、维数组应用举例一维数组应用举例#include int main() int days=0,31,28,31,30,31,30,31,31,30,31,30,31; /* 省去了数省去了数 组的长度组的长度 */ int y,m,d; printf(请输入年份和月份请输入年份和月份(yyyy-mm): ); scanf(%d-%d, &y,&m); /* 假定输入的年份和月份是合法的假定输入的年份和月份是合法的 */ d=daysm; if ( (m=2) & (y%4=0 & y%100!=0 | y%400=0) ) d+; printf(该月有该月有%d天

18、天n, d); return 0;运行结果:运行结果:请输入年份和月份请输入年份和月份(yyyy-mm): 2012-2该月有该月有29天天上海师范大学 计算机系2022年6月22日星期三第4章 数 组第13页4.1.4 一维数组应用举例一维数组应用举例例例4.4 输入输入8个学生的成绩,统计并输出其中的优、良、中、及个学生的成绩,统计并输出其中的优、良、中、及格、不及格的人数。格、不及格的人数。 分析分析:百分制成绩:百分制成绩score的范围为的范围为0100,五级制成绩的标,五级制成绩的标准为:准为:90分以上为优;分以上为优;8089为良;为良;7079为中;为中;6069为为及格,及

19、格,60分以下为不及格。分以下为不及格。如果不用数组如果不用数组,就要用到,就要用到if语句语句或或switch语句以及五个计数器来分别统计优、良、中、及格、语句以及五个计数器来分别统计优、良、中、及格、不及格的人数。不及格的人数。如果用如果用score/10-5作为下标作为下标(当下标为负数(当下标为负数时改为时改为0,都对应不及格),都对应不及格),对应的数组元素作为计数器就对应的数组元素作为计数器就可以简化程序可以简化程序。本例主要说明。本例主要说明如何巧用下标如何巧用下标,成绩的个数同,成绩的个数同样可以通过修改符号常量的定义来扩大。样可以通过修改符号常量的定义来扩大。#define

20、N 8上海师范大学 计算机系2022年6月22日星期三第4章 数 组第14页4.1.4 一维数组应用举例一维数组应用举例#include int main() int score,i,n,c6=0; /*所有元素均被初始化为所有元素均被初始化为0*/ printf(请输入请输入%d个百分制成绩个百分制成绩(0100):n, N); for (i=0; iN; i+) scanf(%d, &score); /* 这里假定输入的成绩是有效的这里假定输入的成绩是有效的 */ n=score/10-5; /* n的取值范围为的取值范围为-55, 当当n为为5或或4时对应的成绩为优时对应的成绩为

21、优 */ if (n0) n=0; /* 当当n取值为取值为-50时对应的成绩不及格时对应的成绩不及格 */ cn+; /* cn为计数器为计数器 */ printf(优优:%d 良良:%d 中中:%d 及格及格:%d 不及格不及格:%dn, c5+c4,c3,c2,c1,c0); return 0;运行结果:运行结果:请输入请输入8个百分制成绩个百分制成绩(0100):71 64 82 47 83 76 95 78优优:1 良良:2 中中:3 及格及格:1 不及格不及格:1上海师范大学 计算机系2022年6月22日星期三第4章 数 组第15页4.1.4 一维数组应用举例一维数组应用举例例例4

22、.5 输入一个正整数,输出其对应的二进制数。输入一个正整数,输出其对应的二进制数。 分析分析:十进制正整数转换成对应的二进制数的:十进制正整数转换成对应的二进制数的方法是方法是“除除2取余取余”,困难在于困难在于第一个余数要最后输出,最后一个余数要第一个余数要最后输出,最后一个余数要第一个输出。第一个输出。如果不用数组,编程很困难如果不用数组,编程很困难。而如果把所有的。而如果把所有的余数都存放到数组中,那么只要反序输出数组元素的值就可余数都存放到数组中,那么只要反序输出数组元素的值就可以了。另外,本例中也充分以了。另外,本例中也充分说明了自增、自减运算符前置运说明了自增、自减运算符前置运算和

23、后置运算的区别和用处算和后置运算的区别和用处。#include int main()上海师范大学 计算机系2022年6月22日星期三第4章 数 组第16页4.1.4 一维数组应用举例一维数组应用举例 int a,n,bits64; /* 正整数对应的二进制数最多正整数对应的二进制数最多64位位 */ printf(请输入一个正整数请输入一个正整数: ); scanf(%d, &a); n=0; /* n中存放对应的二进制数的位数中存放对应的二进制数的位数 */ do /* 因为对应的二进制数至少有因为对应的二进制数至少有1位,适合用位,适合用do-while语句语句 */ bitsn+

24、=a%2; /* 必须用后置运算必须用后置运算, 这样第一个余数才能放到下标这样第一个余数才能放到下标0处处 */ a /= 2; while (a!=0); printf(对应的二进制数为对应的二进制数为: ); while (-n=0) /* 必须用前置运算必须用前置运算, 如果如果n=2,这两位是放在下标,这两位是放在下标1和和0处处 */ printf(%d, bitsn); printf(n); return 0;运行结果:运行结果:请输入一个正整数请输入一个正整数: 83对应的二进制数为对应的二进制数为: 1010011上海师范大学 计算机系2022年6月22日星期三第4章 数 组

25、第17页4.1.4 一维数组应用举例一维数组应用举例例例4.6 用用“筛法筛法”找出找出3100之间的之间的全部素数全部素数,每输出,每输出10个素个素数后换行。数后换行。 分析分析:筛法是公元前古希腊数学家:筛法是公元前古希腊数学家Eratosthenes发明的一个发明的一个更为高效的更为高效的求不超过某一个正整数求不超过某一个正整数N的全部素数的算法的全部素数的算法。为。为了方便解释算法,假定了方便解释算法,假定N=30。(1) 将将330之间的全部奇数组成一个集合(之间的全部奇数组成一个集合(这个集合称为这个集合称为“筛筛”):): 3,5,7,9,11,13,15,17,19,21,2

26、3,25,27,29(2) 集合中的集合中的最小数最小数3是素数是素数,把集合中,把集合中3的倍数(的倍数(6, 9, 12, )全部去掉得)全部去掉得到新的集合:到新的集合: 3,5,7,9,11,13,15,17,19,21,23,25,27,29(3) 集合中除了集合中除了3以外的以外的最小数最小数5就是素数就是素数,把集合中,把集合中5的倍数(的倍数(10, 15, 20, )全部去掉得到新的集合:)全部去掉得到新的集合: 3,5,7,9,11,13,15,17,19,21,23,25,27,29上海师范大学 计算机系2022年6月22日星期三第4章 数 组第18页4.1.4 一维数组

27、应用举例一维数组应用举例(4) 集合中除了集合中除了3,5 以外的以外的最小数最小数7就是素数就是素数,把集合中,把集合中7的倍数(的倍数(14, 21, 28)全部去掉得到新的集合:全部去掉得到新的集合: 3,5,7,9,11,13,15,17,19,21,23,25,27,29(5) 这样一直进行下去,直到得到的新的素数大于这样一直进行下去,直到得到的新的素数大于 为止(因为为止(因为7 ,所以所以(4)白做)。白做)。 请读者思考为什么请读者思考为什么得到的新的素数大于得到的新的素数大于 就可以结束算法。就可以结束算法。 实现筛法的关键是如何表示集合?实现筛法的关键是如何表示集合?虽然虽

28、然C语言中没有集合数据类型,但语言中没有集合数据类型,但可以使用数组来表示集合,则定义可以使用数组来表示集合,则定义int aN+1; 通过通过ai=0表示数表示数i不在集不在集合中,而置合中,而置ai=1表示数表示数i在集合中。在集合中。本例说明通过数组可记录状态信息本例说明通过数组可记录状态信息。#define N 100#include #include int main()N30N上海师范大学 计算机系2022年6月22日星期三第4章 数 组第19页4.1.4 一维数组应用举例一维数组应用举例 int i,j,k,c,aN+1=0; for (i=3; iN+1; i+=2) ai=1

29、; /* 生成生成3N之间全部奇数组成的集合之间全部奇数组成的集合 */ for (k=sqrt(N),i=3; i=k; i+=2) if (ai) /* 若若ai=1,则,则i是素数是素数 */ for (j=2*i; jN+1; j+=i) aj=0; /* 集合中集合中i的倍数全部去掉的倍数全部去掉 */ for (c=0,i=3; i=1; j-) if (ajaj+1) for (j=7; j=2; j-) if (ajaj+1) for (i=1; i=i; j-) /* 下标在下标在Ni范围范围内的数内的数两两比较两两比较, 若逆序,则交换若逆序,则交换 */ if (ajaj

30、+1) t=aj; aj=aj+1; aj+1=t; 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第22页4.1.4 一维数组应用举例一维数组应用举例#define N 8#include int main() int i,j,t,aN+1; /* a0不用不用 */ printf(请输入请输入%d个整数个整数:n, N); for (i=1; iN+1; i+) scanf(%d, &ai); for (i=1; i=i; j-) /* 下标在下标在Ni范围范围内的数内的数两两比较两两比较, 若逆序,则交换若逆序,则交换 */ if (ajaj+1) t=aj; a

31、j=aj+1; aj+1=t; printf(排序后排序后:n); for (i=1; iN+1; i+) printf(%d , ai); putchar(n); 运行结果:运行结果:请输入请输入8个整数个整数:71 95 83 46 74 68 87 52排序后排序后:46 52 68 71 74 83 87 95上海师范大学 计算机系2022年6月22日星期三第4章 数 组第23页4.1.4 一维数组应用举例一维数组应用举例例例4.8 输入输入8个整数,用个整数,用“选择法选择法”对这对这8个数从小到大排序。个数从小到大排序。 分析分析:选择法排序的基本思想选择法排序的基本思想是每趟选择

32、一个最小数,把它是每趟选择一个最小数,把它放到希望的位置上。设有放到希望的位置上。设有N个数要从小到大排序,它们存放个数要从小到大排序,它们存放在从下标在从下标1到下标到下标N的数组的数组a中,排序过程为:中,排序过程为:#define N 8#include int main()71469595528383836846717171717474747474746868688383838387878787878787875252959595959595 第第1趟趟 第第2趟趟 第第3趟趟 第第4趟趟 第第5趟趟 第第6趟趟 第第7趟趟k=i; /* 在下标为在下标为iN的范围内找最小数的范围内找

33、最小数,k中存放最小数的下标中存放最小数的下标 */for (j=i+1; j=N; j+) if (ajak) k=j; if ( k!=i ) /* 若若第第i个最小数不在希望的下标个最小数不在希望的下标i处,则交换处,则交换 */ t=ai; ai=ak; ak=t; 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第24页4.1.4 一维数组应用举例一维数组应用举例 int i,j,k,t,aN+1; /* a0不用不用 */ printf(请输入请输入%d个整数个整数:n, N); for (i=1; iN+1; i+) scanf(%d, &ai); for

34、(i=1; iN; i+) /* 共共N-1趟选择排序趟选择排序 */ k=i; /* 在下标为在下标为iN的范围内找最小数的范围内找最小数,k中存放最小数的下标中存放最小数的下标 */ for (j=i+1; j=N; j+) if (ajak) k=j; if ( k!=i ) /* 若若第第i个最小数不在希望的下标个最小数不在希望的下标i处,则交换处,则交换 */ t=ai; ai=ak; ak=t; printf(排序后排序后:n); for (i=1; iamid,则,则low=mid+1;若若xhigh的现象的现象。上海师范大学 计算机系2022年6月22日星期三第4章 数 组第2

35、6页4.1.4 一维数组应用举例一维数组应用举例二分法查找二分法查找查找查找数值数值7成功成功的过程:的过程:二分法查找二分法查找查找查找数值数值7.5不成功不成功的过程:的过程:下标下标123456789值值2345678910下标下标123456789值值2345678910下标下标123456789值值2345678910下标下标123456789值值2345678910下标下标123456789值值2345678910下标下标123456789值值2345678910下标下标123456789值值2345678910上海师范大学 计算机系2022年6月22日星期三第4章 数 组第27页

36、4.1.4 一维数组应用举例一维数组应用举例#define N 8#include int main() int aN+1=0,46,52,68,71,74,83,87,95; /* a0不用不用 */ int low,high,mid,x; printf(请输入要查找的整数请输入要查找的整数: ); scanf(%d, &x); low=1; high=N; while (lowamid) low=mid+1; else high=mid-1; /*有几种情况退出查找循环?有几种情况退出查找循环?*/ if (low=high) printf(数数%d的位置是的位置是: %dn, x

37、,mid); else printf(数数%d找不到找不到n, x); return 0;上海师范大学 计算机系2022年6月22日星期三第4章 数 组第28页4.2.1 二维数组的定义二维数组的定义 二维数组二维数组定义的一般形式定义的一般形式: 类型说明符类型说明符 数组名数组名常量表达式常量表达式1常量表达式常量表达式2 ; 其中常量表达式其中常量表达式1和表达式和表达式2(都必须是整型)分别表(都必须是整型)分别表示第一维(即行)和第二维(即列)的长度。例如:示第一维(即行)和第二维(即列)的长度。例如:int a34; 该数组共有该数组共有34=12个元素个元素,即:,即:二维数组在

38、形式上是二维的,但是,实际的内存储器二维数组在形式上是二维的,但是,实际的内存储器却是按一维线性排列的却是按一维线性排列的。如何在一维存储器中存放二。如何在一维存储器中存放二维数组的元素?通常可有两种方式:一种是维数组的元素?通常可有两种方式:一种是按行存放按行存放,另一种是另一种是按列存放按列存放。在。在语言中,二维数组采用的是语言中,二维数组采用的是按行存放按行存放。例如:。例如:int a34; 该数组在内存中的存该数组在内存中的存放形式如右图所示。放形式如右图所示。 形式上形式上 第0列 第1列 第2列第3列 第0行 a00 a01a02a03第1行 a10 a11a12a13第2行

39、a20 a21a22a23a00a01a02a03a10a11a12a13a20a21a22a23内存中内存中上海师范大学 计算机系2022年6月22日星期三第4章 数 组第29页4.2.2 二维数组的初始化二维数组的初始化 本质上,二维数组可看作由一维数组的嵌套构成的。本质上,二维数组可看作由一维数组的嵌套构成的。设有设有二二维数组维数组a34,它可分解为,它可分解为3个一维数组个一维数组(每个一维数组都(每个一维数组都有有4个元素),其个元素),其数组名分别为数组名分别为a0、a1和和a2。 二维数组也可以在定义时给各数组元素赋以初值。二维数组二维数组也可以在定义时给各数组元素赋以初值。二

40、维数组的初始化有的初始化有分行赋初值分行赋初值和和顺序赋初值顺序赋初值两种方法。两种方法。(1) 给二维数组给二维数组所有元素赋初值所有元素赋初值,例如:,例如:int a33= 80,75,92, 85,63,70, 66,77,82 ; /* 分行分行赋初值赋初值 */ 或或int a33= 80, 75, 92, 85, 63, 70, 66, 77, 82 ; /* 顺序赋顺序赋初值初值 */上海师范大学 计算机系2022年6月22日星期三第4章 数 组第30页4.2.2 二维数组的初始化二维数组的初始化(2) 若给二维数组的若给二维数组的所有元素都赋了初值所有元素都赋了初值,则,则第

41、一维的长度可以第一维的长度可以省略省略,但第二维的长度不能省略但第二维的长度不能省略。例如:。例如:int a 3= 80,75,92, 85,63,70, 66,77,82 ; /* 有有3行行 */ 或或int a 3= 80, 75, 92, 85, 63, 70, 66, 77, 82 ; /* 有有3行行 */(3) 若若只对部分元素赋初值只对部分元素赋初值,则未赋初值的元素自动取,则未赋初值的元素自动取0值。值。int a33= 80, 85, 66 ; /* 只对只对每一行的第一列每一行的第一列元素赋初值元素赋初值 */int a33= 80, 85,63, 66,77,82;

42、/* 只对只对下三角部分下三角部分元素赋初值元素赋初值 */int a33= 80,75,92, 0,63,70, 0,0,82; /* 只对只对上三角部分上三角部分元素元素 赋初值赋初值 */int a33= 80, , 0,0,82; /* 只对只对第一、三行部分元素第一、三行部分元素赋初值赋初值 */int a33= 80,75,92, 85,63 ; /* 只对只对第一、二行部分元素第一、二行部分元素赋初值赋初值 */int a33= 80, 75, 92, 85, 63 ; /* 只对第一、二行部分元素赋初值只对第一、二行部分元素赋初值 */其中最后二句定义的数组其中最后二句定义的数

43、组a的初值是完全相同的。的初值是完全相同的。 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第31页4.2.2 二维数组的初始化二维数组的初始化(4) 如如只对部分元素赋初值只对部分元素赋初值,这时可,这时可省略第一维的长度省略第一维的长度,但第,但第二维的长度还是不能省略。例如:二维的长度还是不能省略。例如:int a 3= 80, , 0,0,82; /* 有有3行行 */int a 3= 80,75,92, 85,63 ; /* 有有2行行 */int a 3= 80, 75, 92, 85, 63 ; /* 有有2行行 */上海师范大学 计算机系2022年6月22日星期

44、三第4章 数 组第32页4.2.3 二维数组元素的引用二维数组元素的引用 二维数组元素的引用形式:数组名二维数组元素的引用形式:数组名下标下标1下标下标2 其中,下标可以是整型常量或整型表达式,不能为小数。其中,下标可以是整型常量或整型表达式,不能为小数。注注意意:a12不能写成不能写成a1,2;引用二维数组元素时其行引用二维数组元素时其行下标和列下标和列下标一定不能越界下标一定不能越界。对二维数组中的元素进行处理对二维数组中的元素进行处理时,常常需要通过循环嵌套来实现时,常常需要通过循环嵌套来实现。例例4.10 输入一个输入一个34的矩阵,编程找出每一行中值最大的那的矩阵,编程找出每一行中值

45、最大的那个元素并与第个元素并与第1列交换位置。列交换位置。#include int main() int a34, i, j, p, t; printf(请输入一个请输入一个34的矩阵:的矩阵:n); for (i=0; i3; i+) /*i控制行下标的变化控制行下标的变化*/ for (j=0; j4; j+) /*j控制列下标的变化控制列下标的变化*/ scanf(%d, &aij); 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第33页4.2.3 二维数组元素的引用二维数组元素的引用 for (i=0; i3; i+) p=0; /* p中存放每行最大元素的列

46、下标,中存放每行最大元素的列下标,先假定第先假定第1列是最大的列是最大的 */ for (j=1; jaip) p=j; if (p!=0) t=ai0; ai0=aip; aip=t; printf(最大值交换到第最大值交换到第1列后的矩阵:列后的矩阵:n); for (i=0; i3; i+) for (j=0; j4; j+) printf(%4d, aij); printf(n); return 0;上海师范大学 计算机系2022年6月22日星期三第4章 数 组第34页4.2.4 二维数组应用举例二维数组应用举例例例4.11 有一个有一个34的矩阵,将其转置后放到另一个二维数组的矩阵,

47、将其转置后放到另一个二维数组中并输出转置后的矩阵。中并输出转置后的矩阵。 分析分析:原矩阵:原矩阵a为为3行行4列,那么它的转置矩阵列,那么它的转置矩阵b为为4行行3列,并且矩阵列,并且矩阵a的的第第i行元素与矩阵行元素与矩阵b的第的第i列的元素相同。列的元素相同。#include int main() int a34= 80,75,92,62, 46,85,63,70, 52,66,77,82 ; int b43, i, j; for (i=0; i3; i+) for (j=0; j4; j+) bji=aij; for (i=0; i4; i+) for (j=0; j3; j+) pr

48、intf(%4d, bij); printf(n); return 0;思考题思考题:如何对一个:如何对一个n阶方阵原地转置?阶方阵原地转置?所谓原地就是指程序所谓原地就是指程序中只能用一个数组。中只能用一个数组。 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第35页4.2.4 二维数组应用举例二维数组应用举例例例4.12 设有一个设有一个4人学习小组,每人有语文、数学、外语、物人学习小组,每人有语文、数学、外语、物理和化学五门课的考试成绩,求每个人的平均成绩。理和化学五门课的考试成绩,求每个人的平均成绩。 分析分析:可设一个二维数组:可设一个二维数组a45存放存放4个人个人

49、5门课的成绩,再设一个一维门课的成绩,再设一个一维数组数组ave4存放所求得的每个人的平均成绩。存放所求得的每个人的平均成绩。#include int main() int i,j,sum,a45= 80,84,78,81,82, 65,46,63,70,73, 87,93,95,82,88, 75,74,78,67,77 ; float ave4; for (i=0; i4; i+) for (sum=0,j=0; j5; j+) /* 求每个人的总成绩之前,求每个人的总成绩之前,sum必须置必须置0 */ sum += aij; avei=sum/5.0; for (i=0; i4; i+

50、) printf(%8.2f, avei); printf(n); return 0;上海师范大学 计算机系2022年6月22日星期三第4章 数 组第36页4.2.4 二维数组应用举例二维数组应用举例例例4.13 魔方阵是我国古代发明的一种数字游戏。魔方阵是我国古代发明的一种数字游戏。n阶魔方阵是阶魔方阵是指这样一种方阵,它的每一行、每一列以及对角线上的各数指这样一种方阵,它的每一行、每一列以及对角线上的各数之和为一个常数,这个常数是之和为一个常数,这个常数是n(n2+1)/2,被称为魔方阵常数。,被称为魔方阵常数。这里只考虑这里只考虑n为奇数的情况,下面是一个为奇数的情况,下面是一个n=3的

51、魔方阵:的魔方阵:4 3 89 5 12 7 6 分析分析:对于:对于n为奇数的魔方阵,我国的古人早已找到了求解的方法:为奇数的魔方阵,我国的古人早已找到了求解的方法:(1) 魔方阵中的数魔方阵中的数由由1 n2的的n2个整数组成个整数组成。(2) 第一个数第一个数1放在中间一行的最后一列放在中间一行的最后一列。(3) 下一个数放在何处取决于刚刚放的那个数是否是下一个数放在何处取决于刚刚放的那个数是否是n的倍数。的倍数。(4) 若是若是n的倍数的倍数,则下一个数放在刚刚放的那个数的左边,即行标不变,则下一个数放在刚刚放的那个数的左边,即行标不变,列标减列标减1。(5) 若不是若不是n的倍数的倍

52、数,则下一个数放在刚刚放的那个数的右下方,即行标和,则下一个数放在刚刚放的那个数的右下方,即行标和列标均加列标均加1。若行标或列标加。若行标或列标加1后超界,则把它置后超界,则把它置1。(6) 返回返回(3),重复上述过程,当最后一个数,重复上述过程,当最后一个数n2放好后,魔方阵就形成了。放好后,魔方阵就形成了。上海师范大学 计算机系2022年6月22日星期三第4章 数 组第37页4.2.4 二维数组应用举例二维数组应用举例#include int main() int a1616,n,i,j,k; /* 第第0行第行第0列不用列不用 */ do /* 本循环保证输入的整数符合要求本循环保证

53、输入的整数符合要求 */ printf(请输入一个请输入一个315的奇数的奇数: ); scanf(%d, &n); while ( n%2=0 | !(3=n & n=15) ); i=(n+1)/2; j=n; /* 第一个数第一个数1放在中间一行的最后一列放在中间一行的最后一列 */ for (k=1; k=n*n; k+) aij=k; if (k%n=0) j-; /* 若刚放的数若刚放的数k是是n的倍数,则行标不变,列标减的倍数,则行标不变,列标减1 */ else i=i%n+1; j=j%n+1; /* 行标和列标加行标和列标加1,若超界,则置,若超界,则置1

54、*/ /* 输出数组输出数组a中各个元素的值,方法参见例中各个元素的值,方法参见例4.11 */ return 0;上海师范大学 计算机系2022年6月22日星期三第4章 数 组第38页4.3.1 指针与指针变量指针与指针变量 利用指针变量能利用指针变量能表示各种复杂的数据结构;表示各种复杂的数据结构;能能很方便、灵活很方便、灵活地使用数组和字符串;地使用数组和字符串;能能像汇编语言一样处理内存地址;像汇编语言一样处理内存地址;能能为实现函数间各类数据的传递提供简洁便利的方法;为实现函数间各类数据的传递提供简洁便利的方法;能能编出编出精练而高效的程序。精练而高效的程序。能否正确理解和使用指针是

55、检验是否全能否正确理解和使用指针是检验是否全面掌握语言的一个标志面掌握语言的一个标志。因此,指针也成为语言学习中。因此,指针也成为语言学习中最为困难的一部分。最为困难的一部分。1、指针的概念、指针的概念 内存储器中每个存储单元都有一个唯一的编号,称为内存地内存储器中每个存储单元都有一个唯一的编号,称为内存地址,即址,即“指针指针”(常量)(常量)。 内存单元的地址和内存单元的内容是两个不同的概念内存单元的地址和内存单元的内容是两个不同的概念。内存。内存单元的地址即为该单元的唯一编号,其中存放的数据才是该单元的地址即为该单元的唯一编号,其中存放的数据才是该单元的内容。单元的内容。 上海师范大学

56、计算机系2022年6月22日星期三第4章 数 组第39页4.3.1 指针与指针变量指针与指针变量 在在C语言中,当定义一个变量时,系统根据它的数据类型为语言中,当定义一个变量时,系统根据它的数据类型为它分配一定数量的一段连续存储单元,它分配一定数量的一段连续存储单元,这段连续内存单元的这段连续内存单元的起始地址起始地址就是就是变量的地址变量的地址,也就是,也就是变量的变量的“指针指针”,而,而这些这些内存单元中存放的数据也就是变量的内存单元中存放的数据也就是变量的“值值”。 例如,有变量定义例如,有变量定义int a=100; 并假定并假定int数据类型占用数据类型占用2个字个字节的内存空间,

57、系统就为变量节的内存空间,系统就为变量a分配分配2个字节的内存单元,并个字节的内存单元,并将这将这2个单元的内容修改为个单元的内容修改为100。 内存地址 1998内存单元 1999变量名a 2000100变量的地址2001变量的值 20022003上海师范大学 计算机系2022年6月22日星期三第4章 数 组第40页4.3.1 指针与指针变量指针与指针变量2、指针变量、指针变量 指针是一种数据。语言允许用一个变量来存放指针,即指针是一种数据。语言允许用一个变量来存放指针,即指指针变量针变量。指针变量的值是某个内存单元的地址(指针)指针变量的值是某个内存单元的地址(指针)。 指针变量的定义应包

58、括三方面的内容指针变量的定义应包括三方面的内容:指针类型说明指针类型说明,即,即定义变量为一个指针变量;定义变量为一个指针变量;指针变量名指针变量名;基类型基类型,即指,即指针变量的值(即指针)所指向的变量(内存空间)的数据类针变量的值(即指针)所指向的变量(内存空间)的数据类型。其一般形式为:型。其一般形式为: 类型标识符类型标识符 *变量名变量名; 其中,其中,*表示变量名是指针变量,类型标识符即基类型。表示变量名是指针变量,类型标识符即基类型。 例如:例如:int *p1; 表示表示p1是一个指针变量,它可以用来存放是一个指针变量,它可以用来存放某个整型变量的地址,也可以说某个整型变量的

59、地址,也可以说“p1是一个指向整型变量的是一个指向整型变量的指针变量指针变量”,或,或“p1为整型指针变量为整型指针变量”。至于。至于p1究竟指向哪究竟指向哪一个整型变量,应由向一个整型变量,应由向p1赋予的地址来决定。赋予的地址来决定。 int a=6;int *p=&a;p a&a6上海师范大学 计算机系2022年6月22日星期三第4章 数 组第41页4.3.2 与指针有关的运算与指针有关的运算 指针作为一种数据类型,可进行某些运算,但其运算的种类指针作为一种数据类型,可进行某些运算,但其运算的种类比较有限。它比较有限。它只能只能进行进行赋值运算赋值运算和和部分算术运算部分

60、算术运算及及关系运算关系运算。1、指针赋值运算、指针赋值运算 指针变量同普通变量一样,在使用之前不仅要定义,而且必指针变量同普通变量一样,在使用之前不仅要定义,而且必须赋予具体的值。须赋予具体的值。未经赋值的指针变量不能使用,否则将造未经赋值的指针变量不能使用,否则将造成系统混乱成系统混乱。指针变量的。指针变量的赋值运算有以下几种形式赋值运算有以下几种形式:(1) 指针变量在定义时进行初始化赋值。例如:指针变量在定义时进行初始化赋值。例如: int a,*pa=&a;(2) 把一个变量的地址赋予基类型与它相同的指针变量。例如:把一个变量的地址赋予基类型与它相同的指针变量。例如: int a,*pa; pa=&a; (3) 两个基类型相同的指针变量可相互赋值。例如:两个基类型相同的指针变量可相互赋值。例如: int a,*pa=&a,*pb; pb=pa; 上海师范大学 计算机系2022年6月22日星期三第4章 数 组第42页4.3.2 与指针有关

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论