第七讲动态数据处理

上传人:枫** 文档编号:567940150 上传时间:2024-07-22 格式:PPT 页数:52 大小:1.70MB
返回 下载 相关 举报
第七讲动态数据处理_第1页
第1页 / 共52页
第七讲动态数据处理_第2页
第2页 / 共52页
第七讲动态数据处理_第3页
第3页 / 共52页
第七讲动态数据处理_第4页
第4页 / 共52页
第七讲动态数据处理_第5页
第5页 / 共52页
点击查看更多>>
资源描述

《第七讲动态数据处理》由会员分享,可在线阅读,更多相关《第七讲动态数据处理(52页珍藏版)》请在金锄头文库上搜索。

1、第七讲第七讲 动态数据处理动态数据处理由于在C语言中数组只能定义定长的,而在实际中无法事先知道学生的人数,从而无法确定数组的大小。所以当学生人数变动的时候,使用数组就有点不方便了:因为如果将数组定义过长,浪费空间;定义太短,又不够用。现在在这里引入一个C语言中重要的概念-指针。通过使用指针,就可以很方便的实现学生人数的变动,根据实际情况来申请存储空间。从而不会出现存储空间的浪费或不够用问题。本章将继续完善“学生信息管理系统”案例程序。在上一章案例程序的基础上,可以实现对学生人数的变化进行存储空间的动态分配管理。具体是临时确定学生人数,进行存储空间的动态分配 处理“学生信息管理系统”人数变动如果

2、在程序中定义了一个变量,在编译时就给这个变量分配内存单元。系统根据程序中定义变量的类型,分配特定长度的空间。内存区的每一个字节都有一个编号,这就是“地址”。它就相当于旅馆中的房间号或是学生宿舍的宿舍号一样。在地址所标志的内存单元中存放数据,就相当于旅馆中各个房间中住旅客一样。根据内存编号也可以准确地找到所需要的内存单元。所以内存内存单元的地址单元的地址与与内存单元的内容内存单元的内容是两个不同的概念。 使用指针处理人数变动-指针 .20003004x20043000y变量x变量y定义了一个int型变量x,编译时系统分配了2000到2003四个字节给变量x。定义了一个float型变量y,编译时分

3、配了3000到3003四个字节给变量y。通常我们只关心变量的第一个字节的编号。将变量的第一个字节编号称该变量的地址。2000是变量x的地址,3000是变量y的地址。把一个变量的地址称为该变量的“指针”。严格地说,一个指针就是一个地址。一个变量的地址称为该变量的“指针”。如果用一个变量专门来存放另外一个变量的地址(即指针),则它就称为“指针变量”。也可以说存放变量地址的变量是指针变量。定义一个指针变量必须包括3个内容:(1)指针类型说明,即定义变量为一个指针变量;(2)指针变量名;(3)指针变量所指向的变量的数据类型。其一般定义形式为: 基类型 *指针变量名;其中*表示这是一个指针变量,基类型表

4、示指针变量指向的变量的数据类型。基类型必须指定,一个指针变量只能指向同一个类型的变量指针变量的定义int *p1; float *p2; Student *stu;当定义了一个指针变量之后,和其他变量一样,就应该给它赋值。没有赋值的指针变量不能使用。指针变量的赋值只能是赋予地址,绝对不能赋予其他数据,也就是让它指向它定义的那个基类型的一个变量。指针变量的两个运算符(1)&:取地址运算符,也就是说取变量的地址。(2)*:指针运算符,也就是说取指针所指变量的内容。如:&a为变量a的地址,*p为指针变量p所指向的存储单元中的内容。&和*互为逆运算。对于运算符&和*,这两个运算符的优先级别相同。如果没

5、有括号,像&*i_pointer,计算的时候是按照自右向左结合。因此在这里先是计算*i_pointer,它就是变量i,再执行&运算,所以&*i_pointer就是i变量的地址。指针操作符short int i=10;short int *i_pointer; i_pointer=&i;这样定义的指针变量i_pointer就指向变量i。假设定义变量i的时候,它分配的空间的首地址为2000。当运行i_pointer=&i的时候,指针变量中就存储了变量i的地址2000。*i_pointer为指针变量i_pointer所指的存储单元的内容,也就是变量i的值10。.2000200420062005整型变

6、量i10变量i_pointer2001200220032000指针变量 变量的地址 变量的内容【实实例例1】阅阅读读以以下下程程序序,理理解解通通过过指针变量访问普通变量的方法。指针变量访问普通变量的方法。 返回返回#include intmain() int x=0; int *p;p=&x; *p=100; *p=*p+50; printf(x=%dn,x); 将将x的地址赋给指针变量的地址赋给指针变量p 相当于相当于x 运行结果:运行结果:x=1500&x*pxp执行执行p=&x;后后100执行执行*p=100;后后150执行执行*p=*p+50;后后执行执行printf(x=%dn,x

7、);后后运行结果:运行结果:x=150main() int *p1,*p2,*p,a,b; scanf(%d,%d,&a,&b); p1=&a; p2=&b; if(ab) p=p1; p1=p2; p2=p; printf(a=%d,b=%dn,a,b); printf(max=%d,min=%dn,*p1,*p2);运行结果:a=5,b=9 max=9,min=5.指针变量p1 指针变量p20002008200220042006 指针变量p2 整型变量b 整型变量a5200692008200620082006例 输入两个数,并使其从大到小输出#include void swap(int x

8、,int y) int temp; temp=x; x=y; y=temp;main() int a,b; scanf(%d,%d,&a,&b); if(ab) swap(a,b); printf(n%d,%dn,a,b);指针作为函数参数#include void swap(int *p1, int *p2) int *p; p=p1; p1=p2; p2=p;main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab)swap(pointer_1,point

9、er_2); printf(n%d,%dn,a,b);#include void swap(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab)swap(pointer_1,pointer_2); printf(n%d,%dn,a,b);特点:共享内存,“双向”传递swap(int x,int y) int temp; temp=x; x=y; y=temp;m

10、ain() int a,b; scanf(%d,%d,&a,&b); if(ab) swap(a,b); printf(n%d,%dn,a,b);例 将数从大到小输出.20002008200A2002200420065变量a 变量b(main)9 变量temp 变量y 变量x(swap)559 59COPY指针变量作为函数参数地址传递特点:共享内存,“双向”传递swap(int x,int y) int temp; temp=x; x=y; y=temp;main() int a,b; scanf(%d,%d,&a,&b); if(ab) swap(a,b); printf(n%d,%dn,a

11、,b);例 将数从大到小输出值传递.20002008200A2002200420065变量a 变量b(main)9运行结果:5, 9指针变量作为函数参数地址传递swap(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab)swap(pointer_1,pointer_2); printf(n%d,%dn,a,b);.20002008200A20022004200

12、6200C200E2010.59整型变量a 整型变量b(main)指针pointer_1指针pointer_220002002(swap)指针p1指针p2整型p5920002002COPY5例 将数从大到小输出swap(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab)swap(pointer_1,pointer_2); printf(n%d,%dn,a,b)

13、;.20002008200A200220042006200C200E2010.59整型变量a 整型变量b(main)指针pointer_1指针pointer_22000200259运行结果:9,5地址传递例 将数从大到小输出(1)swap(int *p1, int *p2) int *p; *p=*p1; *p1=*p2; *p2=*p;main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab) swap(pointer_1,pointer_2); print

14、f(n%d,%dn,a,b);运行结果:9,9编译警告!结果不对!int x;int *p=&x;x;.20002008200A200220042006200C200E2010.59整型变量a 整型变量b(main)指针pointer_1指针pointer_2200020029920002002COPY(swap)指针p1指针p2指针p*假设2000指针变量在使用前必须赋值!例 将数从大到小输出(2)/*ch9_32.c*/swap(int x,int y) int t; t=x; x=y; y=t;main() int a,b; int *pointer_1,*pointer_2; scan

15、f(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab) swap(*pointer_1,*pointer_2); printf(n%d,%dn,a,b);运行结果:5,9值传递.20002008200A200220042006200C200E2010.59整型a 整型b(main)pointer_1pointer_2200020029COPY(swap)整型x整型b整型t555 9例 将数从大到小输出(3)运行结果:5,9swap(int *p1, int *p2) int *p; p=p1; p1=p2; p2=p;main() int a,b;

16、 int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab) swap(pointer_1,pointer_2); printf(%d,%d,*pointer_1,*pointer_2);.20002008200A200220042006200C200E2010.59整型a 整型b(main)pointer_1pointer_22000200220002002COPY(swap)指针p1指针p2指针p*2000地址传递20002002例 将数从大到小输出(4)通过指针访问数组元素【实实例例2

17、】假假设设运运动动会会包包括括10个个项项目目,编编写写程程序序,输输入入某某班班各各项项目目的得分,计算该班的总分。的得分,计算该班的总分。编程思路编程思路定义包含定义包含10个元素的数组,每个个元素的数组,每个元素用于存放各项目的得分。可元素用于存放各项目的得分。可用以前的方法完成,但为了提高用以前的方法完成,但为了提高效率,在此使用指针变量实现。效率,在此使用指针变量实现。a0a1 a2 a3 a4aa5 a6 a7 a8 a9p数组名代表数组的首地址数组名代表数组的首地址 p=a;相当于相当于p=&a0; a0和和*p代表同一个存储单元代表同一个存储单元 scanf(“%d”,&a0)

18、;可写为可写为scanf(%d,p);printf(“%d”,a0);可写为可写为printf(%d,*p);a0a1 a2 a3 a4aa5 a6 a7 a8 a9p使使p指向指向a1p=p+1;相当于相当于p=&a1; a1和和*p代表同一个存储单元代表同一个存储单元 scanf(“%d”,&a1);可写为可写为scanf(%d,p);printf(“%d”,a1);可写为可写为printf(%d,*p);pa0a1 a2 a3 a4aa5 a6 a7 a8 a9p使使p指向指向a2p=p+1;相当于相当于p=&a2; a2和和*p代表同一个存储单元代表同一个存储单元 scanf(“%d”

19、,&a2);可写为可写为scanf(%d,p);printf(“%d”,a2);可写为可写为printf(%d,*p);p写法与前面一样写法与前面一样 a0a1 a2 a3 a4aa5 a6 a7 a8 a9p使使p指向指向a3执行执行p=p+1; pa0a1 a2 a3 a4aa5 a6 a7 a8 a9p使使p逐个指向逐个指向ai重复执行重复执行p=p+1; ppppppp输入都执行输入都执行scanf(%d,p);输出都执行输出都执行printf(%d,*p);a0a1 a2 a3 a4aa5 a6 a7 a8 a9p再执行再执行p=p+1;时越界时越界 ppppppppfor(p=a;

20、 pa+10; p+)scanf(%d,p);逐个给每个元素输入数据用什么语句?逐个给每个元素输入数据用什么语句? a0a1 a2 a3 a4aa5 a6 a7 a8 a9p再执行再执行p=p+1;时越界时越界 ppppppppfor(p=a; pa+10; p+)printf(%4d,*p); 逐个输出每个元素的值用什么语句?逐个输出每个元素的值用什么语句? a0a1 a2 a3 a4aa5 a6 a7 a8 a9p再执行再执行p=p+1;时越界时越界 ppppppppfor(p=a; pa+10; p+)printf(%4d,*p); 输出的同时还要累加,加什么语句?输出的同时还要累加,加

21、什么语句? sum=sum+*p;#include main() int a10=0,*p=NULL,sum=0; printf(Input scores:); for(p=a; pa+10; p+) scanf(%d,p); for(p=a; pa+10; p+) printf(%4d,*p); sum=sum+*p; printf(nsum=%dn,sum); 通过指针将数据逆置【实实例例3】假假设设数数组组a中中已已存存放放10个个数数据据,编编写写程程序序,将将这这些些数数据据按按逆逆序序重新存放在数组重新存放在数组a中。中。编程思路编程思路按逆序重新存放可采用交换数组按逆序重新存放可

22、采用交换数组元素的方法,即元素的方法,即a0与与a9交换、交换、a1与与a8交换、交换、a2与与a7交换、交换、a4与与a5交换。交换。使使p指向指向a0,用什么语句?,用什么语句? p=a;使使q指向指向a9,用什么语句?,用什么语句? 1a0 a1 a2 a3 a4a2345678910a5 a6 a7 a8 a9pqq=a+9;交换交换a0和和9,用什么语句?,用什么语句? t=*p; *p=*q; *q=t;使使p指向指向a1、q指向指向a8,用什么语句?,用什么语句? p+; q-;1a0 a1 a2 a3 a4a2345678910a5 a6 a7 a8 a9pq交换交换a1和和8

23、,用什么语句?,用什么语句? t=*p; *p=*q; *q=t;pq写法与前面一样写法与前面一样 使使p指向指向a2、q指向指向a7,用什么语句?,用什么语句? p+; q-;1a0 a1 a2 a3 a4a2345678910a5 a6 a7 a8 a9pqpqpqP向右移动、向右移动、q向左移动,用什么语句?向左移动,用什么语句? p+; q-;1a0 a1 a2 a3 a4a2345678910a5 a6 a7 a8 a9pqpqpq移动的条件是什么?移动的条件是什么? pq1a0 a1 a2 a3 a4a2345678910a5 a6 a7 a8 a9pqt=*p; *p=*q; *

24、q=t;p+;q-;pqpqwhile重复操作是重复操作是 #include main() int a10=1,2,3,4,5,6,7,8,9,10, t=0,*p=NULL,*q=NULL;printf(Original:n); for(p=a; pa+10; p+)printf(%4d,*p);printf(n); p=a; q=p+9; while(pq) t=*p; *p=*q; *q=t; p+; q-; printf(Final:n); for(p=a; pa+10; p+)printf(%4d,*p); printf(n);通过指针排序数据【实实例例4】通通过过指指针针将将8名名

25、候候选选人人的的投投票数由多到少排序。票数由多到少排序。#include main() int a8=34,56,45,57,69,48,79,61, *p=a,i=0,j=0,k=0,t=0; for(i=0; i7; i+) k=i; for(j=i+1; j8; j+) if(pkpj) k=j; t=pi; pi=pk; pk=t; for(i=0; i成员名成员名printf(学生基本信息:n姓名=%sn 学号=%sn 身份证=%sn出生日期=%d-%d-%dn 家庭地址=%sn, (*stup).name, (*stup).sno, (*stup).sid, (*stup).bir

26、th.year, (*stup).birth.month, (*stup).birth.day, (*stup).address);printf(学生基本信息:n姓名=%sn 学号=%sn 身份证=%sn 出生日期=%d-%d-%dn家庭地址=%sn, stup-name, stup-sno, stup-sid, stup-birth.year, stup-birth.month, stup-birth.day, stup-address); 可利用指向结构体数组的指针变量来读取结构体中第一个元素的内容。Student stu50 , *stup=&stu0;printf(学生基本信息:姓名=

27、%s, 学号=%s, 身份证=%s, 出生日期=%d-%d-%d, 家庭地址=%sn, stup-name,stup-sno, stup-sid, stup-birth.year, stup-birth.month, stup-birth.day, stup-address);指针的后移就是用stup=stup+1;在这里指针后移就是第二个学生信息的首地址Student stu50 , *stup=&stu0;for(;stupname, stup-sno, stup-sid, stup-birth.year, stup-birth.month, stup-birth.day, stup-ad

28、dress);指针处理人数变动-结构类型指针stu0.snostu0.namestu0.sidstu0.birthstu0.address40字节20字节20字节12字节200字节张三201006050141020319901012304519901012广东省广州市天河区天河北路123号stup或stustu1.snostu1.namestu1.sidstu1.birthstu1.address40字节20字节20字节12字节200字节李四20100605024202031989081720341989817北京市海淀区学院路810号stup+1或stu+1malloc函数函数的原型为: v

29、oid * malloc(unsigned int size);其作用是在内存的动态存储区中分配一个长度为size的连续空间。此函数返回一个指向分配域起始地址的指针。如果该函数没有能成功执行,如内存空间不足,则返回一个空指针。下列语句申请一个前面定义的结构体所占空间,即292个字节大小。同时将申请空间的首地址赋给一个结构体类型的指针变量。Student *stup;stup = (Student *)malloc(sizeof(Student);其中的(Student *)称为强制转换:因为malloc函数的返回值是指向void的指针,如果我们将这个返回值直接赋给stup指针变量,会出现编译错

30、误。而进行这个强制转换,就是为了告诉编译器:我们知道这个类型不匹配问题,但是没关系,请不要把它当做错误对待。 malloc函数申请空间Free函数的函数原型为: void free(void *p)其作用是释放由p指向的内存区,从而使得这部分内存区能被其他变量使用。该函数没有返回值。如上面申请了空间。然后可以释放该空间:free(stup);有了存储空间的分配和释放库函数,在案例程序“学生信息管理系统”中就可以根据实际情况进行存储空间的动态分配。首先确定要保存的学生信息数量,然后就可以动态分配空间了。printf(请输入要录入的学生总数:); scanf(%d, &total);stup =

31、(Student *)malloc(total*sizeof(Student);free函数释放空间Student stu50 改为 Student *stu加上#include 修改insert()函数案例实施-用指针处理学生人数变动int insert() while(total = total)printf(对不起,由于人数已满,不能再添加新学生信息n);return 1; printf(请输入学生姓名:); scanf(%s, stucurrent.name); printf(请输入学生学号:); scanf(%s, stucurrent.sno); printf(请输入学生身份证号码

32、:); scanf(%s, stucurrent.sid); printf(请输入学生出生日期,格式(年-月-日):); scanf(%d-%d-%d, &stucurrent.birth.year, &stucurrent.birth.month, &stucurrent.birth.day);printf(请输入学生家庭地址:); scanf(%s, stucurrent.address);current+;return 0;案例实施-用指针处理学生人数变动处理处理“图书信息管理系统图书信息管理系统”的动态图书数据的动态图书数据至此,已经完成对存储学生信息的存储空间动态分配。现在到了你管理图书信息存储空间动态分配的时候了。继续完善你的案例程序,使之可以对图书信息存储空间的动态分配。具体要求:(1)编写能管理图书存储空间动态分配的案例程序;(2)在codeBlocks环境下调试你的程序,使之正确运行。学生练习学生练习

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号