c语言 大学 第5章课后答案.docx

上传人:b****5 文档编号:29537175 上传时间:2023-07-24 格式:DOCX 页数:38 大小:117.36KB
下载 相关 举报
c语言 大学 第5章课后答案.docx_第1页
第1页 / 共38页
c语言 大学 第5章课后答案.docx_第2页
第2页 / 共38页
c语言 大学 第5章课后答案.docx_第3页
第3页 / 共38页
c语言 大学 第5章课后答案.docx_第4页
第4页 / 共38页
c语言 大学 第5章课后答案.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

c语言 大学 第5章课后答案.docx

《c语言 大学 第5章课后答案.docx》由会员分享,可在线阅读,更多相关《c语言 大学 第5章课后答案.docx(38页珍藏版)》请在冰豆网上搜索。

c语言 大学 第5章课后答案.docx

c语言大学第5章课后答案

第5章数组

大家在前面的章节中已经碰到过这样的例子:

求两个整数中的较小的那个,或者求三个整数中的最小数。

那么大家想一下,如果题目中要求大家找出10个整数中的最小数呢,甚至100个整数中的最小数呢?

在计算机应用领域中,也常常遇到这类处理大量数据的问题,其特点也是:

数据量很大,数据之间存在一定的内在关系。

那么,对于这样的一组数据,计算机如果用前面讲过的简单变量来处理就很不方便,甚至不能处理。

考虑上面的求出10个整数中的最小数,先要设10个变量a1,a2,a3……a10,然后这10个变量之间又要相互比较,求出最小数。

显然是非常麻烦,要是成千上万个数据,是不是还要设一万个变量呢?

为了解决这一问题,C语言引入了一个重要的数据结构——数组,它是具有相同数据类型的变量集合,这些变量具有相同的名字,但用不同的下标表明数据的位置,我们称这些变量为数组元素。

将数组与循环结合起来,可以有效地处理大批量的数据,大大提高了工作效率,十分方便。

本章介绍在C语言中怎样定义和使用数组,包括一维数组,二维数组和字符串。

5.1一维数组

5.1.1一维数组的定义和引用

例5-1要求从键盘中输入10个互不相同的整数,求其中的最小数并输出。

10#include"stdio.h"

20main()

30{

40inta[10];/*定义数组a*/

50inti,min;/*定义变量i和min*/

60for(i=0;i<=9;i++)/*循环10次*/

70scanf("%d",&a[i]);/*从键盘输入数给数组元素赋值*/

80for(i=0;i<=9;i++)/*循环10次*/

90printf("%d\t",a[i]);/*输出数组元素的值*/

100min=a[0];/*给min变量赋初值*/

110for(i=1;i<=9;i++)/*循环9次*/

120if(min>a[i])

130min=a[i];/*比较min与数组中的每个数的大小,将较小的赋给min*/

140printf("Theminis%d\n",min);/*输出最小值*/

150}

该程序的流程图如图5-1所示。

图5-1例5-1的流程图

运行结果:

4512893564715679

4512893564715679

Theminis3

程序说明:

(1)行号为40的语句“inta[10];”是数组的定义。

表示定义一个名为a的数组,其中这个数组里包含10个元素,均为整型。

(2)行号为70,90,100,120和130的语句都是对该数组的引用。

1.一维数组的定义

在C语言中使用数组必须先进行定义。

一维数组的定义方式为:

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

其中:

(1)类型说明符是任一种基本数据类型或构造数据类型,即int、float、char等这些基本数据类型。

从这里可以看出,数组是建立在基本数据类型的基础之上的,因此数组为构造类型。

在上面的例子中int表示数组元素为整型数据。

(2)数组名是用户定义的数组标识符。

对于数组元素来说,具有一个共同的名字,即数组名,用标识符表示,上面例子中a为一维数组名。

(3)方括号中的常量表达式表示数据元素的个数,也称为数组的长度。

例如:

floatb[10],c[20];定义实型数组b,有10个元素,实型数组c,有20个元素。

charch[20];定义字符数组ch,有20个元素。

对于数组定义应注意以下几点:

(1)数组的类型实际上是指数组元素的取值类型。

对于同一个数组,其所有元素的数据类型都是相同的。

(2)数组名不能与其它变量名相同。

例如:

main()

{

inta;

floata[10];

……

}

是错误的。

(3)方括号中常量表达式表示数组元素的个数,如a[5]表示数组a有5个元素。

但是其下标从0开始计算。

因此5个元素分别为a[0],a[1],a[2],a[3],a[4]。

(4)不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。

例如:

#defineD5

main()

{

inta[3+5],b[4+D];/*合法的定义*/

……

}

但是下述说明方式是错误的。

main()

{

intn=10;

inta[n];/*不合法的定义,n为变量*/

……

}

2.一维数组元素的存储

每个数组元素都占用内存中的一个存储单元,每个元素都是一个变量,可以像以前讲过的普通变量一样使用,只不过数组元素是通过数组名和方括号“[]”里的下标来确定的。

系统为数组元素在内存中分配连续的存储单元。

例如:

定义语句inta[15];说明了以下几个问题:

(1)数组名为a。

(2)数组元素的数据类型为int整型数据。

(3)数组元素的下标值从0开始。

数组元素的个数为15个,它们是:

a[0]、a[1]、a[2]....a[13]、a[14]

(4)数组名a是数组存储区的首地址,即存放数组第一个元素的地址。

a&a[0];因此数组名是一个地址常量。

不能对数组名进行赋值和进行运算。

这个例子中数据元素的存储形式如图5-2所示。

a[0]

a[1]

a[2]

a[3]

……

a[12]

a[13]

a[14]

内存地址内存数组元素

2000

2002

2004

2006

……

2026

20282030

图5-2一维数组的存储形式

3.一维数组元素的引用

数组的引用就是对数组元素(数据)的读取操作。

数组的引用与变量的引用类似,数组的引用也是先定义后引用。

与变量不同的是不能对数组整体进行(读取)操作,只能对数组的元素进行操作。

一维数组的引用格式:

数组名[下标]

其中:

(1)下标可以是常量或常量表达式,如a[3]、a[3+2]。

(2)下标也可以是变量或变量表达式,如a[i],a[i+j],a[i++]。

(3)下标如果是表达式,首先计算表达式,计算的最终结果为下标值。

(4)引用时,下标值若不是整型,C系统会自动取整,a[5.3]相当于a[5]。

(5)下标值从0开始。

而不是从1开始。

(5)数组的引用下标不能越限,即引用时的下标不能超过或等于定义时的下标值。

如inta[10];a[10]=4;是错误的。

例5-2有等差数列an=3n,要求输出an的所有值,并求出数列的和。

n为0到9的整数。

#include"stdio.h"

main()

{

inta[10];/*定义数组a*/

intn,sum=0;/*定义变量n和sum*/

for(n=0;n<=9;n++)/*循环10次*/

{

a[n]=3*n;/*给数组元素赋值*/

printf("a[%d]=%d\t",n,a[n]);/*输出数组元素*/

sum+=a[n];/*将数组元素作累加*/

}

printf("sum=%d\n",sum);/*输出累加和*/

}

运行结果:

a[0]=0a[1]=3a[2]=6a[3]=9a[4]=12a[5]=15a[6]=18a[7]=21a[8]=24a[9]=27

sum=135

5.1.2一维数组的初始化

与一般变量的初始化一样,数组的初始化就是在定义数组的同时,给其数组元素赋初值。

数组初始化是在编译阶段进行的。

这样将减少运行时间,提高效率。

初始化赋值的一般形式为:

类型说明符数组名[常量表达式]={数值1,数值2……数值n};

其中在{}中的各数据值即为各元素的初值,各值之间用逗号间隔。

例如:

inta[3]={0,1,2};相当于a[0]=0;a[1]=1;a[2]=2;C语言对数组的初始化有以下几点规定:

(1)可以只给部分元素赋初值。

当{}中值的个数少于元素个数时,只给前面部分元素赋值。

例如:

inta[10]={0,1,2,3,4};相当于只给a[0],a[1],a[2],a[3],a[4]赋初值,而后5个元素自动赋0值。

(2)只能给元素逐个赋值,不能给数组整体赋值。

例如给十个元素全部赋1值,只能写为:

inta[10]={1,1,1,1,1,1,1,1,1,1};而不能写为:

inta[10]=1;

(3)如给全部元素赋值,则在数组说明中,可以不给出数组元素的个数。

例如:

inta[5]={1,2,3,4,5};可写为:

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

(4)花括号{}中数值的个数多于数组元素的个数是语法错误。

5.1.3一维数组应用举例

例5-3兔子问题(它是中世纪最杰出的数学家Fibonacci提出的):

如果一对兔子每月能生一对小兔(一雄一雌),而每对小兔在出生后的第三个月里,又能开始生一对小兔,假定在不发生死亡的情况下,由一对出生的小兔开始,2年后有多少对兔子?

这就是著名的斐波纳契数列。

根据题意,以f[n]表示n个月以后兔子的总对数,其规律为f[n]=f[n-2]+f[n-1],如此构成的数列

f[1]=1,f[2]=1,f[3]=2,f[4]=3,f[5]=5,……,f[n]=f[n-2]+f[n-1],……

根据上述题目的要求,可以写成下面的程序。

流程图如图5-3所示。

#include"stdio.h"

main()

{intn,f[25];/*定义变量*/

f[1]=f[2]=1;/*赋初值*/

for(n=3;n<=24;n++)

f[n]=f[n-1]+f[n-2];/*计算f[n]的值*/

for(n=1;n<=24;n++)

{if((n-1)%4==0)

printf("\n");/*每输出四个数后换行*/

printf("%10d",f[n]);/*输出数列中所有的值*/

}

}

运行结果:

1123

581321

345589144

233377610987

1597258441816765

10946177112865746368

图5-3例5-3的流程图

很多数列的问题都可以类似于上述的斐波纳契数列的计算方法,用数组来进行存储和计算。

例5-4任意给n个数,按由小到大对其排序,并输出结果。

采用“冒泡”排序法。

“冒泡”排序法的思路:

将相邻两个数比较,将小的数调到前头(或将大的数调到后面)。

若有5个数,分别是7,6,10,4,2,依次将其放入数组a中。

我们看一下冒泡排序法的处理过程:

(1)第一趟(如图5-4所示),经过4次比较。

第1次:

将第1个数a[0]和第2个数a[1]进行比较,将较小的数调到前面,也就是说,若后面的数小,就将两数交换,否则不交换。

级7和6对调位置。

结果如图5-4(b)所示。

第2次:

将第2个数a[1]和第3个数a[2]进行比较,将较小的调到前面。

也就是7和10比较,这次比较不用对调位置。

结果如图5-4(c)所示。

第3次:

将第3个数a[2]和第4个数a[3]进行比较,将较小的调到前面。

也就是10和4比较后对调位置。

结果如图5-4(d)所示。

第4次:

将第4个数a[3]和第5个数a[4]进行比较,将较小的调到前面。

也就是10和2比较后对调位置。

结果如图5-4(e)所示。

第1次第2次第3次第4次第一趟结果

a[0]

a[1]

a[2]

a[3]

a[4]

(a)(b)(c)(d)(e)

图5-4冒泡排序第一趟过程

如此进行共4次,结果得到6-7-4-2-10的顺序,最大的数10成为最下面的一个数.最大的数位置“沉底”,最小的数2向上“浮起”一个位置(冒第一个泡)。

这四次处理过程都是类似的,都是“相邻两数比较,若后面的数小,则两数交换,否则不交换”;所不同的是“比较的两个数,他们的位置不同”,先是a[0]和a[1]比较,再是a[1]和a[2]比较,再是a[2]和a[3]比较,最后是a[3]和a[4]比较,大家会发现一个规律,每次比较位置往后移了一位,所以我们可以用一个变量i控制,每次都是a[i]和a[i+1]比较,而每次比较完后i+1,总共比较4次,这样我们就可以用一个循环来实现,即:

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

if(a[i]>a[i+1])

{

temp=a[i];a[i]=a[i+1];a[i+1]=temp;

}

(2)第二趟(如图5-5所示),经过3次比较。

经过第一趟后最大数10已经沉到底了,第二趟就对余下的四个数(6-7-4-2)按上述的方法,经过三次比较,得到次大的数。

次大的数7“沉底”,最小数2又向上“浮起”一个位置(冒第二个泡),结果得到:

6-4-2-7的顺序。

第1次第2次第3次第二趟结果

a[0]

a[1]

a[2]

a[3]

(a)(b)(c)(d)

图5-5冒泡排序第二趟过程

这趟比较的代码跟第一趟几乎一样,不一样的是比较的次数不一样,那就是循环次数不一样,这趟循环3次。

用循环语句实现如下:

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

if(a[i]>a[i+1])

{

temp=a[i];a[i]=a[i+1];a[i+1]=temp;

}

(3)第三趟(如图5-6所示),经过2次比较。

对余下的三个数(6-4-2)按上述方法,经过两次比较,得到第三大数6“沉底”,最小数2又“浮起”一个位置(冒第三个泡)。

第1次第2次第三趟结果

a[0]

a[1]

a[2]

(a)(b)(c)

图5-6冒泡排序第三趟过程

这趟比较代码同上类似,循环次数变成2次。

(3)第四趟(如图5-7所示),经过1次比较。

对余下的三个数(4-2)按上述方法,经过1次比较,得到第四大数4“沉底”,最小数2又“浮起”一个位置(冒第四个泡)。

第1次第四趟结果

a[0]

a[1]

(a)(b)

图5-7冒泡排序第四趟过程

最后得到5个数的排序结果:

2-4-6-7-10(从小到大)。

从上面的四趟处理过程中可以看出,每一趟都很类似,都是“最大的数位置下沉,最小数向上浮起一个位置”;所不同的是“每趟比较的次数不同”,第一趟4次,第二趟3次,第三趟2次,第四趟1次,所以我们引入“趟次”循环变量j,一共需要4趟,故j从1到4,二每趟比较的次数都是5-j。

因此,我们可以用两个for循环来实现,“趟次”循环变量j作为外层循环控制变量,每趟里面的次数作为内循环:

for(j=1;j<=4;j++)/*j是趟次循环变量(外循环变量)*/

for(i=0;i<5-j;i++)/*i是每趟中两两比较的次数变量(内循环变量)*/

if(a[i]>a[i+1])

{

temp=a[i];a[i]=a[i+1];a[i+1]=temp;

}/*比较相邻两数大小,将较小的数放在前面*/

也就是说“冒泡”排序最重要的是在确定趟数和每趟的次数。

我们来分析一下:

其一,需要比较的趟数——5个数需要冒4个泡,即比较4趟,所以n个数要比较(n-1)趟。

其二,每趟比较次数——五个数排序,第一趟比较4次,第二趟比较3次,第三趟比较2次,第四趟比较1次,得出规律“n个数排序,第j趟要比较n-j次”。

综上所述,n个数需要进行n-1趟比较,在第j趟的比较中要进行n-j次两两比较。

所以任意n个数进行排序,程序如下:

#include"stdio.h"

#defineN10/*定义符号常量,对几个数排序,N的值就是几*/

main()

{inta[N];

inti,j,t;

printf("input10numbers:

\n");

for(i=0;i

scanf("%d",&a[i]);

printf("\n");

for(j=1;j

for(i=0;i

if(a[i]>a[i+1])/*比较相邻两数大小,将较小的数放在前面*/

{t=a[i];

a[i]=a[i+1];

a[i+1]=t;

}

printf("thesortednumbers:

\n");

for(i=0;i

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

}

运行结果:

input10numbers:

102348796520

thesortednumbers:

234567891020

5.2二维数组

5.2.1二维数组的定义和引用

前面介绍的数组只有一个下标,称为一维数组,其数组元素也称为单下标变量。

在实际问题中有很多量是二维的或多维的,比如最常见的矩阵就是二维的,因此C语言允许构造多维数组。

多维数组元素有多个下标,以标识它在数组中的位置,所以也称为多下标变量。

本小节只介绍二维数组,多维数组可由二维数组类推而得到。

1.二维数组的定义

二维数组定义的一般形式是:

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

其中常量表达式1表示第一维下标的长度,常量表达式2表示第二维下标的长度。

说明:

(1)类型说明符、数组名的说明同一维数组的说明。

(2)下标为整型常量或整型常量表达式。

(3)数组元素个数为:

常量表达式1常量表达式2。

(4)下标值从0开始。

例如:

intx[2][3];x是二维数组名,这个二维数组共有6个元素(2×3=6),它们是:

x[0][0],x[0][1],x[0][2],x[1][0],x[1][1],x[1][2]。

其全部元素数值均为整型的。

2.二维数组的存储

二维数组在概念上是二维的,比如说矩阵,但是存储器单元是按一维线性排列的。

如何在一维存储器中存放二维数组,可有两种方式:

一种是按行排列,即放完一行之后顺次放入第二行。

另一种是按列排列,即放完一列之后再顺次放入第二列。

在C语言中,二维数组是按行排列的。

如:

intx[2][3];先放第一行,即x[0][0],x[0][1],x[0][2],再放第二行,即x[1][0],x[1][1],x[1][2]。

如图5-8所示。

x[0][0]

x[0][1]

x[0][2]

x[1][0]

x[1][1]

x[1][2]

图5-8二维数组的存储

3.二维数组的引用

同一维数组一样,二维数组也要先定义、后引用;不能对一个二维数组的整体进行引用,只能对具体的数组元素进行引用。

其引用的格式为:

数组名[下标1][下标2]

说明:

(1)下标可以是常量(大于等于0)、常量表达式、变量或变量表达式。

(2)数组中要特别注意下标越限。

因为有的程序编译系统不检查数组下标越限问题,所以程序设计者应特别注意。

例如:

a[3][4],表示a数组第三行四列的元素。

下标变量和数组说明在形式中有些相似,但这两者具有完全不同的含义。

数组说明的方括号中给出的是某一维的长度,即可取下标的最大值;而数组元素中的下标是该元素在数组中的位置标识。

前者只能是常量,后者可以是常量,变量或表达式。

5.2.2二维数组的初始化

二维数组的初始化即定义数组的同时对其元素赋值,初始化有两种方法。

(1)把初始化值括在一对大括号内,例如二维数组intx[2][3]={1,2,3,4,5,6};初始化结果是:

x[0][0]=1,x[0][1]=2,x[0][2]=3,x[1][0]=4,x[1][1]=5,x[1][2]=6。

(2)把多维数组分解成多个一维数组,也就是把二维数组可看作是一种特殊的一维数组,该数组的每一个元素又是一个一维数组。

例:

intx[2][3];可把数组x看成是具有两个元素的一维数组,其元素是x[0]和x[1]。

而每个元素x[0]、x[1]又都是具有三个元素的一维数组,其元素是:

x[0][0]、x[0][1]、x[0][2]、x[1][0]、x[1][1]、x[1][2]。

x:

x[0]:

x[0][0],x[0][1],x[0][2];

x[1]:

x[1][0],x[1][1],x[1][2]。

因此,上例二维数组的初始化可分解成多个一维数组的初始化:

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

对于二维数组初始化赋值还有以下几点说明:

(1)可以只对部分元素赋初值,未赋初值的元素自动取0值。

例如:

intx[2][2]={{1},{2}};是对每一行的第一列元素赋值,未赋值的元素取0值。

赋值后各元素的值为:

x[0][0]=1,x[0][1]=0,x[1][0]=2,x[1][1]=0。

(2)如对全部元素赋初值,则第一维的长度可以不给出。

例如二维数组x的初始化过程:

intx[2][3]={1,2,3,4,5,6};也可写成:

intx[][3]={1,2,3,4,5,6};即第一下标值省略,但第二下标值不能省略。

5.2.3二维数组应用举例

例5-5一个学习小组有5个人,每个人有三门课的考试成绩。

求全组分科的平均成绩和总平均成绩。

学生的成绩表如表5-1所示。

表5-1学生成绩表

课程

Math

80

61

59

85

76

C语言

75

63

67

89

72

英语

90

72

74

80

82

分析:

可设一个二维数组a[5][3]存放五个人三门课的成绩。

再设一个一维数组v[3]存放所求得各分科平均成绩,设变量average为全组总平均成绩。

流程图如图5-9所示。

图5-9例5-5流程图

代码如下:

#include"stdio.h"

main()

{

inti,j,s=0,average,v[3];

inta[5][3]={{80,75,90},{61,63,72},{59,67,74},{85,89,80},{76,72,82}};/*初始化*/

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

{

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

s=s+a[j][i];/*各科的分数累加*/

v[i]=s/5;/*各科平均分*/

s=0;

}

average=(v[0]+v[1]+v[2])/3;/*总平均分*/

printf("math:

%d\nclanguag:

%d\nenglish:

%d\n",v[0],v[1],v[2]);

printf("total:

%d\n",average);

}

例5-6编写一个程序实现34的矩阵的转置。

矩阵转置是把矩阵的行和列互换,如:

1234

5678

9101112

转置后变成43的矩阵:

159

2610

3711

4812

程序如下:

#include"stdio.h"

main()

{

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 成人教育 > 自考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1