资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,C语言程序设计,数组的概念和使用,一个数组在内存中占一片连续的存储单元。,定义一维数组的一般格式为,类型标识符 数组名常量表达式;,例如,int a10;,用方括号括起来的常量表达式表示下标值,如下面的写法是合法的:,int a2*5;,int an*2; /,假设前面已定义了,n,为常变量,常量表达式中可以包括常量、常变量和符号常量,但不能包含变量。,例如,下面这样定义数组是不行的:,int n;,cinn; /,输入,a,数组的长度,int an;,如果把第1,2行改为下面一行就合法了:,const int n=5;,(1) 在定义数组时分别对数组元素赋予初值。例如,int a10=0,1,2,3,4,5,6,7,8,9;,(2) 可以只给一局部元素赋值。例如,int a10=0,1,2,3,4;,(3)在对全部数组元素赋初值时,可以不指定数组长度。例如,int a5=1,2,3,4,5;,可以写成 int a=1,2,3,4,5;,数组元素也可以作函数实参,其用法与变量一样。数组名也可以作实参和形参,传递的是数组的起始地址。,1.4 用数组作函数参数,1. 用数组元素作函数实参,由于实参可以是表达式,而数组元素可以是表达式的组成局部,因此数组元素当然可以作为函数的实参,与用变量作实参一样,将数组元素的值传送给形参变量。,2. 用数组名作函数参数,可以用数组名作函数参数,此时实参与形参都用数组名,实例30:,(1) 如果函数实参是数组名,形参也应为数组名,(2) 需要特别说明的是: 数组名代表数组首元素的地址,并不代表数组中的全部元素。,(3)用数组名作函数实参时,改变形参数组元素的值将同时改变实参数组元素的值。,3. 用多维数组名作函数参数,如果用二维数组名作为实参和形参,在对形参数组声明时,必须指定第二维(即列)的大小,且应与实参的第二维的大小一样。第一维的大小可以指定,也可以不指定。如,int array310; /形参数组的两个维都指定,或 int array10; /第一维大小省略,二者都合法而且等价。但是不能把第二维的大小省略。,实例31:,指针,直接访问和间接访问,间接:将3送到指针变量i_pointer所指向的单元这就是变量i所标识的单元中。,所谓指向,就是通过地址来表达的。,由于通过地址能找到所需的变量单元,因此可以说,地址指向该变量单元。因此将地址形象化地称为“指针。一个变量的地址称为该变量的指针。,如果有一个变量是专门用来存放另一变量地址即指针的,那么它称为指针变量。指针变量的值即指针变量中存放的值是地址即指针。,变量与指针,&:,取地址运算符,*:指针运算符,int,*,p=&a,;,&a,为变量,a,的地址,*,p,为指针变量,p,所指向的变量。,为了表示指针变量和它所指向的变量之间的联系,在C+中用“*符号表示指向,例如,i_pointer是一个指针变量,而*i_pointer表示i_pointer所指向的变量,下面两个语句作用一样:,int *i_pointer=, i=3;, *i_pointer=3;,必须将指针变量定义为指针类型。先看一个具体例子:,int i,j; /,定义整型变量,i,j,int *pointer_1, *pointer_2;,pointer_1=,pointer_2=,在定义指针变量时要注意:,(1) 不能用一个整数给一个指针变量赋初值。,(2) 在定义指针变量时必须指定基类型。,指针作为函数参数,,将一个变量的地址传送给被调用函数的形参。,实例1-2:,指针作为函数参数,数组与指针,在,C+,中,数组名代表数组中第一个元素(即序号为0的元素)的地址。因此,下面两个语句等价:,int *p= /p,的初值为,a0,的地址,也可以写成,int *p=a;,(1),p+i,和,a+i,就是,ai,的地址,或者说,它们指向,a,数组的第,i,个元素,见图6.12。,(2) *(,p+i),或*(,a+i),是,p+i,或,a+i,所指向的数组元素,即,ai。,实例:数组指针,实例,30,实参形参都用数组名,/,数组变量,实参用指针变量,形参为数组变量,实例,31,实参用数组名,形参用指针变量,实参形参都用指针变量,构造体,概述,在实际应用中,有不少应用问题如果只采用已学的变量和数组作为数据构造显得很不方便。,例:输入100个学生的学号、姓名和考试成绩,编写程序找出高分者和低分者。,用变量和数组作数据构造可编写程序如下:,main(), int i, num, maxnum, minnum;,char name20;,char maxname20, minname20;,int score, maxscore, minscore;,maxscore=0; minscore=100;,for(i=1; imaxscore), maxscore=score;,maxnum=num; strcpy(maxname,name); ,if(scoreminscore), minscore=score;,minnum=num; strcpy(minname,name); , 输出 ,明显缺点:,变量过多,同一学生的各个数据无联系,没有整体概念,不便管理。,操作不便如更新过程。,显然,选用一种能把一个学生的数据构造成一个整体的构造型数据构造更适宜,但不能是数组。,对于这种情况,可以将一个学生的数据定义为一个构造体类型:,struct student 类型名,int num; 成员表,char name20;,int score;,;,定义了一个构造体类型,它包含三个成员。,定义构造体类型变量的方法,前面定义的构造体类型只是一种“模型,还必须定义构造体变量后才能存放数据。,定义构造体变量有三种方法:,1、先定义构造体类型再定义构造体变量,定义了构造体类型后:,struct student st, stmax, stmin;,类型符 变量名,定义了三个构造体变量,每个变量包含三个成员,每个变量可存放一个学生的数据。,2、在定义构造体类型的同时定义构造体变量,struct student,int num;,char name20;,int score;,st, stmax, stmin;,3、直接定义构造体类型变量,struct 不出现类型名,int num;,char name20;,int score;,st, stmax, stmin;,常用第一种方法,说明: 类型与变量不同,只对变量分配空间与操作。,对成员可以单独使用,相当于普通变量。,成员也可以是一个构造体变量。,struct date struct student, int month; int num;,int day; char name20;,int year; struct date birthday;,; st1, st2;,成员名可以与程序中的变量名一样,两者代表不同的对象。,构造体变量的引用 成员引用,可以对成员单独引用,形式为:,构造体变量名 . 成员名,成员运算符,st.num=1001;st.score=90;,strcpy(st.name,Li);,printf(“%d%s%d,st.num,st.name,st.score);,scanf(“%d%s%d,可以引用成员的地址,如果成员本身又属一个构造体类型,那么要用假设干个成员运算符,一级一级地找到最低一级的成员,只能对最低级的成员进展存取与运算。,st1.birthday.year=1960;,st1.birthday.month=5;,st1.birthday.day=15;,整体引用,可以对构造体变量进展整体赋值:,stmax=st; 将st中的所有内容赋值给stmax。,对构造体变量的整体操作只限于赋值操作和参数传递,而且要求类型一致。不能对构造体变量进展整体输入输出。,构造体应用举例:,编写程序输入100个学生的学号、姓名和考试成绩,找出高分者和低分者。,struct student, int num;,char name20;,int score;,;,main(),int i;,struct student st,stmax,stmin;,stmax.score=0;,stmin.score=100;,for(i=1;istmax.score),stmax=st;,if(st.scorestmin.score),stmin=st;,printf(“n%5d%15s%5d,stmax.num,stmax.name,stmax.score);,printf(“n%5d%15s%5d,stmin.num,stmin.name,stmin.score);,构造体变量的初始化,对构造体变量可以在定义时指定初始值 struct student,int num;,char name20;,int score;,st=1001,wang,95;,构造体数组 可以定义构造体数组来存放批量数据,构造体数组的定义,struct student,int num;,char name20;,int score;,;struct student a100;,定义a数组,可以存放100个学生的数据,a数组的每个元素又是一个构造体变量。,构造体数组的初始化,在定义构造体数组的同时指定初值。,struct student,int num;,char name20;,int score;,;,struct student a2=,1001,LiLi,85,1002,wang,90;,或:,struct student,int num;,char name20;,int score;, a2=,1001,LiLi,85,1002,wang,90;,构造体数组元素的引用,成员引用:,a0.num=1001;,strcpy(a0.name,wang);,a0.score=85;,整体引用:,a1=a0; 与普通数组元素的引用一样,构造体数组的应用,输入100个学生的学号、姓名和考试成绩,然后按从高分到低分的顺序排列后输出。,struct student, int num;,char name20;,int score;,;,main(), int i, j;,struct student a100, t;,for(i=0;i100;i+),scanf(“%d%s%d,&ai.num,ai.name,for(i=0;i99;i+),for(j=i+1; j100; j+),if(ai.scoreaj.score),t=ai; ai=aj; aj=t; 整体引用,for(i=0;i100;i+),printf(“n%5d%15s%5d,ai.num,ai.name,ai.score);,例:对候选人得票的统计程序。设有三个候选人,每次输入一个得票候选人的名字,要求最后输出各候选人的得票结果。,#include “,struct person, char name20;,int count;,leader3=“Li,0,zhang,0,wang,0;,main(), int i, j ;,char leader_name20;,for(i=1;i=100;i+), scanf(“%s,leader_name);,for(j=0;j3;j+),if(strcmp(leader_name,leaderj.name)=0),leaderj.count+;,printf(“n);,for(i=0;inum=1001;,(*p).score=85; 或 p-score=85;,strcpy(*p).name,wang);,或 strcpy(p-name,wang);,整体引用,st1=*p; 等效于 st1=st;,指向构造体数组的指针,struct student a100;,struct student *p;,p=a;,通过指针变量引用构造体数组元素:,成员引用,(*p).num=1001; 或 p-num=1001;,(*p).score=85; 或 p-score=85;,strcpy(*p).name,wang);,或strcpy(p-name,wang);,一般地:,(*(p+i).num=1001; 或 (p+i)-num=1001;,(*(p+i).score=85; 或 (p+i)-score=85;,strcpy(*(p+i).name,wang);,或 strcpy(p+i)-name,wang);,也可以用下标法:,pi.num=1001;,整体引用,*(p+1)=*(p+0); 或 p1=p0;,用构造体变量和指向构造体的指针作函数参数,用构造体变量作函数参数时,对应的实参应该是同类型的构造体变量或数组元素,参数传递是“值传递。,用指向构造体的指针作函数参数时,对应的实参应该是同类型的构造体变量的地址或数组的地址,参数传递是“地址传递。,main(), struct student st=1001,LiLi,70;,f(st);,printf(“n %5d%10s%5d,st.num,st.name,st.score);,f(struct student a), a.score=90;,printf(“n %5d%10s%5d,a.num,a.name,a.score);,1001,LiLi,70,st,1001,LiLi,70,a,90,main(), struct student st=,1001,LiLi,70;,f(,printf(“n %5d%10s%5d,st.num,st.name,st.score);,f(struct student *a), a-score=90;,printf(“n%5d%10s%5d,a-num,a-name,ascore); ,通过指针变量a可以访问它所指向的构造体。,1001,LiLi,70,st,2000,2000,a,90,用指针处理链表,链表概述,链表是一种重要的数据构造动态数据构造。,以具体例子来说明链表的概念及其应用:,例:选择适宜的数据构造来存放一批学生的学号及考试成绩,以便进一步处理。,由于学生人数未知,用静态数据构造不适宜。,用链表处理较恰当。,用链表处理该问题的根本思路:,将各学生的数据进展离散存放,来一个学生就分配一小块内存结点。并将各结点用指针依次连接起来链表。,每结点应包含下一结点的开场地址。,最后一个结点中的指针为空。,链头指针指向第一个结点,是访问链表的重要依据。,这样的链表称单向链表。,head,学号,成绩,指,针,学号,成绩,指针,学号,成绩,指针,学号,成绩,指针,学号,成绩,NUL,L,一个结点可用如下构造体描述:,typedef struct student,int num; 学号,int score; 成绩,struct student *next; 下一结点的首地址, STU;,typedef : 自定义类型符使用,为现有类型创立同义字,定义易于记忆的类型名,单向链表的建立,输入一个学生的数据。,分配结点空间,数据存入。,将该结点的首地址赋给上一结点的next,假设该结点是第一个结点,那么赋给头指针。,将该结点的next置为空,表示该结点为当前的最后结点。,head,学号,成绩,next,学号,成绩,next,学号,成绩,next,学号,成绩,next,学号,成绩,NULL,STU *creat(), STU st,*p0=NULL,*p,*head=NULL;,while(1), scanf(%d%d,if(st.numnext=p0-next; p0-next=p;,head,学号,成绩,next,学号,成绩,next,学号,成绩,next,学号,成绩,NULL,人有了知识,就会具备各种分析能力,,明辨是非的能力。,所以我们要勤恳读书,广泛阅读,,古人说“书中自有黄金屋。,”通过阅读科技书籍,我们能丰富知识,,培养逻辑思维能力;,通过阅读文学作品,我们能提高文学鉴赏水平,,培养文学情趣;,通过阅读报刊,我们能增长见识,扩大自己的知识面。,有许多书籍还能培养我们的道德情操,,给我们巨大的精神力量,,鼓舞我们前进,。,
展开阅读全文