CC程序设计复合数据类型实用教案

上传人:M****1 文档编号:571277093 上传时间:2024-08-09 格式:PPT 页数:63 大小:1.92MB
返回 下载 相关 举报
CC程序设计复合数据类型实用教案_第1页
第1页 / 共63页
CC程序设计复合数据类型实用教案_第2页
第2页 / 共63页
CC程序设计复合数据类型实用教案_第3页
第3页 / 共63页
CC程序设计复合数据类型实用教案_第4页
第4页 / 共63页
CC程序设计复合数据类型实用教案_第5页
第5页 / 共63页
点击查看更多>>
资源描述

《CC程序设计复合数据类型实用教案》由会员分享,可在线阅读,更多相关《CC程序设计复合数据类型实用教案(63页珍藏版)》请在金锄头文库上搜索。

1、 例例 交换交换( jiohun)( jiohun)两数。两数。voidswap();voidswap();main()main()inta,b;inta,b;scanf(%d%d”,&a,&b);scanf(%d%d”,&a,&b);swap(&a,&b);swap(&a,&b);printf(“%d,%d”,a,b);printf(“%d,%d”,a,b); voidswap(int*p1,int*p2)voidswap(int*p1,int*p2)intt;intt;t=*p1,*p1=*p2,*p2=t;t=*p1,*p1=*p2,*p2=t; 2000H2001H2EA0H2EA1H

2、a=10 b=8内存(ni cn) 地址(dzh)变量108指针变量p2=&b=2EA0H:3100H3101H3802H3803H2000H2EA0Hp1=&a=2000H第1页/共62页第一页,共63页。变量的指针变量1)指针变量的定义*;例int*p1,*p2;2)指针变量的赋值指针变量=&变量例先定义后赋值:p1=&a;p2=&b;定义时赋初值:inta,*prt=&a;其中(qzhng):&是取指针(地址)运算符。赋初值问题:一个指针变量被定义后,在赋予某一变量的指针以前,其值是随机的,这个随机数可能恰好是系统区的某单元的地址。在系统不知和不受系统管理的情形下改写其中(qzhng)内

3、容是危险的。变量的地址是由系统分配和管理的,因而是安全的。3)指针变量的使用p1=&a;p2=&b;scanf(“%d%d”,p1,p2);t=*p1;*p1=*p2;*p2=t;第2页/共62页第二页,共63页。其中:*号是取值运算符。*与&是一对互逆运算。例如:*(&a)a;&(*p)p*指针(zhzhn)变量变量例如:p=&a;*p就是a;定义时的*与使用时的*含义不同,前者表示定义的是指针(zhzhn)变量;后者是对变量的取值运算。定义了一个某类型的指针(zhzhn)变量后,它可以指向任意一个同类型变量。4)指针(zhzhn)变量作函数参数主调函数被调函数实参形参&appp第3页/共6

4、2页第三页,共63页。6.2 数组类型数组的特点: (1) 数组中的每一个元素均属于同一类型,我们称这种类型为数组的基类型; (2) 每个数组中的元素个数一经确定后就保持(boch)不变,我们称它为数组的长度; (3) 数组中的每个元素均为变量,我们用数组下标来直接访问数组的元素; (4) 数组中的元素还允许是数组类型,从而产生二维数组、多维数组等结构; (5) 在数组定义中,常量表达式的值虽然指出了数组元素的个数,但C 编译器不做越界检查; (6) 数组名表示数组所用空间的首地址,也就是数组第0个元素的地址。是一个常量地址。一、一维数组的声明 格式:类型 数组名常量表达式;二、一维数组的引用

5、与初始化第4页/共62页第四页,共63页。引用形式引用形式(xngsh)(xngsh): 数组名数组名 下标下标 初始化形式初始化形式(xngsh)(xngsh):存储类别:存储类别 数据类型数据类型 数组名数组名 数组长度数组长度=初始初始化值化值 ;例:例: static int a5=10,20,30,40,50; static int a5=10,20,30,40,50;一般要求:只有定义为静态或外部存储的才能初始化。一般要求:只有定义为静态或外部存储的才能初始化。三、数组作为函数的参数(传递地址)三、数组作为函数的参数(传递地址)例:对一字符串反序输出。(例:对一字符串反序输出。(e

6、xinver.c)exinver.c)四、二维数组的声明四、二维数组的声明形式形式(xngsh)(xngsh): 类型类型 数组名数组名 常量表达式常量表达式 常量表达式常量表达式 ;如:如:int scores503;int scores503;说明:编译程序为二维数组分配存储空间时是按行进行的,即先按顺序说明:编译程序为二维数组分配存储空间时是按行进行的,即先按顺序存放第一行的所有数据,然后接着按顺序存放第二行的所有数据,如此存放第一行的所有数据,然后接着按顺序存放第二行的所有数据,如此类推。二维数组类推。二维数组scoresscores的存储空间分配如下图所示:的存储空间分配如下图所示:

7、第5页/共62页第五页,共63页。 . 25000 scores00 25002 scores01 25004 scores02 25006 scores10 25008 scores11 25010 scores12 . . . . 25298 scores492 . 第6页/共62页第六页,共63页。五、二维数组元素的引用与初始化引用形式: 数组名行下标列下标 /下标为整数类型的表达式如:scores201=100;初始化形式:存储类别 数据类型 数组名常量1常量2=初值;如:static int s34=50,60,80,20,40,90,70,100,10;例 矩阵行列互换。Exmat

8、rix.c 1 2 3 4 1 5 9 5 6 7 8 2 6 10 9 10 11 12 3 7 11 4 8 12 六、指针(zhzhn)与数组在语言中,指针(zhzhn)与数组之间的关系是十分密切的。指针(zhzhn)类型变量可以当作数组使用,数组类型变量也可以当作指针(zhzhn)使用,即在语第7页/共62页第七页,共63页。言中,我们可以象访问指针一样访问数组,也可以象访问数组一样访问指针。其言中,我们可以象访问指针一样访问数组,也可以象访问数组一样访问指针。其区别为:数组名不能自加、自减,但指针变量可以。区别为:数组名不能自加、自减,但指针变量可以。例如:例如:int a10,*p

9、;int a10,*p; p=a; p=a; p+ p+或或p-p-都是成立的,而都是成立的,而a+ a+ 或或a-a-是不成立的。是不成立的。而而 * *(a+I)a+I)、aIaI、*(p+I)*(p+I)、pIpI是等价的。是等价的。七、指针数组与数组指针七、指针数组与数组指针指针数组:指基类型为指针类型的数组,即该数组的每个元素均为一个指针。如指针数组:指基类型为指针类型的数组,即该数组的每个元素均为一个指针。如果我们需要保留许多指针的值,也就是要保存多个变量的地址,就可以使用指针果我们需要保留许多指针的值,也就是要保存多个变量的地址,就可以使用指针数组。数组。定义形式:数据类型定义形

10、式:数据类型 * *数组名数组名 数组长度数组长度 ;如:如: int *p10; / int *p10; /在此声明了一个包含在此声明了一个包含1010个整数类型指针变量的数组个整数类型指针变量的数组p p。这里。这里(zhl)*(zhl)*并不是数组名字的组成部分,它只是告诉编译程序并不是数组名字的组成部分,它只是告诉编译程序p p是一个整数类型的是一个整数类型的指针数组,而不是简单的整数类型数组。指针数组,而不是简单的整数类型数组。 第8页/共62页第八页,共63页。例:建立如下距阵并输出例:建立如下距阵并输出 1 0 0 0 1 1 0 0 0 1 0 1 0 1 0 0 1 0 1

11、0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 1 0 1 0 0 0 1 1 0 0 0 1程序为:程序为: main() main() int a55=0,*p5,i,j; int a55=0,*p5,i,j; for(i=0;i5;i+) for(i=0;i5;i+)pi=&ai0; /pi=&ai0; /指针数组指针数组p p 指向指向(zh xin)a(zh xin)a数组的每行起始地址数组的每行起始地址for(i=0;i5;i+)for(i=0;i5;i+) *(pi+i)=1; / *(pi+i)=1; / 对主对角线赋值对主对角线赋值 *(pi+4-

12、i)=1; / *(pi+4-i)=1; / 对副对角线赋值对副对角线赋值 for(i=0;i5;i+) / for(i=0;i5;i+) / 用二层循环打印二维数组用二层循环打印二维数组 for(j=0;j5;j+) for(j=0;j5;j+) printf(“%2d”,*(pi+j);/ printf(“%2d”,*(pi+j);/每个指针数组指向每个指针数组指向(zh xin)(zh xin)每列的表示每列的表示 printf(n); printf(n); 第9页/共62页第九页,共63页。数组指针数组指针(zhzhn)(zhzhn):定义形式:数据类型定义形式:数据类型 (* *指针

13、变量名)指针变量名) 长度长度 ;如:如:int (*array_ptr)10;/int (*array_ptr)10;/申明了一个指针类型的变量申明了一个指针类型的变量array_ptr,array_ptr,它指向一个长度为它指向一个长度为10 10 的整数数组。的整数数组。数组指针可以看成是二维的,此时与二维数组在存储上相数组指针可以看成是二维的,此时与二维数组在存储上相同,但变量名是指针变量,可以进行同,但变量名是指针变量,可以进行(jnxng)(jnxng)指针运算。指针运算。引用方式:引用方式:若有:若有:int (*p)4int (*p)4,a34;a34; p=a; p=a;引用

14、:引用: *(*(p+I)+j) aIj *(*(p+I)+j) aIj例:例:exarrp.c exarrp.c 第10页/共62页第十页,共63页。6.36.3字符串字符串一、字符串常量与变量:字符串变量是一个基类型为字符类型的数组变量,同样遵循“先声明(shngmng)、后使用”的原则,我们在声明(shngmng)字符串变量时,可用字符串常量作初始化。如:char name10=“limeixue”;初始化方式有三种。也可以定义指针变量指向字符串。如:char *name=“limeixue”;二、字符串数组定义:char * name12;例:按姓名查询。Exsearch.c第11页/

15、共62页第十一页,共63页。三、字符三、字符(z f)(z f)串库函数串库函数(string.h)(string.h)1. char * strcat(char *str1, const char *str2);1. char * strcat(char *str1, const char *str2); 作用:作用: 将字符将字符(z f)(z f)串串str2str2连接到字符连接到字符(z f)(z f)串串str1str1后,形成一个新字后,形成一个新字符符(z f)(z f)串,原先串,原先str1str1的结束标记的结束标记00被取消。函数返回值为被取消。函数返回值为str1st

16、r1。注。注意为字符意为字符(z f)(z f)串变量串变量str1str1分配的存储空间一定要足够大,能够容纳两个分配的存储空间一定要足够大,能够容纳两个字符字符(z f)(z f)串连接后的新字符串连接后的新字符(z f)(z f)串。串。 如:如:char s1=“good ”,s2=“evening!”; strcat(s1,s2);char s1=“good ”,s2=“evening!”; strcat(s1,s2);2. char * strchr(const char *str, int ch);2. char * strchr(const char *str, int ch)

17、; 作用:作用: 寻找字符寻找字符(z f)(z f)串串strstr中第一次出现字符中第一次出现字符(z f)ch(z f)ch的位置。如果的位置。如果找到找到chch,则返回指向该位置的指针;否则返回空指针。,则返回指向该位置的指针;否则返回空指针。3. int strcmp(const char *str1, const char *str2);3. int strcmp(const char *str1, const char *str2); 作用:作用: 比较字符比较字符(z f)(z f)串串str1str1和和str2str2的内容是否相同。如果的内容是否相同。如果str1str

18、1小于小于str2str2则返回负数;如果则返回负数;如果str1str1等于等于str2str2则返回零;如果则返回零;如果str1str1大于大于str2str2则返回正数。则返回正数。4. char * strcpy(char *str1, const char *str2);4. char * strcpy(char *str1, const char *str2); 作用:将作用:将str2str2指向的字符指向的字符(z f)(z f)串复制到串复制到str1str1指向的位置中并返回指向的位置中并返回str1str1。注意为注意为str1str1分配的存储空间必须能放得下分配的存

19、储空间必须能放得下str2str2指向的字符指向的字符(z f)(z f)串。串。 注:注:char *str; strcpy(str,“Be careful”); char *str; strcpy(str,“Be careful”); 引起的问题。引起的问题。第12页/共62页第十二页,共63页。5. unsigned int strlen(const char *str);5. unsigned int strlen(const char *str);作用:返回字符串作用:返回字符串strstr中的字符个数中的字符个数, ,包括其中的空格与转义字符包括其中的空格与转义字符, , 但不包括

20、字符串结束但不包括字符串结束(jish)(jish)标记标记00。6. char *strstr(const *str1, const char *str2);6. char *strstr(const *str1, const char *str2);作用:寻找字符串作用:寻找字符串str2str2在字符串在字符串str1str1中第一次出现的位置,不包中第一次出现的位置,不包括括str2str2的结束的结束(jish)(jish)标记标记00。如果找到。如果找到str2str2,则返回指向该位置,则返回指向该位置的指针;否则返回空指针。的指针;否则返回空指针。四、字符串应用四、字符串应用例

21、例1 1: 按姓名排序。(按姓名排序。(exnsort.c)exnsort.c)冒泡法排序(从小到大):冒泡法排序(从小到大):n n个数参与排序,每趟找出最大数存个数参与排序,每趟找出最大数存与最后,共与最后,共n-1n-1趟。每一趟中对相邻的两个元素进行比较,不符趟。每一趟中对相邻的两个元素进行比较,不符合次序的立即交换。合次序的立即交换。例例2 2:打印出全班每个学生姓名的长度。:打印出全班每个学生姓名的长度。Exlen.cExlen.c第13页/共62页第十三页,共63页。6.4结构(jigu)体类型一、概述记录型数据与结构体一组相关的不同数据类型的数据项,可作一个整体来处理。PASC

22、AL中称“记录型”数据,C中称结构体类型数据。与数组有明显不同,数组要求其所有成员的类型、长短(chngdun)一样结构体类型和结构体变量。struct student int num; char name20; char sex; struct date birthday; float score; stu1, stu2; struct date int month; int day; int year; 什么情形时适用(shyng)结构体或数组?第14页/共62页第十四页,共63页。二、定义结构体的类型(lixng)和变量定义结构体类型(lixng)一般形式:例参见上页struct 结构体

23、类型名 分量1; 分量2; 分量3; : 分量: 分量又称域或成员。 当分量是结构体时,形成定义时的嵌套。 第15页/共62页第十五页,共63页。定义结构体类型(lixng)的变量定义结构(jigu)体变量三种形式:1. 定义(dngy)结构体的同时定义(dngy) 例如前页例。2. 先定义(dngy)结构体,后定义(dngy)结构体变量 例:struct stu . ; . struct stu st1,st2;3. 直接定义(dngy) 例:struct . 变量名表; 在struct 后不出现结构体类型名第16页/共62页第十六页,共63页。三、结构(jigu)体变量的引用结构体类型不是

24、(bshi)存储数据的实体,即系统并不是(bshi)给它分配内存,它仅是一种数据类型,与int,char类似,用来定义一种数据类型的变量;结构体类型变量才是存储数据的实体,结构体变量的分量具体分配存储单元,等价于一组变量。因此我们引用的是结构体变量。引用结构体变量只能通过引用结构体变量的分量(成员)实现(在I/O时,赋值时等)。用“.”或“-”引用。例如:sum=st1.score+st2.score;成员运算符(多级)例如:age=1999-st1.birthday.year;_QC允许将一结构体变量的所有分量赋予同类的另一变量。例如:st2=st1;例ex2stu1.c第17页/共62页第

25、十七页,共63页。四、结构(jigu)体数组以某结构体类型(lixng)也可以定义数组例按姓名查询。ex2stuarr.cstruct student int num; char name30; char sex; float score; stu30; 每个下标变量stui 都有结构体类型(lixng)student 的各个分量; 下标变量的引用同变量。 第18页/共62页第十八页,共63页。五、结构(jigu)体类型的指针指向结构体类型(lixng)变量的指针 指向结构体类变量的指针就是该变量所占用的内存(ni cn)区段的首址。例 struct student int num; char

26、 name3; char sex; float score; st1,st2,st3; struct student *p=&st1; printf(“%d,%s”, st1.num, st2.name); printf(“%d,%s”, (*p).num, (*p).name); printf(“%d,%s”, p-num, p-name);numnamesexscore: 2A00Hst1p第19页/共62页第十九页,共63页。指向结构(jigu)体类型数组的指针 指向结构体类数组的指针就是该数组所占用的内存(ni cn)区段的首址。例 struct student int num; ch

27、ar name3; char sex; float score; st30=; struct student *p=st; for(p=st;pnum, p-name,p-sex,p-score);: 2A00Hst0st1st2st3:2A0AH 2A14H2AE0Hp第20页/共62页第二十页,共63页。例:若干个学生的信息包括:学号、姓名、三门可课的成绩(c语言、电子(dinz)技术、控制理论)、总分,要求打印一份名次表。分析:总分是需要计算的。 按总分从小到大排序(bubble)。 按行输出。Ex2table.c第21页/共62页第二十一页,共63页。指向结构体类型数据(shj)的指针

28、一、指向结构体类型变量的指针例 打印通讯录。(excommu.c)二、指向结构体数组的指针例用结构指针建立一个图书检索系统。按书名检索。(exsearch.c)三、结构指针的使用例链表。链表的建立、遍历、查找、插入、删除操作。第22页/共62页第二十二页,共63页。2024/8/9链表 什么什么(shnme)(shnme)是链表?是链表?线性表:有限个元素的有序集合。可用数组或链表表示。 数组和链表两 者都逻辑连续,但后者可以(ky)在空间不连续。 动态数据结构:其大小可变;动态分配存储空间。链表是最简单的一种,属于线性动态数据结构,树是非线性动态数据结构。链表:链表中的一个元素称为一个结点或

29、节点。每个结点由两部分组成:数据部分、指向上下结点的指针。靠这样的指针把各个结点串联起来构成链表。分单向、双向链表,后者可以(ky)两方向连接。 00单向(dn xin)链表双向链表0数据部分数据部分第23页/共62页第二十三页,共63页。2024/8/9链表为什么使用(shyng)链表?1)不需要连续存储空间,可利用内存碎片;2)插入删除元素不需移动其它元素,处理速度快;3)动态分配存储空间,不必以最大可能长度预定存储空间, 且可以随意扩充表的容量(rngling)。动态分配存储空间(使用函数)void *malloc(unsigned size)函数(memory allocation):

30、在内存的动态存储区中分配一个长度为size的连续空间,size为结点元素各成员项的总字节数,可以用sizeof(数据类型名)运算符获得。该函数的返回值是一个指针,它的值是所分配存储区的起始地址,当该函数未成功执行时,返回值为0。如: struct student int num; float score; struct student *next;*p1;p1=(struct student *)malloc(sizeof(struct student);第24页/共62页第二十四页,共63页。 void free(ptr) void free(ptr)函数函数: :该函数释放由该函数释放由p

31、trptr指向的内存区。指向的内存区。PtrPtr是最近一次是最近一次调用调用calloccalloc或或mallocmalloc函数时返回的值。函数时返回的值。用结构体及结构体指针构造链表和链表操作用结构体及结构体指针构造链表和链表操作(1 1)建立链表。链表的建立过程可以描述如下)建立链表。链表的建立过程可以描述如下(rxi)(rxi): 假设结构体定义如下假设结构体定义如下(rxi)(rxi): struct node struct node int num; int num; float s; float s; struct node *next; struct node *next;

32、 ; ; 1. 1. 为了建立链表,在程序中需要使用两个指向结构的指针。为了建立链表,在程序中需要使用两个指向结构的指针。 例如:例如:struct node *p1, *p2;struct node *p1, *p2; 建立链表时,首先使用建立链表时,首先使用mallocmalloc函数为第一个元素分配存储函数为第一个元素分配存储 空间,并把该空间的地址赋予空间,并把该空间的地址赋予p1p1,使,使p1p1指向该存储空间:指向该存储空间: p1=(struct node *)malloc(sizeof(struct node); p1=(struct node *)malloc(sizeof

33、(struct node);第25页/共62页第二十五页,共63页。2.2.2.2.把把p1p1p1p1的值赋予的值赋予p2p2p2p2,从而使,从而使p2p2p2p2也指向该存储空间,便于连接也指向该存储空间,便于连接 后面的结点元素。后面的结点元素。3.3.3.3.通过通过p1p1p1p1访问成员访问成员numnumnumnum和和s s s s,并对其赋值:,并对其赋值: p1-num=1; p1-num=1; p1-num=1; p1-num=1; scanf(“%f”,&(*p1).s); scanf(“%f”,&(*p1).s); scanf(“%f”,&(*p1).s); sca

34、nf(“%f”,&(*p1).s); 至此,链表中的第一个元素在内存中已建立,并且其数据部至此,链表中的第一个元素在内存中已建立,并且其数据部 分已被赋值。分已被赋值。4. 4. 4. 4. 建立链表的第二个元素时,再次使用建立链表的第二个元素时,再次使用mallocmallocmallocmalloc函数:函数: p1=(struct node *)maloc(sizeof(struct node); p1=(struct node *)maloc(sizeof(struct node); p1=(struct node *)maloc(sizeof(struct node); p1=(st

35、ruct node *)maloc(sizeof(struct node); 这时这时p1p1p1p1指向第二个元素的存储空间,通过指向第二个元素的存储空间,通过p1p1p1p1访问访问numnumnumnum和和s:s:s:s: p1-num=2; scanf(“%f”,&(*P).s); p1-next=p2; p1-num=2; scanf(“%f”,&(*P).s); p1-next=p2; p1-num=2; scanf(“%f”,&(*P).s); p1-next=p2; p1-num=2; scanf(“%f”,&(*P).s); p1-next=p2; 从而第二个元素指向第一个

36、元素,将两个元素链接在一起。从而第二个元素指向第一个元素,将两个元素链接在一起。 最后调整指针为:最后调整指针为:p2=p1;p2=p1;p2=p1;p2=p1;使指针使指针p2p2p2p2指向第二个指向第二个( ( ( (始终指向最始终指向最 后一个后一个) ) ) )元素。反复执行上面的四个语句,就可以不断地把元素。反复执行上面的四个语句,就可以不断地把 元素加入到链表中去。这种建立链表的方法是从表头插入元素加入到链表中去。这种建立链表的方法是从表头插入(ch r)(ch r)(ch r)(ch r)的的 过程,指针过程,指针p2p2p2p2总是指向最后出现的那个元素。总是指向最后出现的那

37、个元素。第26页/共62页第二十六页,共63页。链表建立函数:链表建立函数:# define NULL 0 /* # define NULL 0 /* 定义空指针,作为表尾结点定义空指针,作为表尾结点(ji din)(ji din)的的nextnext域域*/*/struct node /* struct node /* 结点结点(ji din)(ji din)元素的数据结构类型元素的数据结构类型 */ */ int num; int num; struct node *next; struct node *next; ; ;int n=0; /* int n=0; /* 定义外部变量定义外部

38、变量n n,用来记录结点,用来记录结点(ji din)(ji din)的个数的个数 */ */struct node *creat() /*struct node *creat() /*函数的返回值为指向头结点函数的返回值为指向头结点(ji din)(ji din)的指针的指针*/*/ struct node *p1,*p2,*head; struct node *p1,*p2,*head; p2=NULL; /* p2=NULL; /* 最先加入的为表尾结点最先加入的为表尾结点(ji din)(ji din),将其,将其nextnext域置为域置为NULL*/ NULL*/ printf(n

39、please input num:n); printf(nplease input num:n);dodo p1=(struct node*)malloc(sizeof(struct node); p1=(struct node*)malloc(sizeof(struct node); /* /* 申请一个结点申请一个结点(ji din)(ji din)空间空间 */ */ 第27页/共62页第二十七页,共63页。scanf(%d,&p1-num); /* scanf(%d,&p1-num); /* scanf(%d,&p1-num); /* scanf(%d,&p1-num); /* 输入结

40、点元素的数据部分输入结点元素的数据部分*/*/*/*/ scanf(“%f”,&p1-s); scanf(“%f”,&p1-s); scanf(“%f”,&p1-s); scanf(“%f”,&p1-s); p1-next=p2; /* p1-next=p2; /* p1-next=p2; /* p1-next=p2; /* 使新生成的结点元素指向前一结点使新生成的结点元素指向前一结点 */ */ */ */ p2=p1;/* p2=p1;/* p2=p1;/* p2=p1;/* 调整调整(tiozhng)p2(tiozhng)p2(tiozhng)p2(tiozhng)p2,使其始终指向最后

41、出现的那个,使其始终指向最后出现的那个元素元素 */ */ */ */ n+; /* n+; /* n+; /* n+; /* 结点数加结点数加1 */1 */1 */1 */ while(p1-num!=-1); while(p1-num!=-1); while(p1-num!=-1); while(p1-num!=-1);n - -; /* n - -; /* n - -; /* n - -; /* 结点数应减去最后输入的作为结束标志的结点结点数应减去最后输入的作为结束标志的结点*/*/*/*/p2=p2-next;/* p2=p2-next;/* p2=p2-next;/* p2=p2-

42、next;/* 最后一次生成的结点不作为链表的一部分最后一次生成的结点不作为链表的一部分, , , ,应跳应跳过该结点过该结点*/*/*/*/ head=p2; /* head=p2; /* head=p2; /* head=p2; /* 用用headheadheadhead作头指针,指向表头元素作头指针,指向表头元素 */ */ */ */ return(head);/* return(head);/* return(head);/* return(head);/* 返回链表头指针返回链表头指针*/*/*/*/ 第28页/共62页第二十八页,共63页。 (2) 链表的遍历(输出) 函数如下:

43、void print(head)struct node *head; struct node *p; printf(n The table is:n); p=head;/*以表尾结点中指针为NULL做为遍历结束的标志(biozh)*/ while(p!=NULL) printf(%4d-%7.2f,p-num,p-s); p=p-next; /* 移向下一个结点*/ (link_t.c)第29页/共62页第二十九页,共63页。2024/8/9链表插入结点( jidin)删除结点( jidin)0单向(dn xin)链表2100h2100h2180h2010h2050h2050h2a02h2a0

44、2h2100h2180h0单向(dn xin)链表2100h2050h2a02h2010h2050h2100h2a02h2a02h第30页/共62页第三十页,共63页。指针在函数中的应用一、指针作为函数的参数用指针作为函数的参数,应该在主调函数和被调用函数分别(fnbi)定义指针变量;在函数调用中实参指针和形参指针类型应一致。例分析结果。(expoint.c)# include stdio.h”sub(int *s,int y) static int t=3; y=st; st=st+4; t- -; main() int a=1,2,3,4,i, x=0; printf(x ain); fo

45、r(i=3;i=0;i-) sub(a,x); printf(%d %dn,x,ai); X ai0 80 80 70 60 60 5第31页/共62页第三十一页,共63页。二、二、 函数的指针及函数的指针变量函数的指针及函数的指针变量概念概念函数的指针就是函数代码在内存中所占存储区的首地址。函数的指针就是函数代码在内存中所占存储区的首地址。函数的指针变量函数的指针变量( (指向函数的指针变量指向函数的指针变量) )存放函数的指针,用来指向某函数。存放函数的指针,用来指向某函数。p+,p+np+,p+n无意义。可以在不同时间无意义。可以在不同时间(shjin)(shjin)用同一个指针变量调用

46、不同函数。用同一个指针变量调用不同函数。指向函数的指针变量的定义指向函数的指针变量的定义类型标示符类型标示符(*(*变量名变量名)();)();例如:例如:float(*p)();float(*p)();表示表示pp是一个指向返回值为是一个指向返回值为floatfloat型的函数的指针变量。型的函数的指针变量。运用运用例例 求求n!n!。赋值形式:赋值形式:=;调用形式:调用形式:(*(*指向函数的指针变量指向函数的指针变量)()(实参表实参表) );(expfun.c)(expfun.c)第32页/共62页第三十二页,共63页。# include stdio.h# include stdio

47、.h# include stdio.h# include stdio.hint add(n)int add(n)int add(n)int add(n)int n;int n;int n;int n; int sum=1,i; int sum=1,i; int sum=1,i; int sum=1,i; for(i=1;i=n;i+) for(i=1;i=n;i+) for(i=1;i=n;i+) for(i=1;i=n;i+) sum=sum*i; sum=sum*i; sum=sum*i; sum=sum*i; return(sum); return(sum); return(sum);

48、return(sum); main()main()main()main() int n,m,(*p)(); int n,m,(*p)(); int n,m,(*p)(); int n,m,(*p)(); printf(input n:n); printf(input n:n); printf(input n:n); printf(input n:n); scanf(%d,&n); scanf(%d,&n); scanf(%d,&n); scanf(%d,&n); p=add; p=add; p=add; p=add; m=(*p)(n); m=(*p)(n); m=(*p)(n); m=(*p

49、)(n); printf(n!=%dn,m); printf(n!=%dn,m); printf(n!=%dn,m); printf(n!=%dn,m); 赋值赋值调用调用(dioyng)(dioyng)第33页/共62页第三十三页,共63页。用指向函数的指针变量用指向函数的指针变量(binling)(binling)作函数的参数作函数的参数在在C C语言中可以把指向函数的指针变量语言中可以把指向函数的指针变量(binling)(binling)作为参数传作为参数传递到其他函数。例如在有些程序中,用户可以从各种可供选择的选择递到其他函数。例如在有些程序中,用户可以从各种可供选择的选择项中选用他

50、所需的操作,而各选项又是由一个独立的函数来实现的,项中选用他所需的操作,而各选项又是由一个独立的函数来实现的,在程序实现中就可以采用函数指针作参数的方式完成。在程序实现中就可以采用函数指针作参数的方式完成。第34页/共62页第三十四页,共63页。例 编写一个简单的帐单系统,包括:录入、删除、显示 帐目、退出功能(gngnng),各功能(gngnng)项所对应的实现函数分别为 enter()、delete()、review()、quit()。# include stdio.h# include stdio.h# include stdio.h# include stdio.h” ”int ent

51、er(),delete(),review(),quit();int enter(),delete(),review(),quit();int enter(),delete(),review(),quit();int enter(),delete(),review(),quit();main()main()main()main() int i; int (*p)(); int i; int (*p)(); int i; int (*p)(); int i; int (*p)(); i=menu(); i=menu(); i=menu(); i=menu(); switch(i) switch(i

52、) switch(i) switch(i) case 1: p=enter;break; case 1: p=enter;break; case 1: p=enter;break; case 1: p=enter;break; case 2: p=delete;break; case 2: p=delete;break; case 2: p=delete;break; case 2: p=delete;break; case 3: p=review;break; case 3: p=review;break; case 3: p=review;break; case 3: p=review;b

53、reak; case 4: p=quit;break; case 4: p=quit;break; case 4: p=quit;break; case 4: p=quit;break; process(p); process(p); process(p); process(p); 第35页/共62页第三十五页,共63页。menu()menu() char ch; char ch; do do printf(1.entern); printf(1.entern); printf(2.Deleten); printf(2.Deleten); printf(3.Reviewn); printf(3

54、.Reviewn); printf(4.Quitn); printf(4.Quitn); printf(Select a number:); printf(Select a number:); ch=getche(); ch=getche(); printf(n); printf(n); while(!strchr(1234,ch); while(!strchr(1234,ch); return(ch-48); return(ch-48); 第36页/共62页第三十六页,共63页。process(int (*f)()process(int (*f)()process(int (*f)()pro

55、cess(int (*f)() (*f)(); (*f)(); (*f)(); (*f)(); enter()enter() printf(In enter!n); printf(In enter!n); delete()delete()delete()delete() printf(In deleten); printf(In deleten); review()review() printf(In printf(In review!n);review!n); quit()quit()quit()quit() printf(In quit!n); printf(In quit!n); 第37

56、页/共62页第三十七页,共63页。返回指针值的函数定义类型标示符*函数名(参数表);例如:char*person(charname,charsex);函数person()返回的指针指向char型量。例编写(binxi)一个strchr()函数,它的作用是在一个字符串中找一个指定的字符,返回该字符的地址。#includestdio.hchar*strch(char*str,charch)while(*str!=ch)str+;/*查找指定字符的位置*/return(str);/*返回找到字符的地址*/第38页/共62页第三十八页,共63页。main()main()main()main() cha

57、r *strchr( ); char *strchr( ); char *strchr( ); char *strchr( ); char *pt,ch,line=I love china.; char *pt,ch,line=I love china.; char *pt,ch,line=I love china.; char *pt,ch,line=I love china.; printf(please input char:n); printf(please input char:n); printf(please input char:n); printf(please input

58、char:n); scanf(%c,&ch); /* scanf(%c,&ch); /* scanf(%c,&ch); /* scanf(%c,&ch); /* 输入要查找的字符输入要查找的字符*/*/*/*/pt=strchr(line,ch);pt=strchr(line,ch);pt=strchr(line,ch);pt=strchr(line,ch);/*/*/*/*调用函数查找指定调用函数查找指定(zhdng)(zhdng)(zhdng)(zhdng)字符,将返回的地址值赋给指针变字符,将返回的地址值赋给指针变量量pt*/pt*/pt*/pt*/printf(nstring star

59、ts at address %x.n,line);printf(nstring starts at address %x.n,line);printf(nstring starts at address %x.n,line);printf(nstring starts at address %x.n,line);/* /* /* /* 输出本字符串的首地址输出本字符串的首地址*/*/*/*/printf(First occurrence of char %c is address printf(First occurrence of char %c is address printf(Firs

60、t occurrence of char %c is address printf(First occurrence of char %c is address %x.n,ch,pt);%x.n,ch,pt);%x.n,ch,pt);%x.n,ch,pt);/*/*/*/*输出找到字符的地址,地址都用十六进制表示输出找到字符的地址,地址都用十六进制表示*/ */ */ */ printf(This is position %d (starting from 0)n,pt-printf(This is position %d (starting from 0)n,pt-printf(This i

61、s position %d (starting from 0)n,pt-printf(This is position %d (starting from 0)n,pt-line);line);line);line);/*/*/*/*输出找到字符的相对于首地址的偏移位置输出找到字符的相对于首地址的偏移位置*/*/*/*/ 第39页/共62页第三十九页,共63页。指针数组和二级指针概念:数组的元素(yuns)是指针变量。定义:类型标示符*数组名数组长度;例如:char*p20;定义了p0-p19计20个带下标的指针变量,都指向char型量。适合于处理字串。指针(zhzhn)数组 namename

62、0name1name2name3“Turbo C ”“MS C ”“Quick C ”:“ANSI C ”字符串第40页/共62页第四十页,共63页。二级指针二级指针二次间接二次间接(jinji)(jinji)。定义:定义:*;例如:例如:int*p;int*p;引用方式为:引用方式为:* 例例11main()main()staticchar*name=“TurboC”,“ANSIC”,“MSC”,staticchar*name=“TurboC”,“ANSIC”,“MSC”,“VisualC”,.);“VisualC”,.);char*p=name;char*p=name;inti;inti;

63、for(i=0;i10;i+)for(i=0;i10;i+)printf(“%sn”,*p+);/*?*p*/printf(“%sn”,*p+);/*?*p*/&p&a25二级指针变量二级指针变量pppp一级指针变量一级指针变量p p变量 a第41页/共62页第四十一页,共63页。例2 # include stdio.h” main() int *k,*j,i=100; j=&i; k=&j; printf(%dn,*k); getch(); 结果(ji gu):100第42页/共62页第四十二页,共63页。main函数中的参数main函数也可以有参数,它可以带两个参数。其一般形式为: mai

64、n(argc,argv) int argc; char *argv; 其中第一个形参argc是一个整型变量(binling),第二个形参argv是一个指针数组,其元素指向字符型数据。 这两个参数的值从那里传递而来呢?main()函数是主函数,它不能被程序中其它函数调用,因此显然不可能从其它函数向它传递所需的参数值,只能从程序以外传递而来。 main函数的参数传递是在命令行中,除了给出应执行的文件名外,再给出一个或多个字符串,作为传递该main函数的参数值。例如,从键盘输入以下命令行:file computer enginish 第43页/共62页第四十三页,共63页。 main函数的参数传递规

65、律与其它函数有所不同,并不是将file(文件名)传递给argc,将后面的computer和enginish传递给argv。而是将命令行中总的字符串的个数(包括文件名)传递给参数argc,上面的命令行中有三个字符串,即传递给argc的值为3;将命令行中第一个字符串(如file)的地址传递给指针数组argv中第0个元素(yun s)argv0,第二个字符串的地址传给argv1,依次类推。例1有如下main函数(其所在文件的源文件名为file1.c):# include stdio.h”main(int argc,char *argv) int i=1; while(argc1) printf(%s

66、n,argvi); -argc; i+; (file1.c)如果从键盘输入的命令行为如果从键盘输入的命令行为(xngwi)(xngwi)(xngwi)(xngwi):file1 This is a example.file1 This is a example.file1 This is a example.file1 This is a example.则输出为则输出为:(argc=5 argv0):(argc=5 argv0):(argc=5 argv0):(argc=5 argv0)This file1This file1This file1This file1isisisisa a a

67、 aexample.example.example.example.第44页/共62页第四十四页,共63页。例2编写一个(y )ren(换名)程序。# include dir.h”# include string.h”int main(int argc,char *argv) char oldnameMAXPATH,newnameMAXPATH; if (argc2) strcpy(oldname,argv1); strcpy(newname,argv2); else printf(use:jc12 oldname newnamen); exit(1); if (rename(oldname,

68、newname)=0) puts(successfuln); exit(0); else printf(nerrorn); exit(2); return(0); exren.c定义定义(dngy)(dngy)在在dir.hdir.h中中系统系统(xtng)(xtng)函数函数第45页/共62页第四十五页,共63页。指向结构体类型数据的指针一、指向结构体类型变量的指针例 打印(d yn)通讯录。(excommu.c)二、指向结构体数组的指针例用结构指针建立一个图书检索系统。按书名检索。(exsearch.c)三、结构指针的使用例链表。链表的建立、遍历、查找、插入、删除操作。第46页/共62页第

69、四十六页,共63页。2024/8/9枚举(mi j)类型Made by lut共用(n yn)体类型位域类型(lixng)别名第47页/共62页第四十七页,共63页。2024/8/9共用(nyn)体(联合)类型 什么什么(shnme)(shnme)是共用体是共用体 结构型数据类型(lixng); 存储形态:共用体类型(lixng)变量的若干分量分时共占同一存储空间。例如:union data int i; char c; long l; com;com . i= 10;com . c=A;com . l= 65535; c c i il l0000 0000 0000 0000 0000 00

70、00 0000 0000 00000000 000010100000 0000 0000 0000 1111 1111 1111 11110100 0001第48页/共62页第四十八页,共63页。2024/8/9共用(nyn)体类型共用体类型及其变量的定义(dngy)和引用 共用体类型及其变量的定义(dngy)和引用与结构体类似,本质的不同在于使用内存的方式。 类型定义(dngy):union 类型名 数据类型 变量名; 数据类型 变量名; 联合变量名表;(或;结束) 变量的定义(dngy):三种方式(同结构提变量的定义(dngy)方式) 共用体变量的引用方式:(.或-) 如前所示:com.I

71、、com.c、com.l第49页/共62页第四十九页,共63页。例1 main() union unsigned char c; unsigned int I4; z; z.I0=65; z.I1=66; printf(“%cn”,z.c); 结果(ji gu):A第50页/共62页第五十页,共63页。 例2 main() union int I2; long k; char c4; r,*s=&r; s-I0=0x39; s-1=0x38; printf(“%cn”,s-c0); 结果(ji gu):9 57 0 56 0 0 1 2 398S-I0 S-I1S-c0第51页/共62页第五十

72、一页,共63页。2024/8/9枚举类型(lixng)什么是枚举类型(lixng) 枚举是一组命名的整数常量,用以说明(shumng)可能类型变量的所有合法值。 定义类型形式 :enum 名字枚举列表 变量表; 定义变量形式(三种方式) 枚举类型的变量仅有几个确定的值。例如:enum weekday sun, mon, tue, wed, thu, fri, satworkday; 枚举元素是常量,具有数值。按顺序默认为0,1,2,.;也可以在定义时按需求指定。如:enum colorred,green,blue=8,blank,white;第52页/共62页第五十二页,共63页。应用(yng

73、yng)举例例1main() enum language basic=3,assembly,ada=100,cobel,fortran97; enum language speak; speak=fortran97; printf(“%dn”,speak); 结果:102第53页/共62页第五十三页,共63页。例2main() enum teammy,your=4,his,her=his+10; printf(“%d %d %d %dn”,my,your,his,her);结果(ji gu):0 4 5 15第54页/共62页第五十四页,共63页。类型(lixng)别名为提高程序(chngx)

74、的可读性,我们可用保留字typedef为类型起一个新名字, 这个新名字应该用一个有意义的标识符来命名。typedef 不建立新的类型,它只是为原有类型起一个新的名字而已。如:typedef char* STRING;就可以用STRING代替char *,即 STRING P;定义了一个指向字符的指针变量p。例1: typedef union long I; int k5; char c;DATE;/ 10 struct date/2+10+8=20 int cat;DATE cow;double dog;too;第55页/共62页第五十五页,共63页。 main() DATE max; pri

75、ntf(%dn”,sizeof(struct date)+sizeof(max); 结果(ji gu):30例2typedef union long x2;int y4;char z8;MYTYPE; MYTYPE them;main() printf(%dn”,sizeof(them); 结果(ji gu):8第56页/共62页第五十六页,共63页。位域 所谓的位域是以位为单位定义长度的结构体类型中的成员。位域类型及变量的定义形式: struct 位域类型名 类型 位域名1:长(二进制位数); 类型 位域名2:长(二进制位数); 变量表;注:一个位域可以定义成int,unsigned或sig

76、ned。长度为1的位域必须(bx)定义为unsigned,因为单个位不可能有符号。第57页/共62页第五十七页,共63页。位域的引用位域的引用(ynyng)(ynyng): struct packed_data struct packed_data unsigned a:2; unsigned a:2; unsigned b:6; unsigned b:6; unsigned c:4; unsigned c:4; unsigned d:4; unsigned d:4; int i; int i; data; data; a b c d i 2 6 4 4 16第58页/共62页第五十八页,共6

77、3页。例1:下列定义(dngy)中的错误。Struct twobyte unsigned I:3; unsigned j:4; unsigned :0; float k:4; unsigned :2 unsigned m:18; bit;第59页/共62页第五十九页,共63页。例2:main() struct pp unsigned i:3; unsigned j:4; unsigned k:4; unsigned :0;/下面将从下一字节(z ji)开始分配 unsigned :3; unsigned m:6; ; union uu/长度为4个字节(z ji) struct pp bb; l

78、ong int l; u; u.l=0x12345678;第60页/共62页第六十页,共63页。 printf(%u,%u,%u,%u,%dn,u.bb.i,u.bb.j,u.bb.k,u.bb.m,sizeof(struct pp); 结果(ji gu):0,15,12,6,400010010 00110100 01010110 01111000 m 3 3 k j i12 34 56 78第61页/共62页第六十一页,共63页。感谢您的观赏(gunshng)!第62页/共62页第六十二页,共63页。内容(nirng)总结例 交换两数。PASCAL中称“记录型”数据,C中称结构体类型数据。每个结点由两部分组成:数据部分、指向上下结点的指针。2)插入删除元素不需移动其它元素,处理速度快。这时p1指向第二个元素的存储空间,通过p1访问num和s:。可以在不同时间用同一个指针变量调用不同函数。sum=sum*i。printf(“%cn”,s-c0)。长度为1的位域必须定义为unsigned,因为单个位不可能有符号(fho)。感谢您的观赏第六十三页,共63页。

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

最新文档


当前位置:首页 > 高等教育 > 研究生课件

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