第四章数组与结构体.docx
《第四章数组与结构体.docx》由会员分享,可在线阅读,更多相关《第四章数组与结构体.docx(15页珍藏版)》请在冰豆网上搜索。
![第四章数组与结构体.docx](https://file1.bdocx.com/fileroot1/2023-1/14/72ef4f58-903d-452a-a01c-3b17b09b4c6d/72ef4f58-903d-452a-a01c-3b17b09b4c6d1.gif)
第四章数组与结构体
第1章数组和结构体
本章目标
掌握数组定义的规则。
掌握数组的初始化方法及数组元素的引用。
掌握有关数组的基本算法。
掌握字符串处理函数的应用。
掌握结构体定义和使用的规则
学会使用VC++6.0开发环境中的Debug调试功能:
单步执行、设置断点、观察变量值。
授课内容
4.1数组
4.2字符型数组和字符串处理库函数
4.3结构体类型
4.4数组和结构体
4.5构体嵌套
程序设计举例
调试技术
4.1、数组
迄今为止,我们使用的都是属于基本类型(整型、字符型、实型)的数据,c语言还提供了构造类型的数据,它们有:
数组类型、结构体类型、共用体类型。
构造类型数据是由基本类型数据按一定规则组成的,因此有的书称它们为“导出类型”。
问题的引出:
实际应用的程序设计中,只用几个变量的情况是极少的;更多的情况是处理大批量的相同类型或不同类型的数据。
相同类型数据举例:
统计交大15,000学生英语4级统考成绩;
不同类型数据举例:
管理交大15,000学生学籍信息记录,包括:
姓名、学号、出生日期、班级、各科成绩等。
用什么样的数据结构来描述这类应用更简洁?
一维数组
常用于处理大批量数据;
数据特点:
存在内在联系;
数组——具有相同数据类型的变量集合;
这些变量都有相同名字,但下标不同;
称这些变量为数组元素;
只有一个下标——一维数组;
有两个下标——二维数组。
一维数组定义
数组是具有一定顺序关系的若干变量的集合体,组成数据的变量称为该数组的元素变量,简称元素。
一维数组的定义方式为:
例如:
inta[10];
它表示数组名为a,此数组有10个元素。
说明:
(1)数组名定名规则和变量名相同,遵循标识符定名规则。
(2)数组名后是用方括弧括起来的常量表达式,不能用圆括弧,
下面用法不对:
inta(10);
(3)方括弧括中的下标表示元素在数组中的位置。
C语言的下标从0,
必须是整型变量或常量。
(4)编译系统处理数组说明语句时,为它在内存中分配一定的存储
空间,数组在内存中存储时,是按下标递增的顺序连续存储各
元素的值的。
一维数组的初始化
(1)在定义数组时对数组元素赋以初值。
例如:
inta[10]={0,1,2,3,4,5,6,7,8,9};
(2)可以只给一部分元素赋值。
例如:
inta[10]={0,1,2,3,4};
定义a数组有10个元素,但花括弧内只提供5个初值,这表示只给前面5个元素赋初值,后5个元素值为0。
(3)如果想使一个数组中全部元素值为0,可以写成
inta[10]={0,0,0,0,0,0,0,0,0,0};
不能写成 inta[10]={0*10};
这是与FORTRAN语言不同的,不能给数组整体赋初值。
(4)在对全部数组元素赋初值时,可以不指定数组长度。
例如:
inta[5]={1,2,3,4,5};
可以写成inta[]={1,2,3,4,5};
在第二种写法中,花括弧中有5个数,系统就会据此自动定义a数组的长度为5。
例:
intA[5];在内存存储如图
数组的首地址是数组名A
数组的首地址也是第一个元素的地址&A[0]
C语言中,数组的整体不能参加数据处理,参加处理的只能是数组中的元素变量。
所以要对数组进行初始化。
例如:
intdata[5]={,4,,8,};赋值如图
例4-1
题目:
给一维数组x输入10个整数,找出x数组中的最大数和最小数。
算法分析:
1、假设数组中第1个元素最大,令xmax=a[0]
2、将a[i](0<=i若a[i]否则,令xmax=a[i],i=i+1,再执行2
3、循环结束,求出最大元素并输出max。
#include
intmain()
{intarray[7];
cout<<"Pleaseinputanarraywithsevenelements:
"<for(inti=0;i<7;i++)
cin>>array[i];
intbig=array[0];
for(intj=0;j<7;j=j+1)
if(array[j]>big)
big=array[j];
cout<<"max="<
return0;
}
二维数组
定义格式:
例如,三个学生四门课程成绩数据如下:
85879388
86909589
78918295
利用二维数组存放这些数据更能表现数据之间相互联系的特征。
每一行数据表示该学生的各门课程的成绩,而每一列数据表示该门课程各学生的成绩。
该数组定义为:
intmatrix[3][4];
二维数组存储结构
逻辑结构:
二维数组恰似一张表格(或矩阵)。
数组元素中的第一个下标值表示该元素在表格中的行号,第二个下标为列号。
M[3][3]具有如下逻辑结构:
M[0][0]M[0][1]M[0][2]
M[1][0]M[1][1]M[1][2]
M[2][0]M[2][1]M[2][2]
存贮结构:
二维数组在内存中按一维数组存放、占据一片连续的存贮单元;是“按行顺序”在内存中分配存贮单元。
M数组在内存中排列如下:
二维数组初始化
1.按照二维数组元素的物理存储次序给所有或部分数组元素提供数据值
intscore[3][4]={85,87,93,88,86,90,95,89,78,91,82,95};
//给数组stu_score每个元素都提供初值
floatmatrix[2][3]={1.0,3.0};
//仅为数组matrix的前2个元素提供初值
2.以行结构方式提供各数据值
intscore[3][4]={{85,87,93,88},
{86,90,95,89},
{78,91,82,95}};
4.2字符型数组和字符串处理库函数
字符串用双引号括起来,例如,”abc”;
用字符型数组存放字符串,存放时,在有效字符后自动加’\0’;
称’\0’为空值,是字符串结束标志;
有效字符的个数称为字符串长度。
例如,”abc”的长度为3,但占4个字节
(’\0’占一位)。
字符型数组的定义和初始化
charweekday[7]={"MONDAY"};
charweekday[7]="MONDAY";
字符串的输入与输出
charname[20];
cin>>name;
cin.get(name,n);
//第一个是字符数组变量,第二个指定向这个变量//中读入几个字符
cout<例4-2字符串的输入与输出
#include
intmain()
{
charname1[20],name2[20];
cout<<"Pleaseinputanamewithblank(within19characters):
"<cin.get(name1,20);
cout<<"Pleaseinputthenameagain"<cin>>name2;
cout<<"Usingfunctionget,thenamestoringinthevariableis:
"<cout<<"Usingoperater<<,thenamestoringinthevariableis:
"<return0;
}
字符串处理库函数
需要添加#include
stpcpy():
字符串拷贝;
strcat():
字符串连接;
strchr():
在字符串中查找字符;
strcmp():
字符串比较;
strlen():
求字符串长度;
strlwr():
将字符串中的大写字母转换为小写字母;
strrev():
反转字符串;
strstr():
在字符串中查找另一个字符串;
strupr():
将字符串中的小写字母转换为大写字母;
……
例4-3
编写一个用来计算字符串长度的函数mystrlen(),并用主函数验证
算法分析:
1)设一个计数器变量len=0
2)从数组s[len]第一个元素开始进行处理
3)若当前的元素值s[len]非空(‘\0’),则len+1,继续执行3;否则,退出循环。
4)打印结果len
#include
//计算字符串的长度的函数
intmystrlen(charstring[])
{
intlen=0;
while(string[len]!
='\0')
len=len+1;
returnlen;
}
//测试计算字符串长度的主函数
intmain()
{
charstring[100];
intlen=0;
cout<<"Pleaseinputastring(within99characters):
"<cin>>string;
cout<<"Thelengthofthestringis:
"<return0;
}
4.3结构体类型
迄今为止,已介绍了基本类型(或称简单类型)的变量(如整型、实型、字符型变量等),也介绍了一种构造类型数据——数组,数组中的各元素是属于同一个类型的。
但是只有这些数据类型是不够的。
有时需要将不同类型的数据组合成一个有机的整体,以便于引用。
这些组合在一个整体中的数据是互相联系的。
例如,工人工资单:
姓名、单位、编号.....
例如,学生成绩单:
学号、姓名、性别、各科成绩等
这些项都与某一学生相联系。
可以看到性别(sex)、年龄(age)、成绩(score)、地址(addr)是属于学号为10010和名为“LiFun”的学生的。
如果将num、name、sex、age、score、addr分别定义为互相独立的简单变量,难以反映它们之间的内在联系。
例职工工资单的层次结构
01工资单
02工作部门:
字符串,最大长度为10个字符
02姓名:
字符串,最大长度为8个字符
02职务(含职称、工种):
代码,0-99
02参加工作时间
03年份:
1900-2050
03月份:
1-12
03日:
1-31
02家庭情况
03婚否:
0-否,1-是
03是否双职工:
0-否,1-是
03独生子女出生日期
02基本工资:
0-10000,保留两位小数
02岗位津贴:
0-10000,保留两位小数
02劳保福利:
0-1000,保留两位小数
02独生子女费:
0-10,保留两位小数
02房租:
0-10000,保留两位小数
02电费:
0-10000,保留两位小数
02水费:
0-10000,保留两位小数
02取暖费:
0-1000,保留两位小数
02保育费:
0-1000,保留两位小数
02实发工资:
0-10000,保留两位小数
4.3.1结构体类型的定义
结构体作为一种数据构造类型,在C语言程序中也许需要经历定义——声明——调用的过程。
结构体是由不同的数据类型的数据组成的。
组成结构体的每个数据成为该结构体的成员项简称成员。
structstudent
{charname[20];
unsignedlongnumber;
floatmath;
floatenglish;
floatphysics;
};
在程序使用结构体时,首先要对结构体进行描述,这称为结构体的定义。
struct结构名
{数据类型成员名1;
数据类型成员名2;
……
数据类型成员名n;
};
三种结构体变量的声明
(1)先定义结构体类型,再定义结构体类型变量。
例如,日期类型可以定义为
structdate
{
intda_year;
charda_mon;
charda_day;
};
structdateyesterday,today,tomorrow;
//说明了3个日期类型的变量:
yesterday、today和tomorrow
(2)定义类型的同时声明变量。
例如,
structdate
{
intda_year;
charda_mon;
charda_day;
}yesterday,today,tomorrow;
声明了3个日期类型的变量:
yesterday、today和tomorrow。
(3)直接定义结构体类型变量。
例如,
struct
{
intda_year;
charda_mon;
charda_day;
}yesterday,today,tomorrow;
不出现结构体类型名。
程序设计举例
例4-5编写一个用于对整型数组进行排序的程序,排序方法使用
简单的交换排序法
例4-6编写一个字符串处理程序,将一个字符串之中的所有小写
字母转换为相应的大写字母
例4-7使用数组编写一个统计学生课程平均分的程序
例4-8使用结构体重新编写上题的程序
例4-5、冒泡排序
算法分析:
(1)两两比较相邻元素A(I)和A(I+1)(I=1,2,…N-1),如果
A(I)>A(I+1),则交换它们的位置A(I)A(I+1);
(2)对剩下的N-1个元素,再两两进行比较,按同样规则交换它们
的位置,经过N-2次比较,将次最大值交换到A(N-1)的位置;
(3)如法炮制,经过N-1趟的“冒泡处理”,每趟进行N-i次的
比较,全部数列有序。
//Example4-5:
冒泡排序
#include
intmain()
{constintCOUNT=16;
intlist[COUNT]={503,87,512,61,908,170,897,
275,653,426,154,509,612,677,765,703};
for(inti=0;ifor(intj=COUNT-1;j>i;j=j-1)
if(list[j-1]>list[j])
{inttmp=list[j-1];
list[j-1]=list[j];list[j]=tmp;}
cout<<"Theresultis:
"<for(intk=0;k<16;k++)
cout<cout<return0;
}
例4-6将小写字母转换为大写字母
算法分析:
将大写字符转换为小写,用到转换公式:
str[i]=str[i]-‘A’+‘a’;
将小写字符转换为大写,用下列公式:
str[i]=str[i]-‘a’+‘A’;
#include
intmain()
{charstr[]="Thisisasample";
cout<<"Theoriginalstringis:
"<inti=0;
while(str[i]!
=0)
{
if(str[i]>='a'&&str[i]<='z')
str[i]=str[i]-'a'+'A';
i=i+1;
}
cout<<"Aftertransform:
"<return0;
}
例4-7统计学生课程平均分的程序
定义二维数组student[6][5],
其中,给数组student前4列元素读值,第1列为学号,第2列到第4列为4门课程的成绩。
第5列为平均分,通过计算求得。
#include
#definePERSON6
#defineCOURSE3
intmain()
{intstudent[PERSON][COURSE+2];
inti,j;
cout<<"Pleaseinputdataofstudent:
"<for(i=0;i{cin>>student[i][0];student[i][COURSE+1]=0;
for(j=1;j<=COURSE;j=j+1)
{cin>>student[i][j];
student[i][COURSE+1]=student[i][COURSE+1]+student[i][j];
}
student[i][COURSE+1]=student[i][COURSE+1]/COURSE;
}
cout<<"学号高数英语体育平均分"<cout<<"--------------------------------------"<for(i=0;i{
for(j=0;j<=COURSE+1;j=j+1)
cout<cout<}
return0;
}
例4-8使用结构体重新编写上题的程序
算法定义一个结构体类型StudentType,其中包含学号、各门课程成绩和平均分等数据成员,其值分别通过输入和计算求得。
//Example4-9:
统计学生课程的平均分
#include
#definePERSON6
#defineCOURSE3
structStudentType
{charid[10];//学号
intscore[COURSE];//课程成绩
intGPA;//平均分
};
intmain()
{StudentTypexjtuStudent[PERSON];
inti,j;
cout<<"Pleaseinputdataofstudent:
"<for(i=0;i{cin>>xjtuStudent[i].id;
xjtuStudent[i].GPA=0;
for(j=0;j{cin>>xjtuStudent[i].score[j];
xjtuStudent[i].GPA=xjtuStudent[i].GPA
+xjtuStudent[i].score[j];
}
xjtuStudent[i].GPA=xjtuStudent[i].GPA/COURSE;
}
cout<<"学号高数英语体育平均分"<cout<<"--------------------------------------"<for(i=0;i{
cout<for(j=0;jcout<cout<}
return0;
}