第七章 结构体_第1页
第七章 结构体_第2页
第七章 结构体_第3页
第七章 结构体_第4页
第七章 结构体_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、20082008东北大学计算机基础教研室东北大学计算机基础教研室 1 1 第八章 结构体8.1 概述8.2 定义结构体变量的方法8.3 结构体变量的初始化8.4 结构体变量的引用8.5 结构体数组8.6 指向结构体数据的指针8.7 用指针处理链表20082008东北大学计算机基础教研室东北大学计算机基础教研室 2 2 8.1 概述 在实际问题中我们常需要把不同类型的几个数据组合起来在实际问题中我们常需要把不同类型的几个数据组合起来, 构成构成一个整体。如一个公司职员的个人信息一个整体。如一个公司职员的个人信息, 或学校中教师和学生的信息。或学校中教师和学生的信息。以学生信息为例以学生信息为例,

2、 它可能包括学生的学号、班级、姓名、性别、年龄、它可能包括学生的学号、班级、姓名、性别、年龄、成绩等。这时原有的那些数据类型就显的有点无能为力了,所以引入成绩等。这时原有的那些数据类型就显的有点无能为力了,所以引入一种新的数据类型一种新的数据类型- 结构体。结构体。结构体是由一些逻辑相关结构体是由一些逻辑相关, 但数据类型不同的分量组成的一组数据。但数据类型不同的分量组成的一组数据。注意注意: 用户需要先定义用户需要先定义结构体类型结构体类型, 之后才能之后才能定义结构体变量定义结构体变量注意不要忘了分号注意不要忘了分号成员列表成员列表结构体类型定义形式结构体类型定义形式: struct 结构

3、体类型名结构体类型名 数据类型数据类型 成员名成员名1; 数据类型数据类型 成员名成员名2; : : 数据类型数据类型 成员名成员名n; ;关键字关键字用户定义用户定义的标识符的标识符20082008东北大学计算机基础教研室东北大学计算机基础教研室 3 3 8.2 定义结构体变量的方法一、一、 定义结构体变量定义结构体变量1. 先定义结构体类型先定义结构体类型, 再定义变量再定义变量 struct student char name10 ; int age ; float s1 , s2 ; ; struct student st1 , st2 ;st1st2nameages1s2nameag

4、es1s2结构体变量结构体变量st1和和st2各自都各自都需要需要20个字节的存储空间个字节的存储空间20082008东北大学计算机基础教研室东北大学计算机基础教研室 4 4 2. 定义结构体类型同时定义变量定义结构体类型同时定义变量 struct student char name10 ; int age ; float s1 , s2 ; st1 , st2 ;3. 直接定义结构体变量直接定义结构体变量 struct char name10 ; int age ; float s1 , s2 ; st1 , st2 ;4. 说明说明: (1) 结构体变量具有结构体类型的一切特征结构体变量具

5、有结构体类型的一切特征 在内存中结构体变量占有一片连续的存储单元在内存中结构体变量占有一片连续的存储单元 存储单元的字节数可用存储单元的字节数可用sizeof 运算符运算符算出算出 printf(“%dn” , sizeof(struct student) ) ; printf(“%dn” , sizeof(st1) ) ; 20082008东北大学计算机基础教研室东北大学计算机基础教研室 5 5 (2) 结构体类型可以嵌套定义结构体类型可以嵌套定义 例例: struct date int year ; int month ; int day ; ; struct stud char name

6、10 ; struct date birthday ; float s1 , s2 ; ; 或或 : struct stud char name10 ; struct date int year ; int month ; int day ; birthday ; float s1 , s2 ; ;20082008东北大学计算机基础教研室东北大学计算机基础教研室 6 6 8.3 结构体变量的初始化struct student char name10 ; int age ; float score1 , score2 ; st1=“ Mary”, 21, 78, 86 ;struct stud

7、char name10 ; struct date birthday ; float score1 , score2 ; ;struct stud st2= “John” , 1980 , 11 , 23 , 89 , 95 ;struct student char name10 ; int age ; float score1 , score2 ; ;struct student st3; st3=“ Mary”, 21, 78, 86 ;正确初始化正确初始化错误错误, C不允许不允许这样赋值这样赋值正确初始化正确初始化20082008东北大学计算机基础教研室东北大学计算机基础教研室 7 7

8、 8.4 结构体变量的引用1. 引用结构体变量中的成员引用结构体变量中的成员 格式格式: 结构体变量名结构体变量名. 成员名成员名struct student char name10 ; int age ; float s1 , s2 ; ;注意注意: 一般是对结构体变量的各个成员分别进行赋值一般是对结构体变量的各个成员分别进行赋值st1 = “Mary”, 21 , 78 , 86 ; 这样的赋值是不允许的这样的赋值是不允许的struct student st1 ;strcpy(st1. name, “Mary”) ; st1. age = 21 ;st1. s1 = 78 ; st1. s

9、2 = 86 ; struct date int year ; int month ; int day ; ;struct stud char name10 ; int age ; struct date birthday; float s1 , s2 ; ;struct stud st2 ;int age , year ;strcpy(st2. name,“John”) ; st2. age = 20 ; st2. birthday. year = 1980 ;st2. birthday. month = 11 ;st2. birthday. day = 23 ;st2. s1 = 89 ;

10、 st2. s2 = 95 ;age = 24 ; year = 2000 ;可以定义与结构体变量可以定义与结构体变量成员名相同名字的变量成员名相同名字的变量 它们之间不会发生混乱它们之间不会发生混乱20082008东北大学计算机基础教研室东北大学计算机基础教研室 9 9 2. 相同类型的结构体变量可以进行相同类型的结构体变量可以进行整体赋值整体赋值 struct date int year ; int month ; int day ; ;struct stud char name10 ; int age ; struct date birthday; float s1 , s2 ; ;st

11、ruct stud st1, st2, st3;strcpy(st1. name, “John”) ; st1. age = 20 ; st1. birthday.year = 1980 ;st1. birthday.month = 11 ;st1. birthday.day = 23 ;st1. s1 = 89 ; st1. s2 = 95 ;st2=st1;strcpy(st3. name,“Mary”);st3. age=20;st3. birthday=st1. birthday;st3. s1 = 76;st3. s2 = 85;注意要正确赋值的条件注意要正确赋值的条件是变量是变量s

12、t1已经有了初值已经有了初值20082008东北大学计算机基础教研室东北大学计算机基础教研室 1010 3. 结构体变量的输入结构体变量的输入 输出输出 C语言不允许结构体变量整体进行输入和输出语言不允许结构体变量整体进行输入和输出, 只能对结构体变量的只能对结构体变量的成员成员进行输入和输出进行输入和输出gets( st1. name ) ;scanf( “%d%d%d”, &st1. birthday. year , &st1. birthday. month , &st1. birthday. day ) ;scanf ( “%d%f%f”, &st1.

13、age , &st1. s1 , &st1. s2 ) ; puts( st1. name ) ;printf( “%4d”, st1. age );printf( “%d .%d .%d”, st1. birthday. year , st1. birthday. month , st1. birthday. day ) ;printf(“%5.2f %5.2fn”, st1. s1 , st1. s2 ) ; 20082008东北大学计算机基础教研室东北大学计算机基础教研室 1111 8.5 结构体数组 一、一、 结构体数组的定义结构体数组的定义 1. 先定义结构体类型先定

14、义结构体类型 再定义结构体数组再定义结构体数组 struct student char name10 ; int age ; float s1 , s2 ; ; struct student st6 ;2. 定义结构体类型的同时定义数组定义结构体类型的同时定义数组 struct student char name10 ; int age ; float s1 , s2 ; st6 ; 3. 直接定义结构体数组直接定义结构体数组 struct char name10 ; int age ; float s1 , s2 ; st6 ;20082008东北大学计算机基础教研室东北大学计算机基础教研室

15、 1212 二、结构体数组的初始化二、结构体数组的初始化 将每个数组元素的数据用花括号将每个数组元素的数据用花括号 括起来括起来struct student char name10 ; int age ; float s1 , s2 ; ;struct student st3= “Mary”, 21, 78, 86, “Alex”, 20, 90, 80 , “Mike”,19, 75, 68 ;Mary217886Alex209080Mike197568st0st1st22. 数组元素之间可以整体赋值数组元素之间可以整体赋值 也可以将一个元素赋给一个相同类型的结构体变量也可以将一个元素赋给一

16、个相同类型的结构体变量 struct student x , st3= “Mary”,21,78,86, “Alex”, ; st2 = st0 ; x = st1 ; 3. 只能对数组元素的只能对数组元素的成员成员进行输入和输出进行输入和输出gets( st2. name ) ;scanf(“%d” , &st2. age ) ;scanf(“%f%f ”, &st2. s1 , &st2. s2 );puts( st0. name );printf(“%4d%5.2f %5.2fn”, st0. age , st0. s1 , st0. s2) ;都是结构体变量的整

17、体赋值都是结构体变量的整体赋值三、三、 结构体数组的引用结构体数组的引用1. 引用某个数组元素的成员引用某个数组元素的成员 例例: puts( st0. name ) ; printf(“%d, %d”, st1. age , st1. s1 ) ;例例: 有有30名学生名学生, 输入每个学生信息包括学号、姓名、成绩,输入每个学生信息包括学号、姓名、成绩, 要求找出成绩最高者,并输出他的信息要求找出成绩最高者,并输出他的信息#include #define N 30void main( ) struct student int n ; char name10 ; int score ; ; s

18、truct student stN; int i , m ; int max ; for ( i=0 ; iN ; i+) scanf(“%d%s%d”, &sti.n , , &sti.score) ; max=st0.score;for( i=1 ; i max ) max=sti.score; m=i; printf(“%4d”, stm.n ) ; printf(“%10s ”, ); printf(“%5d ”, stm.score);例例: 按成绩对学生信息进行从高到底的排序按成绩对学生信息进行从高到底的排序#include #de

19、fine N 30void main( ) struct stud int n ; char name10 ; int s ; ; struct stud aN, temp; int i ,j,k; for ( i=0 ; iN ; i+) scanf(“%d%s%d”, &ai.n, , &ai.s) ; for ( i=0 ; iN-1 ; i+) for ( j=i+1 ; jN ; j+) if ( ai.saj.s ) k=j; temp=ak ; ak=ai ; ai=temp ; for ( i=0 ; i s1 = 87 ;p - s2 = 90

20、;(2) (*指针变量名指针变量名) . 成员名成员名 (*p) . age(3) 指针变量名指针变量名 - 成员名成员名 p - s1up只能指向一个结构体变量,如:只能指向一个结构体变量,如:p=&stu;而不能指向结;而不能指向结构体变量的一个成员。如:构体变量的一个成员。如:p=&stu.age;是非法的;是非法的。u -运算符的优先级最高。运算符的优先级最高。例如:例如:struct char name20 ; int age ; *p ;则表达式:则表达式: +p-age: 表示表示age的值增加的值增加1。 等价于等价于+(p-age) u使用结构体指针变量应注意

21、以下几点:使用结构体指针变量应注意以下几点:u p不是结构体变量不是结构体变量(是指向结构体变量的指针是指向结构体变量的指针),因此,因此不能写成不能写成成员引用方式成员引用方式p.age的形式的形式。二、二、 指向结构体数组的指针指向结构体数组的指针1. 定义定义 struct student st3 , *p ;2. 使用使用 for ( p=st ; pname ) ; scanf( “%d%d %d ”,&p-age,&p-s1,&p-s2) ; 对于指向结构体数组的指针:对于指向结构体数组的指针:pp只能指向只能指向一个结构体一个结构体数组的一个元素数组的一个

22、元素(相当于变量),然(相当于变量),然后后用用-指向运算符指向运算符取其成员的值取其成员的值,而不能直接指向一个数组,而不能直接指向一个数组元素的成员。元素的成员。p(+p)-age:p表示表示p指针指向下一个数组元素后,再访问其成员指针指向下一个数组元素后,再访问其成员age。p(p+)-age:p先访问先访问age操作,再对指针操作,再对指针p加加1,使其指向下一个数组,使其指向下一个数组元素。元素。结构体变量作为函数参数结构体变量作为函数参数1. 函数的实参和形参都用结构体变量函数的实参和形参都用结构体变量 , 参数之间为参数之间为值传递值传递即即:实参实参 结构体变量结构体变量各成员

23、的值依次传给各成员的值依次传给形参结构体变量形参结构体变量2. 返回结构体类型值的函数返回结构体类型值的函数 函数定义格式函数定义格式 : 结构体类型名结构体类型名 函数名函数名 ( 形参表列形参表列) 函数体函数体 ; 例例 : struct student funct ( int x , float y ) 函数体函数体 ; 注意注意 结构体类型是已经定义好的结构体类型是已经定义好的20082008东北大学计算机基础教研室东北大学计算机基础教研室 2020 三、结构体与函数三、结构体与函数 注意注意 结构变量作为参数传递时,其实参与形参的结构类型必结构变量作为参数传递时,其实参与形参的结构

24、类型必须一致,传递时其实参只需指定其结构变量名即可。当实参须一致,传递时其实参只需指定其结构变量名即可。当实参为数组时,其形参可以定义为同类型结构的结构数组或结构为数组时,其形参可以定义为同类型结构的结构数组或结构指针。指针。与普通变量一样,结构变量在函数内部定义时为局部的,其值与普通变量一样,结构变量在函数内部定义时为局部的,其值只在本函数范围内有效,不会影响其它函数只在本函数范围内有效,不会影响其它函数 将结构传递给函数的方式有三种将结构传递给函数的方式有三种p传递单个成员传递单个成员p传递整个结构传递整个结构p传递指向结构的指针传递指向结构的指针传递结构变量的地址可以实现结构的传址调用。

25、传递结构变量的地址可以实现结构的传址调用。结构数组也可作为函数参数传递。结构数组也可作为函数参数传递。在调用在调用print时,时, &stud做实参,将做实参,将stud的地址的地址传递给函数的传递给函数的形参形参p,这时这时p指向了结构变量指向了结构变量 stud的成员值。的成员值。#include #define FORMAT “%dn%sn%6.2fn” struct student int num; char name20; float score; ; main() void print (); struct student stud; stud.num=1001; str

26、cpy(,”michell”); stud.score=90.9; print(&stud); void print(struct student *p) printf(FORMAT,p-num,p-name,p-score); printf(“n”); 例例: 求学生成绩的总分和平均分求学生成绩的总分和平均分 #include #define N 5struct stud char name10 ; int s3 ; float sum , ave ; ; struct stud comp (struct stud x) int j ; x.sum = 0 ; fo

27、r ( j = 0; j3 ; j+ ) x.sum = x.sum + x.sj ; x.ave = x.sum / 3 ; return(x); void main ( ) struct stud aN ; int j ; for ( j=0; jN; j+ ) scanf(“%s%d%d%d ”, , &aj.s0, &aj.s1 , &aj.s2 ); for ( j=0; jN; j+) aj=comp ( aj ) ; for ( j=0; jN; j+) printf(“%10s%4d”, , aj.s0 ); printf(“

28、%4d%4d”, aj.s1, aj.s2 ); printf(“%8.2f %6.2fn”, aj.sum , aj.ave ); 例例: 按成绩对学生信息进行从高到底的排序按成绩对学生信息进行从高到底的排序#include #define N 30struct stud int n ; char name10 ; int s ; ;void input(struct stud a ) int i ; for ( i=0 ; iN ; i+) scanf(“%d%s%d”, &ai.n, , &ai.s) ; void output(struct stud a

29、) int i ; for ( i=0 ; iN ; i+) printf(“%4d%10s%4d”, ai.n, , ai.s) ; void sort(struct stud a ) int i , j ,k; struct stud temp; for ( i=0 ; iN-1 ; i+) k=i; for ( j=i+1 ; jN ; j+) if ( ai.saj.s ) k=j; if(k!=i)temp=ak ; ak=ai ; ai=temp ; void main( ) struct stud stN; input(st); sort(st); output(s

30、t); 20082008东北大学计算机基础教研室东北大学计算机基础教研室 2424 8.7 利用结构体组织链表一、基本概念一、基本概念1. 动态存储分配动态存储分配: 根据需要临时分配内存单元用以存放数据根据需要临时分配内存单元用以存放数据, 当数据不用时可以随时释放内存单元当数据不用时可以随时释放内存单元2. 链表链表: 是可以动态地进行存储分配的一种数据结构是可以动态地进行存储分配的一种数据结构 它是由一组动态数据链接而成的序列它是由一组动态数据链接而成的序列3. 结点结点: 链表中的每一个动态数据称为一个结点链表中的每一个动态数据称为一个结点4. 结点类型结点类型: 是一个包含指针项的结

31、构体类型是一个包含指针项的结构体类型 一般由两部分组成一般由两部分组成:(1) 数据成员数据成员: 存放数据存放数据(2) 指针成员指针成员: 存放下一个结点的地址存放下一个结点的地址struct sd int num; int score; struct sd *next ; ; 数据成员数据成员指针成员指针成员20082008东北大学计算机基础教研室东北大学计算机基础教研室 2525 头指针头指针表头结点表头结点表尾结点表尾结点2010head 2010 1428 15709514281861570282NULL3NULL为空地址为空地址, 表示链表到此结束表示链表到此结束二、简单链表二、

32、简单链表#include struct sd int num; int score; struct sd *next ; ; void main( ) struct sd a,b,c,*head,*p; head=&a; a.num=1; a.score=95; a.next=&b; b.num=2; b.score=86; b.next=&c; c.num=3; c.score=82; c.next=NULL; p=head; while(p!=NULL) printf(“%3d%4dn”,p-num,p-score); p=p-next; head201014281

33、5702010abc19514282861570382NULLp201014281570NULL说明说明: 该程序虽然建立了一个链表该程序虽然建立了一个链表, 但这个链表是静态的但这个链表是静态的, 因为它因为它的结点个数是固定的的结点个数是固定的, 不能按需要增加新的结点不能按需要增加新的结点,也不能按需要删也不能按需要删除结点除结点. 这样的链表并不实用这样的链表并不实用, 我们需要的是我们需要的是“动态链表动态链表”三、三、 处理动态链表所需的函数处理动态链表所需的函数 ( 需用头文件需用头文件 )1. malloc 函数函数 原型原型 : void *malloc( unsigned

34、int size ) 作用作用 : 在内存中开辟一个长度为在内存中开辟一个长度为 size 的连续存储空间的连续存储空间 , 并将此存储并将此存储 空间的起始地址带回空间的起始地址带回注意注意 : (1) 函数返回值是指针函数返回值是指针, 但该指针是指向但该指针是指向void类型的类型的 , 因此在因此在 使用时希望这个指针指向其他类型需要用强制类型转换使用时希望这个指针指向其他类型需要用强制类型转换(2) 如果内存缺少足够大的空间进行分配如果内存缺少足够大的空间进行分配 , 则则 malloc 函数函数 返回值为返回值为“空指针空指针” (即即NULL)例例: struct sd *p;

35、p = (struct sd * ) malloc ( sizeof(struct sd) ) ;强制类型转换强制类型转换结构体类型占用的字节长度结构体类型占用的字节长度2. free函数函数 原型原型 : void free( void *ptr ) 作用作用 : 将指针变量将指针变量ptr指向的存储空间释放指向的存储空间释放 注意注意: (1) ptr的值不是任意的地址的值不是任意的地址, 必须是程序中执行必须是程序中执行malloc或或 calloc函数所返回的地址函数所返回的地址(2) 模型中模型中ptr是是void型型, 但调用但调用free函数时函数时, 参数可能是参数可能是 其他

36、类型其他类型, 计算机系统会自动进行转换计算机系统会自动进行转换 例例: struct sd *p; p=(struct sd *) malloc (sizeof(struct sd) ; free(p);p42004200 四、四、 链表应用举例链表应用举例 1. 建立链表建立链表(表尾添加法表尾添加法) #include #include #define ST struct student ST int num ; int score ; ST *next ; ; #define LEN sizeof(ST) int n ; 宏定义宏定义ST , 以后书写简单以后书写简单求出结构体类型占用

37、的字节数求出结构体类型占用的字节数全局量全局量 , n 表示结点的个数表示结点的个数ST * creat(void) ST *head , *p1 , *p2 ; n=0 ; head=NULL ; p1=(ST *) malloc ( LEN ) ; scanf( “%d %d ”, &p1-num, &p1-score ) ; while ( p1-num!=0 ) n=n+1; if (n= =1) head=p1 ; else p2-next=p1 ; p2 = p1 ; p1 = (ST *) malloc (LEN) ; scanf( “%d %d ”, &

38、p1-num, &p1-score ) ; p2-next = NULL ; return( head ) ; headhead201020101428142815701570NULLp1p2326432642010201010951428n0 1 2 320101428208630820014281570NULL1570157032642. 输出链表输出链表void list ( ST *head ) ST *p ; p = head ; while ( p!=NULL ) printf(“%3d %4dn”, p-num, p-score ) ; p = p-next ; headhead2010201014281428157015702010201010951428208615703082NULLp201014281570NULLp120101428num20p22010headhead201020101428142815701570201020101095142828615703082NULL1570n3 23. 链表的删除链表的删除ST *del ( ST *head , int num ) ST *p1 , *p2 ; p1 = h

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论