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

下载本文档

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

文档简介

第6章

数组——批量数据的表示与处理6.1一维数组6.2二维数组6.3字符数组实训任务十一

熟悉数组的使用实训任务十二

学习使用数组的程序设计方法 6.1一维数组

6.1.1一维数组的定义与存储结构

一维数组定义的一般形式为

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

其中,基类型符可以是基本类型中任一种类型的关键字,如int、char、float、double等,说明了构成数组各元素的数据类型。

数组名是数组引用的标识符。命名规则同变量。

方括号中的常量表达式表示数组元素的个数,也称为数组的长度。常量表达式是指只能包含常量和符号常量,不能包含变量的表达式,即表达式具有确定的值。

定义数组就定义了数组的引用符号、元素的类型和元素的个数及元素的顺序关系。数组元素的序号是从0开始的,所以最大序号应是常量表达式的值减1。如a[5]表示数组a有5个元素,分别为a[0]、a[1]、a[2]、a[3]、a[4]。

在数组定义中需注意以下几点:

(1)常量表达式中可以使用符号常量,但不能出现变量。例如:

(2)数组长度说明只能用方括号,不能使用其他形式的括号。

(3)在一个定义语句中,可以定义一个数组,也可定义多个同一类型的数组,还可以和同一类型的变量一起定义,但各变量和数组之间要用逗号分隔。例如:

inti,j,k,a[10],b[20];

在程序中定义的数组,C语言编译系统会给数组元素分配一段连续的存储空间,每个元素按数据类型占用相同的字节数。6.1.2一维数组的初始化

定义了数组,编译系统给其分配了存储空间,但数组元素还不具有值。数组的初始化就是给数组元素提供初值。数组的初始化有以下几种情况:

(1)给全部元素赋初值。例如:

inta[5]={5,8,9,12,3};

给数组元素提供的初值要用花括号括起来,数据之间用逗号分隔。编译时,把数据依次赋给数组元素,即5赋给a[0],8赋给a[1],9赋给a[2],12赋给a[3],3赋给a[4]。

给全部元素赋值时,在数组定义中,数组元素的个数可以缺省,元素个数默认为数据的个数。定义语句可以写成

inta[]={5,8,9,12,3};

(2)只给部分元素赋初值。例如:

inta[10]={0,1,2,3};

系统将提供的数据从a[0]开始,按顺序赋给前面的元素,剩余元素无初值,即将0赋给a[0],将1赋给a[1],将2赋给a[2],将3赋给a[3],a[4]~a[9]无初值。

(3)若给全部元素赋相同初值,也只能给元素逐个赋值,不能给数组整体赋值。

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

inta[5]={1,1,1,1,1};

而不能写为

inta[5]=1;

6.1.3一维数组元素的引用

虽然数组是作为一个数据对象的,但只能引用数组的元素,而不能整体引用。对一个数组元素的引用相当于对一个变量的引用。

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

数组名[下标]

其中,下标只能为整型常量或整型表达式,如为小数,系统自动取整。

例如:a[5]、a[i+j]、a[i++]都是合法的数组元素引用形式。注意:引用数组元素时,其下标表示元素在数组中的位置信息,而数组定义时方括号中的整型常量或整型表达式表示的是元素个数。

例6.1

定义数组,依次分别给10元素赋值0~9,并逆序输出。

编程思路:这是一个数组元素引用的例子。因为数组只能按元素引用,所以赋值和输出都只能逐个元素依次来进行。

运行结果:

分析:从程序可以看出,利用循环实现了数组逐个元素赋初值和输出。数组的下标变量与循环的控制变量使用一个变量i,利用循环规律能方便地实现数组元素的引用。6.1.4一维数组的应用程序设计

例6.2

定义一个具有10个元素的一维数组,输入元素的值,并输出其中最大值。

编程思路:利用循环输入10个数,一次赋给数组元素。求10个元素中的最大数,可定义一个存放最大数的变量max,先将a[0]赋给max(暂设a[0]中的值为最大数),然后max与a[1]~a[9]比较,遇到max小于某一元素,则将该元素值赋给max,作为当前的最大数。逐个元素比较完,max中的值就是10个元素中的最大数。

运行结果:

分析:程序中第一个循环控制变量i初值为0,循环终值为9,循环10次,从键盘输入10个整数,依次赋给a[0]~a[9]。第二个循环控制变量i初值为1,循环终值为9,循环9次,从a[1]开始,与max值比较,找出最大元素。在数组处理循环中一定要注意下标越界的问题。如果将for(i=1;i<10;i++)改为for(i=1;i<=10;i++),将会出现什么情况?

例6.3

编写程序,实现用数组来产生Fibonacci数列。

编程思路:Fibonacci数列是1,1,2,3,5,8,13,…。用迭代关系式表示的数列规律为

F1=1

F2=1

Fn=Fn-2+Fn-1 (n>2)

即从第3项开始,每一项是前两项之和。

迭代处理是一类常见的数据处理问题。利用数组和循环结构能有效地实现这类问题的处理。

运行结果:

分析:数组定义时,按Fibonacci数列的形成规律,给数组前两个元素赋初值1,从第3个元素开始,由循环根据迭代公式求出。

例6.4

使用冒泡法将10个数据按由小到大的次序排序并输出。

编程思路:排序问题是数据处理的常见问题之一。冒泡法排序是最基本的排序方法。在程序中实现对n个数排序,应定义一个有n个元素的一维数组。对数组元素两两进行比较,如果符合序(前一个小于后一个),则不交换;如果不符合序(前一个大于后一个),则进行交换。如此进行n-1次比较,能找出最大的数,被交换到最后一个元素(a[n-1])中。这样的比较过程称为一轮比较。经过第1轮比较,前面n-1个元素仍是无序状态,需要进行第2轮比较。在第2轮中,对n-1个元素进行n-2次比较,可将最大的数交换到a[n-2]中。如此需要进行n-1轮比较。最后一轮变为a[1]与a[2]的比较。最后在数组中就存放了排好序的数。冒泡法排序过程如图6.1所示(图中双向箭头线表示两数比较操作)。

从算法分析可知,冒泡法排序要用两重循环来实现,外循环控制轮次,内循环实现每一轮中数组元素的两两比较。若n个数排序,设外循环控制变量为i,内循环控制变量为j,则其取值范围分别为0≤i≤n-1和0≤j≤j-i。

#include<stdio.h>

voidmain()

图6.1冒泡法排序过程运行结果:

分析:程序中用了4个for循环。第一个for循环实现输入10个待排序的数,依次赋给数组元素。第二个for循环实现输出排序前的10个数。第三个for双重循环实现对10个数排序。外层循环语句实现排序数的9轮比较,内层循环语句实现本轮排序数的两两比较,不符合序则交换。最后一个for循环语实现排序后的10个数的输出。以上排序方法如要实现数据由大到小排列,只需将第三个for中循环嵌套比较条件改为a[j]<a[j+1]即可。

例6.5

使用选择法对10个数据按由小到大排序并输出。

编程思路:选择法是对冒泡法排序的改进。冒泡法对n个数排序,相邻两数比较,只要不符合序都要进行交换。在例6.4中,每轮比较,找出一个最大数,放在最后一个数组元素中。这种方式可称为“下沉法”。换一个思路,每轮比较找出一个最小数,放在最前一个数组元素中,这种方式可称为“上浮法”。选择法排序采用“上浮法”。在内循环中,每轮比较中只将最小值元素的下标记录在一个变量中,每轮比较结束只将所记录的最小值元素与首元素进行一次交换,以减少冒泡法排序中的交换次数,提高排序效率。

分析:输入与例6.4相同的数,运行结果也相同。程序中定义变量k,记录本轮比较最小值元素的下标号。在内循环外,k赋值i,即设a[i]为最小数元素,也是本轮比较的首元素。在内循环中,a[k]与其后的元素两两比较,如有一元素a[j]比a[k]的值小,就将j记录在k中。结束内循环时,a[k]是最小元素,与a[i]进行一次交换。内循环控制变量j的初值是i+1,表示前i个元素已排好序,本轮只进行第i个元素后的n-i个元素的比较排序。

只需对程序稍作改进,即可实现数据由大到小排序的功能,读者可自行修改验证。

6.2二维数组

6.2.1二维数组的定义与存储结构

二维数组定义的一般形式为

基类型符数组名[常量表达式1][常量表达式2]

其中,基类型符和数组名的表示与作用同一维数组的定义。数组名后跟两个方括号,其中常量表达式1表示二维数组的行数,常量表达式2表示二维数组的列数。例如:

inta[3][4];

定义了一个三行四列的二维数组a,包含3×4=12个整型数据元素,即

a[0][0],a[0][1],a[0][2],a[0][3]

a[1][0],a[1][1],a[1][2],a[1][3]

a[2][0],a[2][1],a[2][2],a[2][3]

二维数组的行号和列号都是从0开始的,最大行号是常量表达式1的值减1,最大列号是常量表达式2的值减1。

在程序中定义的二维数组,C语言编译系统给各元素按所定义的数据类型分配一段连续的存储空间。与一维数组不同的是,二维数组是二维逻辑结构,但存储器是线性存储结构,二维数组是按行线性存储的,即按第1行、第2行、第3行,直到最后一行的顺序存储。

6.2.2二维数组的初始化

定义了二维数组,只说明了二维数组的符号名称、所包含元素的个数及类型,数组元素不具有值。要使数组元素具有值,需对二维数组初始化。二维数组的初始化也可以分为如下几种情况。

(1)按行分段给全部元素赋初值。例如:

inta[4][3]={{11,12,13},{21,22,23},{31,32,33},{41,42,43}};

在初值数据花括号中,把每一行的初值数据用花括号括起来,括号间也要用逗号分隔。花括号的顺序对应行顺序,花括号内数据的顺序对应列顺序。系统按行序,再按列序,把初值数据依次赋给各元素。

(2)线性连续给全部元素赋初值。例如:

inta[4][3]={11,12,13,21,22,23,31,32,33,41,42,43};

系统按二维数组的线性存储顺序把初值数据依次赋给各元素。

若定义数组时,给全部元素赋初值,则第一方括号中的行数可以缺省。例如:

inta[][3]={{11,12,13},{21,22,23},{31,32,33},{41,42,43}};

inta[][3]={11,12,13,21,22,23,31,32,33,41,42,43};

(3)按行分段给部分元素赋初值。例如:

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

系统只给4行的首元素分别赋所提供的初值,其余元素不具有初值。

若只给部分行的部分元素赋初值应采用这种方式,而且第1个方括号中的行数可以缺省,由尖括号的个数可得到行数。例如:

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

(4)线性连续给部分元素赋初值。例如:

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

系统按二维数组的线性存储顺序把提供的数据依次赋给前面的元素,剩余元素不具有初值。即第0行3个元素分别具有初值1、2、3,第1行的a[1][0]和a[1][1]分别具有初值4、5,其余元素不具有初值。

6.2.3二维数组元素的引用

对二维数组的数据处理中,也只能对其元素进行引用,不能进行整体引用。二维数组元素引用的一般形式为

数组名[行下标][列下标]

行下标和列下标只能为整型常量或整型表达式,如为小数,系统自动取整。行下标和列下标分别表示元素在数组中的行位置和列位置信息。对二维数组中一个元素的引用也如同对一个变量的引用一样。

例6.6

从键盘输入一个二维数组各元素的值,并输出。

编程思路:同一维数组一样,二维数组也只能按元素引用,给数组元素输入值和输出数组元素值都只能逐个元素依次来进行。

运行结果:

分析:从程序可以看出,利用双重循环实现了数组逐个元素值的输入和输出。数组的行下标变量、列下标变量与外内循环的控制变量结合,利用双重循环能方便地实现数组元素的引用。

6.2.4二维数组的应用程序设计

例6.7

编写程序,求4个同学3门课程的单科成绩的平均分和所有科目总的平均分,并输出。

编程思路:4个学生、3门课程成绩表属于二维数组结构数据。定义学生数据为行、课程成绩为列的二维数组,则求单科成绩平均分需按列求和。为求所有科目总的平均分,需将单科平均分保存,可将二维数组多定义一行,最后一行用于保存单科平均分。

运行结果:

分析:外循环控制变量i代表第i门课程,内循环控制变量j代表第j个学生。外循环一次,内循环执行一遍,就求出4个学生一门课程的总分。内循环结束时,求出第i门课程的平均分,存入a[4][i]中。结束外循环后,又对数组第4行元素求和除以课程门数得平均分。

运行结果:

分析:程序中用了3个双重循环。第1个双重循环实现原矩阵输出;第2个双重循环实现求转置矩阵;第3个双重循环实现转置矩阵输出。

例6.9

编写程序,在一个3 × 3矩阵中找出最大的元素,输出元素值及所在的行号和列号,并求主对角线元素值之和。

编程思路:定义一个存放最大数变量max,以及行号、列号存放变量row、colum,先将矩阵二维数组的首元素赋给max,在双重循环中,使每一元素与max比较,遇到大于max的元素,则将其值置换到max中,并将行号、列号记录在row、colum中。求对角线元素值之和是行号与列号相等的元素累加。

运行结果:

分析:对角线元素值之和,使用一个单层循环即可实现,放在外循环中。找最大元素值可在内循环中实现。在内循环外先设定首元素为最大元素。实际上,设定比矩阵中最大元素值小的一个数值就可以。

例6.10

利用二维数组打印杨辉三角形。

编程思路:定义一个二维数组,存放杨辉三角形数据。利用杨辉三角形规律形成数据,存入二维数组。杨辉三角形数组元素形成的算法是,数组的第0列和对角线元素值为1;其余各行元素是其上一行同列元素和上一行前一列元素之和。下面以5行数据为例编写程序。

运行结果:

分析:程序中第1个单层循环使第1列和对角线元素为1。第2个双重循环生成杨辉三角形的其他元素。第3个双重循环输出生成的杨辉三角形元素值。定义了常量N作数组行列数,只要修改N的定义值,可生成任意行数的杨辉三角形。

6.3字符数组

6.3.1字符数组的定义与初始化

字符数组的定义形式与数值数组的定义形式相同,只是基类型说明符用char。例如:

charc[10];

由于字符型和整型可以通用,也可以定义intc[10]来存储字符串,但这时每个数组元素在VC中占用4个字节的内存单元,会造成空间的浪费。

字符数组也可以是二维的。例如:

charc[5][10];

即为二维字符数组。字符数组也允许在定义时,对部分或全部元素进行初始化赋值。字符数组初始化是给元素提供字符常量。例如:

charc[10]={'c','','p','r','o','g','r','a','m'};

该字符数组的存储结构如图6.2所示。

图6.2字符数组的存储结构因为字符串是按字符数组存储的,所以可以用字符串对字符数组初始化,而且字符数组定义时,方括号中的长度可以缺省。用字符串初始化的字符数组可称为字符串数组。

例如:

charc[]="Cprogram";

C语言规定,一个字符串有一个字符串结束符“\0”。所以,用字符串给字符数组提供初值,系统自动在字符串最后一个字符后增加一个字节,用于存储“\0”。如c[9]中即存“\0”。字符数组与字符串数组的不同之处是,字符串数组的存储字节数比实际字符多一个。也可以定义、初始化二维字符数组。初始化的方法同数值数组,只是提供的数据为字符数据。例如:定义一个表示5行5列的“*”菱形图案的二维字符数组。

charc[5][5]={{'','','*'},{'','*','','*'},{'*','','','','*'},{'','*','','*'},{'','','*'}};

6.3.2字符数组的引用

C语言中各种类型的数组都只能按元素来引用。但字符串数组的输入/输出可以是整体方式。字符串数组用printf函数和scanf函数,使用“%s”格式符,可一次性输入/输出一个字符数组中的字符串。例如:

charc[]="CPrograme";

printf("%s",c);

scanf("%s",c);

注意,scanf中使用的是数组名。这与数组元素的引用不同,数组元素引用是地址方式。字符串输入结束后,系统也自动加存一个字符串结束符“0\”。

例6.11

输入一个字符串,然后输出,测试字符串长度。

编程思路:C语言库函数中提供了一个测试字符串函数intstrlen(str)。使用时,在程序开头要用预处理命令#include<string.h>。下面采用字符串输入/输出方式。

运行结果:

分析:程序中定义的字符数组要比输入的字符串长度大,在输入字符串时,系统自动加字符串结束符“\0”。输出时,识别到“\0”就认为字符串结束,仅输出有效字符。字符串长度测试函数也只计数有效字符。

例6.12

编写程序,输出一个钻石图形。

编程思路:钻石图形用“*”表示。定义一个二维字符数组,存放图形字符数据,采用字符数组元素输出方式。运行结果:

分析:定义字符数组,用字符初始化,字符串后没有字符串结束符“\0”,需用字符数组元素的方式输出,使用“%c”格式符。

6.3.3字符串处理函数

1.字符串输出函数puts

格式:

puts(字符数组);

功能:输出字符数组中的字符串。

2.字符串输入函数gets

格式:

gets(字符数组);

功能:从键盘输入一个字符串,存入到指定的字符数组中。当输入的字符串中含有空格时,空格也作为有效字符,只以回车作为输入结束。这是与scanf函数不同的。

3.字符串连接函数strcat

格式:

strcat(字符数组1,字符数组2);

功能:把字符数组2中的字符串连接到字符数组1中字符串的后面,并删去字符串1后的串结束标志“\0”,组成新的字符串。本函数返回值是字符数组1的首地址。应注意:字符数组1应定义足够的长度,否则不能全部装入被连接的字符串。

4.字符串拷贝函数strcpy

格式:

strcpy(字符数组1,字符串2);

功能:把字符串2拷贝到字符数组1中,字符串2可以是字符串,也可以是字符数组。串结束标志“\0”也一同拷贝。

在使用函数strcpy时应注意以下几点:

(1)字符数组1必须定义得足够大,以便容纳被复制的字符串。字符数组1至少不应小于字符串2的长度,否则不能全部装入所拷贝的字符串。

(2)字符数组1必须写成数组名形式,而字符串2可以是字符数组,也可以是字符串常量。

(3)有时也可以只复制字符串2中的前若干个字符,其具体使用格式为

strcpy(字符数组1,字符串2,m)

表示将字符串2中的前m个字符复制到字符数组1中,取代字符数组1中的前m个字符。

5.字符串比较函数strcmp

格式:

strcmp(字符串1,字符串2);

功能:对两个字符串字母逐个比较,比较对应字符的ASCII码值,函数返回比较结果。

返回值情况如下:

(1)字符串1=字符串2,返回值为0,表示两字符串每个字符都相同,字符个数也相同。

(2)字符串1>字符串2,返回大于0的正整数值,只要遇到串1的一个字符大于串2的字符,就是串1大于串2。

(3)字符串1<字符串2,返回小于0的负整数值,只要遇到串1的一个字符小于串2的字符,就是串1小于串2。

6.求字符串长度函数strlen

格式:

strlen(字符数组名);

功能:测字符串的实际长度(不含字符串结束标志“\0”)并作为函数返回值。

7.小写转大写函数strupr

格式:

strupr(字符串);

功能:将字符串中的小写字母转换为大写字母,其他字符不转换(包括大写字母和非字母)。其中“字符串”可以是字符数组名或字符串常量,函数的返回值为转换后的字符串

地址。

8.大写转小写函数strlwr

格式:

strlwr(字符串);

功能:将字符串中的大写字母转换为小写字母,其他字符不转换(包括小写字母和非字母)。其中“字符串”可以是字符数组名或字符串常量,函数的返回值为转换后的字符串地址。

6.3.4字符数组的应用程序设计

字符数组中字符数据的处理程序设计,其思路方法与数值数组相同。只是输入/输出可有两种方式:一是字符数组元素的引用方式,二是串的整体方式。要注意字符数组赋初值的方式,它是通过字符赋初值的,字符串没有结束符“\0”,应按字符元素输入/输出。在字符串的处理中,要善于使用串处理库函数。

例6.13

从键盘输入一串字符,实现其中大小写字母的转换并输出。

编程思路:通过字符串输入给字符数组提供值,系统自动添加字符串结束符“\0”,可用字符串方式输入/输出。从附录A可知,字母大小写的ASCII码值相差32,将大写字母的ASCII码值加32就转换成小写字母,将小写字母的ASCII码值减32就转换成大写字母。

运行结果:

分析:程序中使用了字符串长度检测函数,程序头部有“#include"strin

温馨提示

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

评论

0/150

提交评论