资源描述
第五章 构造体类型(数组),C语言程序设计,第一节 数组概述 第二节 一维数组 第三节 字符数组 第四节 二维数组 第五节 数组作为函数参数,第一节 数组概述,定义:数组是有序数据的集合。数组的每个元素都属于同一个数据类型。 每个数组要用一个统一的标识符标识。 组成数组的数据称为数组的元素。,特点: 数据元素在内存中是按顺序连续存放的。 每个元素都属于同一个数据类型 具有整体性,一、定义 二、引用 三、初始化 四、输入和输出 五、应用举例,第二节 一维数组,定义,类型说明符 数组名常量表达式; 一维 int a5; char c20; float x10;,注意: 数组名命名规则与变量名相同; 数组名后是方括号,而不是小括号; 常量表达式表示元素的个数, 数组的大小是固定的,不能动态定义。 例如:int n; scanf(“%d”,是错误的。,引用,数组必须先定义,后使用。 只能逐个引用数组元素。 例如,若定义数组 int a3,则数组元素为: a0 a1 a2,引用形式: 数组名下标; 例如:a2=1; ai+j;(i,j为整型变量),注意,下标的值不要超过数组的范围。,初始化,顺序指定全部元素的初始值 int a5=1,2,3,4,5;,输入和输出,C语言规定,对数组的使用只能逐个引用数组元素,不能一次引用整个数组。同样,对数组的输入和输出也是依次对每个元素进行的。 例5.2 输入10个数,并将它们输出。,printf(“please enter the data:n“); for(i=0;i10;i+) scanf(“%d“,printf(“output the data:n“); for(i=0;i10;i+) printf(“%d “,arrayi); printf(“n“); ,输入,输出,说明:在循环体内利用循环控制变量作为下标输入输出数组元素,因此数组元素输入输出的次序和数量可以控制。 例如,将一个数组按照逆序打印数组元素的值? 只打印一个数组的前五个元素的值?,第四节 一维数组的应用,例5.1 使用数组编程,计算出前10项fibonacci数列,要求一行打印5个数。,main() int f10; int i; f0=0; f1=1; for(i=2;i10;i+) fi=fi-1+fi-2;,for(i=0;i10;i+) if(i%5=0) printf(“n“); printf(“%4d“,fi); ,应用举例,例5.3 有一个数组,有5个整数存放其中,找出其中最大的一个数。,程序,int a5 n a0 a1 a2 a3 a4 21 13 90 32 -1,13 21 90 32 -1,13 21 32 90 -1,13 21 90 32 -1,13 21 32 -1 90,定义,printf(“max=%dn“,max);,main() int i,max,x5;,printf(“enter data:n“); for(i=0;i5;i+) scanf(“%d“, ,for(i=0;i4;i+),输入,处理,输出,if (xixi+1) temp=xi; xi=xi+1; xi+1=temp;,max=a4;,例5.4用冒泡法对10个整数按从小到大的顺序排列。 排序的方法很多,主要有: 冒泡法 选择法,冒泡法,冒泡法的思想是:假设有n个数,将相邻的两个数依次进行比较,使小的在前,大的在后,那么第一轮比较n-1次就把最大的数排到了最后,第二轮比较n-2次就把次大的数排到了倒数第二,依此类推,直到第n-1轮比较1次将最小的数排到了第一,算法结束。算法的整体思路是让大的数不断地往下沉,小的数不断地往上冒,所以叫“冒泡排序法”。,for(i=1;ixj+1) temp=xj; xj=xj+1; xj+1=temp; ,选择法排序,for(i=0;i10-1;i+) p=i; for(j=i+1;j10;j+) if(ajap) p=j; if(p!=i), med=ap; ap=ai; ai=med; ,数据查找,线性查找 基本思想:从头到尾逐个查找,效率较低。 主要程序段: int b10,j,key; int find=0; scanf(“%d”,折半查找,基本思想:先检查中间的一个数据,看它是否为所需要 的数据,如果不是,则判断要找的数据是在中间数的 那一边,下次就在这个范围内查找,同样与中间数进行 比较。例如:一组数据 10 17 20 22 31 44 51 55 算法: (1)设变量top、mid、bot分别表示数列的开头、中间和末尾,mid=(top+bot)/2; (2)如果x=amid,则设查到标志为“真”,打印相关信息 (3)否则如果xamid,则设top=mid+1 重复以上过程直到bottop或已经找到为止。,int mid, top, bot,find,a10; top = 0; bot = 9; find = 0; do mid =( top + bot ) / 2; if( x = amid ) printf(“找到了%3d,是 a%d“,x,mid); printf(“n“); find = 1; else if( x amid ) top = mid + 1; while( top = bot ,一、二维数组的引用 二、二维数组的初始化 三、二维数组元素在内存中的排列 顺序 四、应用举例,第五节 二维数组,英语 数学 社科 王 宁 90 90 89 王 光 89 91 95 . . 李 达 90 100 90 . .,定义,类型说明符 数组名常量表达式常量表达式; int a34; char c23; float x23;,注意:数组的大小是固定的。,引用,例如,定义数组 int a23,表明此数组为2行3列,数组元素为: a00 a01 a02,a10 a11 a12,引用形式: 数组名下标1下标2; 例如: b01=5; aij;(i,j为整型变量),注意,下标的值不要超过数组的范围。,printf(“please enter the data:n“) for(i=0;i3;i+) for(j=0;j2;j+) scanf(“%d“,for(i=0;i3;i+) for(j=0;j2;j+) printf(“%nb%d%d=%d“,i,j,bij); printf(“n“),输入,输出,二维数组的输入与输出,初始化,分行赋初值 int a23=1,2,3,4,5,6; 不分行赋初值 int b23=1,2,3,4,5,6;,初始化(续),对部分元素赋初值 int c24= 0,2,3 ; 未赋值的元素自动赋值0,而且前面的0不能省,后面的0可以省 对全部元素赋初值,省略第一维的长度 int a2= 1,2,3,4 ;,二维数组元素在内存中的排列顺序,按行存放 二维数组的元素在数组中的排列顺序可以计算出来: 设一个mn的数组x,数组元素xij 在数组中的排列顺序为in+j+1。 例如43数组x,元素x31在数组的排列顺序为33+1+1=11即数组中的第11个元素。 二维数组可以看成由几个一维数组构成,其中一行为一个一维数组。,应用举例,例5.5求两个3*4矩阵的和。参考程序如下: main( ) int a34,b34;c34; int i,j; printf(“输入a矩阵的元素值n“); for(i=0;i3;i+) for(j=0;j4;j+) scanf(“%d“,printf(“输入b矩阵的元素值n“); for(i=0;i3;i+) for(j=0;j4;j+) scanf(“%d“, /* 结果存放在c矩阵中 */,printf(“和矩阵为:n“); for(i=0;i3;i+) for(j=0;j4;j+) printf(“%5d“, cij); printf(“n“); ,例5.6 将一个4*3的矩阵转置。程序片段如下: for(i=0;i4;i+) for(j=0;j3;j+) bji=aij; ,例:现有四个学生,每个学生有三门课,求每个学生的平均成绩和每门课的平均成绩。,#define m 4 #define n 3 main() float scoremn=70,80,90,90,92,94, 65,67,63,80,90,72; float avem,coursen,sum; int i,j; for(i=0; i m; i +) sum=0; for (j=0;jn;j+) sum=sum+scoreij; avei=sum/n; /*求每个学生的平均成绩(确定行)*/,for(j=0; j n; j+) sum=0; for (i=0;im;i+) sum=sum+scoreij; coursej=sum/n; /*求每门课的平均成绩(确定列)*/,一、字符数组的定义 二、初始化 三、字符串,第六节 字符数组,定义 char str20; 初始化 逐个为数组中各元素指定初值字符。 char str4 =w,e,l,l; 对一个字符数组指定一个字符串初值。 char str =“good morning“; char str =“good morning“;,字符串,什么是字符串? 字符串是用一对双引号括起来的字符序列,这些字符可以是一般的可显示字符,也可以是某些特殊的控制字符; 字符串只能用字符数组来处理,没有字符串变量。字符串在内存中存放时,系统将自动在字符串的末尾添加一个字符串的结束标记0 (空字符),碰到第一个0就认为字符串处理结束。,用字符串给字符数组初始化 char st8= “welcome“; 等价于 char st8=w, e,l,c,o,m,e,0;,注意:这里的st不是一个字符串变量,而是字符数组的名字,代表字符数组在内存中的起始地址,是一个常量,那么这个赋值表达式是指将字符串中的每一个字符依次赋给以st开始的地址单元。,字符串的长度 定义 char ch = “Good“; 则数组ch的元素个数是5,而不是4,也就是说,字符串的长度是双引号中所包括的字符个数加1。,字符串的输入和输出,逐个输入输出 main() int i;char a10; for(i=0;i10;i+) scanf(“%c “, ,整体输入/输出 main() char c10; scanf(“%s“,c); printf(“%sn“,c); ,注意:scanf函数不能完整地读入带空格的字符串。C语言提供了一个用于读字符串的函数,它读入全部字符(包括空格),直到遇到回车符为止, 它是 gets()。 例如: char c13; gets (c); 键盘输入: How are you?,字符串处理函数,字符串的输入gets( ) 格式:gets(ch) 功能:从终端输入一个字符串到字符数组ch中,输入回车键时结束,并将回车符n转换成 0 ,其中ch只能是一个字符数组名。 字符串的输出 puts( ) 格式:puts(ch) 功能:向终端输出字符串,并将0转换成n输出,其中ch可以是某个字符数组名,也可以是一个字符串常量。,求字符串长度的 strlen( ) 格式:strlen(ch) 功能:返回ch的有效字符的个数,不包括 0,其中ch为字符数组名或某个字符串常量。 字符串的复制 strcpy( ) 格式:strcpy(ch1,ch2) 功能:将ch2中的字符串复制到ch1字符数组,限定ch1为字符数组名,ch2可以是字符串常量或字符数组名。,字符串的比较 strcmp( ) 格式:strcmp(ch1,ch2) 功能:对ch1和ch2所对应的字符串从左到右一一进行比较(比较字符的ASCII码值的大小),第一个不相等的字符的大小决定了整个字符串的大小,若ch1和ch2的所有字符完全相同,则ch1=ch2 ch1=ch2 函数返回0 ch1ch2 函数返回一个正整数,字符串大小写转换strlwr() 格式:strlwr(ch); 功能:将ch中所有的大写字母转换成小写字母。 字符串大小写转换strupr() 格式:strupr(ch); 功能:将ch中所有的小写字母转换成大写字母。,字符串的连接函数strcat() 格式:strcat(ch1,ch2); 功能:将ch2复制到ch1的后面,连接时先将ch1的0去掉,连接后在新字符串后补上0 。要求ch1必须是一个足够大的字符数组,ch2可以是字符串常量或字符数组名。,例:从键盘输入一字符串,统计其中字母、数字和其它字符的个数。,#include “stdio.h“ main() char st60;int i,english=0,space=0,num=0,other=0; gets(st); for (i=0;(sti!=0);i+) if (sti=a ,#include “stdio.h“ main() char st160,st260;int i; gets(st1); for(i=0;(st1i!=0);i+) printf(“%c“,st1i); for (i=0;(st1i!=0);i+) st2i=st1i; st2i=0; for(i=0;(st2i!=0);i+) printf(“%c“,st2i); ,例:用程序实现将一个字符串复制到另外一个字符数组中,不能用strcpy()函数。,例5.7 将10个学生的姓名按字典顺序排列。定义两个字符数组 char name109,temp9; 程序片段如下: #include ”stdio.h” main( ) int i,j; char name109,temp9; printf(“请输入10个学生的姓名:n“); for(i=0;i10;i+) scanf(“%s“,namei);,/* 外循环控制程序比较9轮 */ for(i=1;i0) strcpy(temp,namej);/* 交换两个姓名的次序*/ strcpy(namej,namej+1); strcpy(namej+1,temp); ,一、数组元素作为函数的实参 二、数组名作为函数的参数,第五节 数组作为函数参数,数组元素作为函数的实际参数,数组元素的引用与一般变量的引用是一样的,传递的是数组元素的值,属于“值传递”方式。 例5.8 设a8和b8分别保存了A班和B班八门课程的平均成绩,现要统计出A班有几门课程的平均成绩高于B班。,main( ) int i,k=0;float a8,b8; for(i=0;iave2 ) return(1); else return(0); ,数组名作为函数的实际参数,C语言中的数组名代表了数组在内存中存放的起始地址,所以数组名作为函数的参数传递的是数组的起始地址,属于“传地址”,是一种双向传递的方式。 说明: (1)用数组名作为函数的参数,必须对实参数组先定义,形参必须说明成与实参数组类型一致的数组。 (2)形参数组和实参数组的数组名可以不一样,数组的大小也可以不一致。由于传递的是地址,所以形参数组和实参数组在内存中实际上是共用了连续的一块地址空间。,例5.9 用函数average()求30个学生英语课的平均成绩。 float average(mark,n) int mark,n;float ave; int sum=0,i; for(i=0;in;i+) sum=sum+marki; ave=sum/n; return(ave); main( ) int i,score30; printf(“请输入30个学生的英语成绩:n“); for(i=0;i30;i+) scanf(“%d“, ,main() int a2; scanf(“%d,%d“, ,结构体类型的定义 结构体变量的定义和引用 结构体变量的初始化 应用举例,5.7 结构体类型,构造一个结构体类的数据类型的一般形式: struct 结构类型名 类型标识符 成员名; 类型标识符 成员名; : : 类型标识符 成员名; ;,例如: struct student char number10; char name20; char sex; int age; float score20; char addr30; ;,定义 先构造结构体类的数据类型,后定义具有这种构造的变量。 struct 结构体类型名 类型标识符 成员名; : 类型标识符 成员名; ; struct 结构体类型名 变量名1,变量名2;,例如: struct student char number10; char name20; char sex; int age; float score20; char addr30; ; struct student stud1,stud2;,引用 对结构体变量的使用是通过对其成员的引用来实现的。引用结构体成员的一般形式如下: 结构变量名成员名 例如 stud1.age 其中的圆点符号称为成员运算符,它的运算级别最高。,struct stud long num; char name20; char sex; char addr30; stud1=9708,”Liwei“,F,“144BeijingRoad”;,例5.11 输入3个学生的信息并输出。 #include #include struct stud long num; char name20; char gender; int age; float score; ;,void main() struct stud student3; int i; char ch; char numstr20; for( i = 0 ; i 3 ; i+) printf(“n输入第%d个学生的数据:n“,i); gets(numstr); studenti.num = atol(numstr); gets(studenti.name); studenti.gender = getchar(); ch = getchar(); gets(numstr); studenti.age = atoi(numstr); gets(numstr); studenti.score = atof(numstr); printf(“nnumtname gender age scoren“); for( i = 0 ; i 3 ; i+) printf(“%ld%-15s%3c%6d %6.2fn“,studenti.num,studenti.name, studenti.gender,studenti.age,studenti.score); ,main() int i,j,k; for(i=-3;i=3;i+) for(j=1;j=abs(i);j+) printf(“ “); for(k=1;k=7-2*abs(i);k+) printf(“*“); printf(“n“); ,作业讲解:,#include “stdio.h” main() char ch; int english=0,space=0,num=0,other=0; while (ch=getchar( ) != n) if (ch=a ,作业讲解:,#include #include void main() char str120; char str220; int i,j=0; printf(“请输入第一个字符n“); gets(str1); for(i=0;istrlen(str1);i+) if(i%2=0) str2j=str1i; j=j+1; printf(“%sn%s“,str1,str2); ,作业讲解:5-6,str2j=0;,#include “stdio.h“ void main() int a2020; int i,j,n; scanf(“%d“,作业讲解:5-9,#include #include void str(char a) int i; for(i=0;ai!=0;i+) if(ai=a) ai-=32; void main() char str120; printf(“请输入字符串n“); gets(str1); printf(“%sn“,str1); str(str1); printf(“%sn“,str1);,作业讲解:5-12,编写函数判断输入的字符串是否是回文。 #include “string.h“ #include “stdio.h“ int ishuiwen(char a) int i,n,flag=1; n=strlen(a); for(i=0;in/2;i+) if(ai!=an-1-i) flag=0; break; return flag; ,main() char str10; int i; gets(str); i=ishuiwen(str); if (i) printf(“字符串是回文!“); else printf(“字符串不是回文!“); ,数据统计分析,在实际应用中,经常要对大量的数据进行统计、分析和分类等,下面将介绍用数组统计所搜集到的数据。 例5.12 在某一次歌唱比赛中,20名评委给某个参赛选手打分,分数等级从110共10个等级,1表示最低,10表示最高,统计打分结果。,#include #define N 20 void main() int i,j; int score20=1,2,6,4,10,9,8,3,4,6,7,8,9,5,9,7,8,7,8,5; int frequency11=0; /*存放统计结果*/ for( i = 0; i 20; i+) +frequencyscorei; /*进行统计*/ printf(“ 等级 频率“); for( j = 1; j 11;j+) printf(“%4d%12d n“, j,frequencyj); ,
展开阅读全文