还剩6页未读,继续阅读
文本内容:
第十章结构体与共用体第十章结构体与共用体概述有时需要将不同类型的数据组合成一个有机的整体,如一个学生的基本情况学§
10.1号(),姓名(),性别(),年龄(),成绩(),地址()intnum charname
[20]charsex intage语言提供了这样一种数据结构,称为结构体结构体定义的一般形式结floatscore charaddr
[30]构体名成员表列;或称域表如一个学生的基本情况可定义如下c struct字节字节字节字节字{}“”structstudent节字节{intnum;2charname
[20];20charsex;1intage;2floatscore;4字节charaddr
[30];30};定义结构体类型变量的方法59三种方法§
10.2
一、先定义结构体类型,再定义变量structstudent,{intnum;charname
[20];charsex;intage;floatscore;charaddr
[30];};注意是一个整体来定义结构体变量的structstudentstu1stu2;
二、在定义类型的同时定义变量structstudent,structstudent
三、直接定义结构体类型变量{intnum;charname
[20];charsex;intage;floatscore;charaddr
[30];}stu1stu2;,说明struct成员也可以是一个结构体变量如{intnum;charname
[20];charsex;intage;floatscore;charaddr
[30];}stu1stu2;
1.structdate{intmonth;intday;intyear;};structstudent1{intnum;charname
[20];charsex;intage;成员名可以与程序中的变量名相同structdatebirthday;charaddr
[30];}stu3;birthdaynumnamesexagemonthdayyear结构体类型变量的引用
2.对结构体变量的引用,一般是分别引用其成员,引用方式为结构体变量名成员addr§
10.3名(由此可与函数中同名的变量区分)如,.其中为成员运算符,它在所有的运算符中优先级最高若成员的类型又是一个结stu
1.num stu
1.age构体,则要用多个成员运算符(只能对最低级的成员进行赋值“.”或存取及运算)成员变量与一般的变量是一样的如操作stu
3.birthday.year(,)(,)赋值操作i/oscanf“%d”stu
1.num;printf“name=%s\\n”stu
1.name;在有些系统中允许将一个结构体变量直接赋给另一个具有相同结构体类型的变量,stu
2.age=25;stu
3.age=stu
2.age;stu
1.age++;stu
3.birthday.day++;如(也可以)可以引用成员变量的地址,也可以引用结构体变量的地址如(,stu1=stu2turboc)(,)scanf“%d”结构体变量的初始化stu
3.birthday.year;printf“%x”stu1;把各成员的值放在大括号内,用逗号分隔如§
10.4structstudent{longnum;charname
[20];charsex;,,,charaddr
[30];结构体数组}a={99031”lilin”’m’”123beijingroad”};
一、结构体数组的定义§
10.5也有三种方式
1.structstudent{intnum;charname
[20];charsex;intage;charaddr
[30];};structstudentstu
[3];
2.structstudent{intnum;charname
[20];charsex;intage;charaddr
[30];}stu
[3];
3.struct{intnum;charname
[20];charsex;intage;数组各元素在内存中连续存放charaddr
[30];}stu
[3];
二、结构体数组的初始化stu
[0]stu
[1]stu
[2]structstudent{longnum;charname
[20];charsex;intage;,,,,,charaddr
[30];,,,,,,,,}stu
[3]={{99031”lilin”’m’18”123beijingroad”},{99032”zhangsan”’m’20”130shanghairoad”}{99033”lisi”’f’在定义数组时,若对所有元素都进行了初始化,也可以不指定元素的个数19”1010zhongshanroad”}};,,
三、结构体数组元素的引用structstudentstu[]={{}{}{}};如例对候选人得票的统计程序设有个候选人,每次输入一个得票的候选人的stu
[0].numstu
[1].namestu
[2].age名字,要求最后输出各人得票结果3,,,,,#include“string.h”structperson{charname
[20];intcount;,}leader
[3]={“li”0”zhang”0”wang”0};(为指向结构体成员运算符main{inti j;
二、指向结构体数组的指针charleader_name
[20];for i=1;istructstudent{longnum;charname
[20];charsex;intage;,,,,,charaddr
[30];,,,,,,,,}stu
[3]={{99031”lilin”’m’18”123beijingroad”},{99032”zhangsan”’m’20”130shanghairoad”}{99033”lisi”’f’19”1010zhongshanroad”}};main()(,,,{structstudent*p;,)printf“nonamesexageaddr\\n”;for p=stu;pnum p-name p-sex p-age p-addr;注意若指向的第一个元素(即),则相当于}相当于p stu p=stup-age++()先得到值为,而后即指向stu
[0].age++++p-age++stu
[0].age()先即指向,再取值为p++-age p-age18p++p stu
[1]
三、用指向结构体的指针作函数参数++p-age p++p stu
[1]p-age20例有一个结构体变量,内含学生学号,姓名和门课程的成绩要求在中赋值,在函数中将它们打印输出stu3main print#include“string.h”#defineformat“%d\\n%s\\n%f\\n%f\\n%f\\n”structstudent{intnum;()charname
[20];floatscore
[3];};main{voidprint structstudent*p;structstudentstu;stu.num=1234;(,)s(trcpy)stu.name”lili”;stu.score
[0]=
67.5;stu.score
[1]=89;stu.score
[2]=
78.6;print()stu;}(,,,,,)voidprint structstudent*p也可以用结构体变量的成员作为参数{printf formatp-num p-name p-score
[0]p-score
[1]p-score
[2];}(,,,,)另外,允许用结构体变量作为参数,但必须保证实参与形参的类型相同print stu.num stu.name stu.score
[0]stu.score
[1]stu.score
[2];()ansic但这两种方法都必须把成员一个个传递,费时费空间一般采用指针作参数print stu;较好,能提高运行效率用指针处理链表
一、链表概述§
10.7链表是一种常见的重要的数据结构,它是动态地进行存储分配的一种结构(数组是静态的存储结构)下面介绍最简单的一种链表(单向链表)的结构链表由结点构成,结点包括两部分的内容一部分为用户的信息(数据),通常包括各种类型的数据另一head12491249a13561356b14751475c10211021dnull“”部分为指向下一个结点的指针为了表示链表的起始位置(起始结点),有一个指针指向第一个结点,存放这个指针的变量称为头指针变量(一般变量名为)结点一般采用结构体类型“”headstructstudent1{intnum;floatscore;
二、结点的插入操作structstudent1*next;}要将结点插入在结点之后,可用如下操作head pss p
三、结点的删除操作s-next=p-next;p-next=s;要将结点的后一个结点删除,可用如下操作p()()s=p-next;
四、处理动态链表所需的函数p-next=p-next-next;p-next=s-next;free s;head p这些函数所包含的文件标准包含在中;而多数系统包含在中;包含在中ansi“stdlib.h”c函数“malloc.h”turboc“alloc.h”函数原型()
1.malloc作用在内存中分配一个长度为字节的连续空间void*malloc unsignedintsize返回指向分配域的起始地址指针,若不成功则返回空指针()如size()(())null int*p;p=分配一个结点int*malloc sizeofint;,structstudent1{intnum;floatscore;structstudent1*next;}stu*p;或()()(())函数sizeof stup=structstudent1*malloc sizeof函数原型(,)作用在内存中分配个长度structstudent1;
2.calloc为字节的连续空间void*calloc unsignednunsignedsize n返回指向分配域的起始地址指针,若不成功则返回空指针()size函数null函数原型()
3.free作用释放由指向的内存空间,无返回值voidfree void*p共用体p
一、共用体的概念§
10.8几个不同类型的变量存放在同一段内存单元中(它们的起始地址是一样的)共用体定义的一般形式共用体名成员表列变量表列;如union{}uniondata,,或{inti;charch;floatf;chif}a bc;,,或uniondata{inti;charch;floatf;},,uniondataa bc;共用体变量占用内存的长度等于最长成员的长度而结构体变量占用内存长度为各union{inti;charch;floatf;}a bc;成员长度之和
二、共用体变量的引用方式不能直接引用共用体变量名,而只能引用共用体变量中的成员如
三、共用体类型数据的特点a.ia.cha.f在使用共用体类型数据时要注意以下一些特点共用体变量中的成员不能同时都起作用,在某一时刻只能一个成员起作用(有意义),其他成员则是无意义的起作用的成员是最后一次存入数据的成员如
1.main(,,,){uniondata{inti;charch;}a;a.ch=’a’;printf“\\n%d%d\\n”a.ch a.i;(,,,)a.i=266;共用体变量的地址与它的各成员的地址是一样的即printf“\\n%d%d\\n”a.ch a.i;}不能直接引用共用体变量名,也不能对它进行初始化
2.a=a.i=a.ch不能把共用体变量作为函数参数,也不能使函数返回一共用体类型数据但可以
3.使用指向共用体变量的指针作为函数参数
4.结构体类型的成员可以是共用体类型的,共用体的成员也可以是结构体的和数组也可以定义共用体数组
5.如何知道应该使用共用体变量中的哪一个成员呢一般使用一个变量用来标记应使用哪个成员如struct{union{inti;charch;floatf;}da;inttype;}a;()a.da.f=
1.5;a.type=3;(,)(,switch a.type)(,){case1printf“%d\\n”a.da.i;break;case2printf“%c\\n”枚举类型a.da.ch;break;case3printf“%f\\n”a.da.f;break;}枚举类型是新标准所增加的,枚举的含义为可以一一列举出来的§
10.9枚举类型的定义ansic“”,,,,,,枚举变量的定义,,,,,,,enumweekday{sun montue wedthu frisat};或enumweekday{sun montue wedthu frisat};enumweekdayday1day2;,,,,,,,或,,,,,,,说明enumweekday{sun montue wedthu frisat}day1day2;在定义枚举类型时内的标识符(枚举常量)不能相同,如,,,enum{sun montue wedthu frisat}day1day2;,,错误这些标识符在程序中也不能作为其它用处如,,
1.{}enumch{a bc,a ip};enumch{a bc d};枚举元素按常量处理(称为枚举常量),它们不是变量,不能对它们赋值main{inta;charc;枚举元素是有值的,编译按定义时的顺序使它们的值为,,,
2.
3.c012称为枚举元素或枚举常量如,,,,,,()main({enumweekday{sun montue wedthu frisat}day;printf“\\n”;for day=sun;day{intmonth;intday;intyear;}date;,(相当于,),typedeffloatnum
[10];typedefchar*string;integeri j;inti j;datebirthday*p;(相当于(相当于))numx;stringstr;floatx
[10];char*str;。