《C语言程序设计》课件第5章_第1页
《C语言程序设计》课件第5章_第2页
《C语言程序设计》课件第5章_第3页
《C语言程序设计》课件第5章_第4页
《C语言程序设计》课件第5章_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

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

文档简介

第5章数组5.1一维数组

5.2二维数组

5.3字符数组

5.1一维数组

5.1.1一维数组的定义格式

一维数组的定义格式如下:

类型说明符

数组名[常量表达式];

例如,语句“floata[6],b[10];”表示定义了一个可存放6个float类型数据的一维数组a和一个可存放10个float类型数据的一维数组b。

说明:

(1)数组名应符合标识符的命名规则,例如a12、gain_ratio是合法的数组名。

(2)方括号内的常量表达式表示数组元素的个数,即数组长度。可以是整型常量或整型常量表达式,也可以是符号常量,但不能包含变量。

(3)数组的数据类型既可以是基本类型,也可以是构造类型等。

(4) C编译系统为数组分配连续的内存单元。数组元素的相对次序由下标来表示。数组元素的下标是从0开始的整数。

上面定义的数组a的存储示意图如图5.1所示。图5.1数组的存储示意图5.1.2一维数组的引用

在C语言中不能引用整个数组,只能引用单个数组元素。一个数组元素相当于一个变量,它的使用与同类型的普通变量是相同的。但数组元素特定的引用形式会给编程带来很多方便。

一维数组元素的引用形式为

数组名[下标]

说明:

(1)数组名后面方括号内是数组下标,下标表示该元素是数组的第几个元素。数组名后面方括号内的内容只有在数组定义时才是数组的长度,其他时候都是数组下标。

(2)数组元素的下标是整型的常量、变量或表达式。下标的取值范围是0~数组长度-1的整型值。

(3) C程序运行时,编译系统并不检查数组元素的下标是否越界,需要编程人员自己保证数组元素的下标不要越界。

例如,对于语句“floata[8];intx=2;”,数组元素a[0]、a[6]、a[5+1]、a[x]、a[3*x]都是合法引用;而a[-5]、a[8]、a[5.2] 是非法的引用。注意,a[8] 虽然非法,但是编译系统不报错。对a[8]的操作实际是对内存其他空间的操作,因此可能造成严重后果。5.1.3一维数组的初始化

数组的初始化就是给数组元素赋初值。数组的初始化操作既可以在数组定义之后进行,也可以在数组定义时进行。

如果在数组定义之后进行初始化操作,则只能对每个数组元素一一赋值。例如:

intarr[10],i;

for(i=0;i<10;i++)arr[i]=i;

如果在定义数组时完成数组的初始化操作,则需要将数组元素的初值依次放在一对花括号中,并用赋值符号与数组连接。定义数组时赋初值的形式为

类型说明符数组名[常量表达式]={初值列表};说明:

(1)花括号内各个初值之间用逗号分隔,数值类型必须与数组类型一致。系统将按初值的排列顺序给数组元素赋值。例如,语句“intarr[10]={0,1,2,3,4,5,6,7,8,9};”在定义数组arr的同时,将0、1、2、3、4、5、6、7、8、9依次赋给数组元素arr[0]、arr[1]、arr[2]、arr[3]、arr[4]、arr[5]、arr[6]、arr[7]、arr[8]、arr[9]。

(2)花括号中初值的数量必须小于等于数组长度。当初值数量小于数组长度时,数值型数组的后面没有初值的元素由系统自动赋值为0。例如,对于语句“intarr[6]={0,1,2};”arr[0]、arr[1]、arr[2] 的值依次为0、1、2,其他元素即arr[3]、arr[4]、arr[5] 的值均为0。

(3)若给数组的所有元素赋初值,可以省略数组的长度。系统会根据所赋初值的个数确定数组的长度。例如,语句“intarr[]={1,2,3,4,5,6,7,8,9,10};”定义数组arr的长度为10,相当于语句“intarr[10]={1,2,3,4,5,6,7,8,9,10};”。

5.1.4一维数组应用举例

【例5.1】

求10个整数的平均值。

问题分析:首先输入10个整数,然后对这10个整数求和,再求平均值,最后输出结果。

程序如下:程序运行结果如图5.2所示。图5.2例5.1的运行结果

【例5.2】

编写程序,找出10个整数中的最小值及其位置。

问题分析:首先输入10个整数,然后找出其中的最小值及其位置,最后输出结果。其中最主要的功能是求最小值及其位置,完成这一功能的主要步骤如下:

(1)定义变量min以记录最小值的位置,即下标号,程序开始时假定第一个数为最小值,也就是位置min为0;

(2)将min位置的数和数组的下一个数进行比较,如果下一个数更小,则更改min值为更小数的位置;

(3)比较完数组中所有的数,位置min上的数就是最小值,否则转向步骤(2)继续执行。

假设数组x的10个数依次为3、2、7、1、4、8、5、11、4、9,则寻找最小值及其位置的过程应该为

同样的方式将x[min] 依次与x[5]、x[6]、x[7]、x[8]、x[9] 相比较。每次比较均为x[min] 小,因此min值不变,最终min的值为3。图5.3例5.2的运行结果类似地,请思考如何查找一个数列中最大值的位置。

【例5.3】

在递减的有序数列中,插入一个数x,使得数列仍然有序(如果有相同的数则不插入)。

问题分析:本题相当于在一个有序的数组中寻找合适的位置插入一个元素。问题的解决可分为两个步骤:

(1)寻找插入位置:由于是递减的序列,所以插入位置应该是在第一个小于x的数组元素的前面(假定找到的位置为k);

(2)如果第k个元素等于x,则不须插入,否则执行插入操作:

①第k个元素及其后面的元素都后移一位。

②插入元素在k位置。

程序如下:图5.4例5.3的运行结果请思考:移动元素可不可以从前面的元素开始移动(即先移动插入位置的元素,最后移动最后一个元素)?为什么?如果可以有重复数据,程序该如何编写?

【例5.4】

用冒泡法对10个数进行排序(由小到大)。冒泡法思路是:从前到后扫描数据序列,比较相邻两个数的大小,将小的数调到前头,大的数沉底。假设对6个数据进行排序的过程如图5.5所示。图5.5冒泡法排序原理图问题分析:假设有6个数据,第一次将8和9进行比较后对调,第二次将9(下沉了一位)和5进行比较后对调……直到所有的数均比较完毕后,9已沉到了最底层,这时,最小的数0上浮了一位,经第一趟(共5次)后,已得到最大的数。然后进行第二趟对余下来的数据进行比较,第二趟要比第一趟少比较1次,即只需4次即可比较出最大的数。依次类推,比较完毕后得到的就是按顺序排列的数据。

对10个数排序的程序如下:运行结果如图5.6所示。图5.6例5.4的运行结果 5.2二维数组

含有两个下标的数组称为二维数组,其中的数据是按照行列的格式排列的,即数据分为若干行、若干列。C语言规定:二维数组的行下标和列下标均是从0开始的。

5.2.1二维数组的定义格式

二维数组的定义格式如下:

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

例如,语句“intb[4][3];”表示定义了一个具有4行3列的整型数据的二维数组b。说明:

(1)二维数组定义中,数组名、数据类型的定义方式和一维数组相同,不同的只是数组名后面紧跟两个方括号;两个常量表达式,常量表达式1表示数组的行数,常量表达式2表示每行数据的个数,即列数。数组的元素个数就是两个常量表达式之积。

(2)二维数组只是在逻辑上是二维的,从存储上看,二维数组仍然存储在一维线性空间。C语言中,按照行优先方式存储二维数组,即先存放第0行的元素,再连续存放第1行的元素……例如,上面定义的b是一个4行3列的数组,它在内存中的存储示意图如图5.7所示,它是一维线性存储空间。图5.74行3列的数组在内存中的存储示意图5.2.2二维数组的引用

二维数组也只能引用单个数组元素,不能引用整个数组。二维数组元素的引用形式为

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

二维数组的下标可以是整型的变量、常量或表达式。第一维下标的取值范围是0~第一维长度 -1,第二维下标的取值范围是0~第二维长度 -1。例如,在语句“intb[4][3];”之后引用数组b的元素b[0][2]、b[1+1][1]、b[i][j](i、j为整型变量)是合法的引用方式,而b[2][3]、b[1.2][2]、b[6][0]、b[1,2]、b[2],[0]、b(1,2)、b(3)(1)是非法的引用方式。花括号内各个初值之间用逗号分隔,初值类型必须与数组类型一致。系统自动按数组元素在内存的顺序将初值依次赋给相应的元素。数值型数组的初值数量不足时,将0赋给其余数组元素。例如,语句“intx[2][3]={1,2,3,4,5};”之后,系统自动按数组x的元素在内存的顺序将初值依次赋给相应的元素,即x[0][0]=1,x[0][1]=2,x[0][2]=3,x[1][0]=4,x[1][1]=5。其余元素被自动赋值为0,如x[1][2]=0。

(2)赋初值时,每一行的初值放在一个花括号中,所有行的初值再放在一个花括号中。具体格式为

类型说明符数组名[常量表达式1][常量表达式2]={{第0行初值列表},{第1行初值列表},…};系统将第一个花括号内数据依次赋值给数组的第0行,将第二个花括号内数据依次赋值给数组的第1行,依次类推。例如,语句“intx[4][4]={{1,2,3,4},{4,5,6},{},{7}};”之后,系统将1、2、3、4依次赋给x[0][0]、x[0][1]、x[0][2]和x[0][3];4、5、6依次赋给x[1][0]、x[1][1]和x[1][2],没有列出初值的元素系统自动赋0;对应第2行的“{}”,系统给x[2][0]、x[2][1]、x[2][2]和x[2][3]均赋值0;第3行对应{7},则系统将7赋值给x[3][0],而x[3][1]、x[3][2]和x[3][3]均被系统赋值为0。5.2.4二维数组应用举例

【例5.5】

将一个二维数组行和列元素互换后,存到另一个二维数组中,如图5.8所示。图5.8二维数组元素互换示意图图5.9例5.5的运行结果

【例5.6】

编写程序:求一个M行N列的矩阵和一个N行W列的矩阵的乘积。

M行N列的矩阵A与N行W列的矩阵B相乘,乘积矩阵C为M行W列,其元素的计算公式为

程序运行结果如图5.10所示。图5.10例5.6的运行结果

【例5.7】

编程序查找矩阵的鞍点并输出。所谓矩阵的鞍点,就是其值在所在行最小,而在所在列最大的元素。

问题分析:根据鞍点的定义,每行都可能有一个鞍点,所以要逐行查找。查找第i行鞍点的过程可分为两个步骤:

(1)找出第i行最小值的列位置k。

(2)判断第i行第k列元素在第k列是否最大。如果最大则是鞍点;如果不是,则第i行中无鞍点。判断是否为最大值的方式是看是否有比a[i][k]大的值。

程序如下:输入了以下一个有鞍点矩阵后的运行结果如图5.11所示。

图5.11例5.7的运行结果 5.3字符数组

5.3.1字符数组的定义和引用

字符数组是指数组元素为字符型的数组。字符数组的定义、引用、初始化方式和其他类型数组非常类似。但是由于字符数组是文字型数据,因此其使用方式又有不同之处。

一维字符数组的定义格式为

char数组名[常量表达式];

如果需存放多个字符串,则需要定义二维字符数组。二维字符数组的定义格式为

char数组名[常量表达式1][常量表达式2];字符数组元素也可通过数组名和下标引用。

字符数组也可以在定义时初始化,方法和其他类型的数组一样,例如:

charstr1[3][8]={{'r','e','d'},{'y','e','l','l','o','w'},{'g','r','e','e','n'}};

注意:若没有对字符数组全部元素赋值,编译系统会对剩余的元素自动赋值为空字符。空字符用'\0'来表示,它是ASCII码值为0的字符,表示什么都不做,也不显示。

在定义字符数组之后,只能逐个给数组元素赋值,例如:

charstr2[8];

str2[0]='a';str2[1]='b';str2[2]='c';str2[3]='d';

对字符数组元素的操作只要符合字符类型的操作规则即可。图5.12例5.8的运行结果如果输入“AF5ab#$djaxf!”,则程序的运行结果如图5.13所示。图5.13例5.9的运行结果5.3.2字符串和字符数组

1.字符串的表示

编程者用字符数组处理字符串时,关心的不是数组的长度,而是有效字符串的长度。C语言中不保存字符串的长度,因此需要在字符串末尾加字符串结束标志

空字符'\0'以表示字符串结束。对于字符串常量,编译系统处理时会自动在字符串末尾处加上'\0'。因此,含有n个字符的字符串常量在内存中占n+1个字节的空间,第n+1个字节存放'\0'。例如,"s"表示含有一个字母s的字符串,在内存保存的是字母s和空字符'\0'的ASCII码值,占两个字节。""表示空串,在内存中保存的是空字符'\0'的ASCII码值,占一个字节。""表示一个含有一个空格的字符串,在内存中占两个字节;''表示空格字符,在内存中占一个字节。图5.14例5.10的运行结果

2.字符串常量赋给字符数组

若在定义字符数组的同时赋初值,则可将字符串常量赋给该字符数组。例如:

charc[20]={"Thegreatwall"};

习惯上可以省略花括号,上面定义写为

charc[20]="Thegreatwall";

数组c在内存中存储的示意图如图5.15所示。图5.15数组c在内存中存储示意图说明:

(1)若定义字符数组时完成赋初值,则可以在定义中省略数组的长度。系统会根据所赋字符串常量的实际长度来确定字符数组的长度。如上述定义也可写为

charc[]="Thegreatwall";

系统会自动确定数组c的长度为15。

(2)字符串常量末尾处有系统自动加的结束标志'\0',所以要求数组长度比字符串长度至少大1。例如:

charc[14]="Thegreatwall";

这条语句中数组c不能满足字符串长度。

(3)除了数组定义时可以将字符串直接付给字符数组外,其他时刻只能对元素进行赋值。例如,不能用语句“c="string";”对字符数组c赋值。图5.16例5.11的运行结果

(注意这里Γ↔☺是四个未知字符造成的)

charstr1[]="Thisisastring";和charstr2[]={'T','h','i','s','','i','s','','a','','s','t','r','i','n','g','\0'}是等效的,在内存中存储了字符串 "Thisisastring" 和一个 '\0',数组长度都为17。但charstr3[]={'T','h','i','s','','i','s','','a','','s','t','r','i','n','g' }这条语句在内存中存放了'T'、'h'、'i'、's'、''、'i'、's'、''、'a'、''、's'、't'、'r'、'i'、'n'、'g' 共16个字符,数组长度为16。因为输出str3时没有找到结束标志,超出了数组范围,所以输出了四个未知字符。5.3.3常用字符串处理函数

为了简化程序设计的复杂度,C语言提供了大量处理字符串的库函数。这里仅介绍几个常用的函数。

1.字符串输入函数gets

1)格式

gets(字符数组)

2)功能

接收从键盘输入的一个字符串(可包含空格)并存放在字符数组中。函数的返回值是字符数组的起始地址。

温馨提示

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

最新文档

评论

0/150

提交评论