《结构体和共用体(正式).ppt》由会员分享,可在线阅读,更多相关《结构体和共用体(正式).ppt(41页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第6 6章章 结构体与公用体结构体与公用体 6.1 6.1 结构体概述结构体概述6.1.1 6.1.1 结构体的引入结构体的引入 为了方便处理多个数据项的数据,常常把这些关系密切但类型不同的数据项组织在一起,即“封装”起来,并为其取一个名字,在C语言中,就称其为结构体(有些高级语言称之为记录)。所以,结构体通常是由不同数据类型的数据项组成,一般也称是由不同成员组成,因此可以说:一个结构体可包含若干成员,每一个成员可具有不同的名字及数据类型。结构体的引入为处理复杂的数据结构提供了有力的手段,也为函数间传递一组不同数据类型的数据提供了方便,特别是对于数据结构较为复杂的大型程序提供了方便。16.1
2、.2 6.1.2 结构体类型的定义结构体类型的定义 结构体类型结构体类型和简单类型不同,简单类型是由系统预定和简单类型不同,简单类型是由系统预定义的,如义的,如intint、floatfloat、charchar,直接可以使用。而结构体类型直接可以使用。而结构体类型是根据需要由程序员自行定义,因此在使用之前必须先定义是根据需要由程序员自行定义,因此在使用之前必须先定义结构体类型。结构体类型。结构体类型定义struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;合法标识符可省:无名结构体成员类型可以是基本型或构造型struct是关键字,不能省略2例 struct student in
3、t num;char name20;char sex;int age;float score;char addr30;namenumsexagescoreaddr2字节2字节20字节1字节4字节30字节.结构体类型定义描述结构的组织形式,不分配内存3说明说明(1)(1)定义一个结构体类型只是描述了此结构体的组织形定义一个结构体类型只是描述了此结构体的组织形式,在编译时并不为其分配存储空间,即仅描述此数据结式,在编译时并不为其分配存储空间,即仅描述此数据结构的形态或者说模型,故不能对定义的一个结构体类型进构的形态或者说模型,故不能对定义的一个结构体类型进行赋值、存取或运算。行赋值、存取或运算。(
4、2)(2)结构体的成员可以是简单变量、数组、指针、结构体结构体的成员可以是简单变量、数组、指针、结构体或公用体等。或公用体等。(3)(3)结结构构体体类类型型定定义义可可以以放放在在函函数数内内部部,也也可可以以放放在在函函数数外外部部。若若放放在在内内部部,则则只只在在函函数数内内有有效效;若若放放在在外外部部,则则从定义点到源文件尾之间的所有函数都有效。从定义点到源文件尾之间的所有函数都有效。(4)(4)结结构构体体成成员员的的名名字字可可以以同同程程序序中中的的其其它它变变量量同同名名,二二者不会相混,系统会自动识别它。者不会相混,系统会自动识别它。46.2 6.2 结构体变量结构体变量
5、6.2.1 6.2.1 结构体变量的定义与初始化结构体变量的定义与初始化1结构体变量的定义 同其它变量一样,结构体变量也必须先定义,然后才能引用。一个结构体变量的定义可以有以下三种方式:(1)先定义类型再定义变量其形式:struct stud_typechar name10;long num;char sex;int age;float score;char address10;struct stud_type student1,student2;5(2)(2)在定义类型的同时定义变量在定义类型的同时定义变量其形式其形式:struct stud_typestruct stud_type stu
6、dent1,student2;student1,student2;(3)(3)直接定义结构体变量直接定义结构体变量其形式其形式:structstruct student1,student2;student1,student2;6说明说明(1)(1)在定义结构体类型时,系统并不分配内存空间,仅当定在定义结构体类型时,系统并不分配内存空间,仅当定义结构体变量时,系统才为被定义的每一变量分配相应的存义结构体变量时,系统才为被定义的每一变量分配相应的存储单元。如上面定义的结构体变量储单元。如上面定义的结构体变量student1student1、student2student2在内在内存中各占存中各占3
7、131个字节(个字节(10+4+1+2+4+10=3110+4+1+2+4+10=31)(2)(2)结构体变量的定义一定要在结构体类型定义之后或同时结构体变量的定义一定要在结构体类型定义之后或同时进行,对尚未定义的结构体类型,不能用它来定义结构体变进行,对尚未定义的结构体类型,不能用它来定义结构体变量。量。例如:例如:对一个教师对一个教师teacherteacher的结构体类型未作定义,则下面的的结构体类型未作定义,则下面的变量定义变量定义 struct teacher struct teacher teah1teah1 是错误的;反之亦然;是错误的;反之亦然;对某变量对某变量birthday
8、birthday (也称结构体成员变量),若其类型未作也称结构体成员变量),若其类型未作定义,就写定义,就写struct date_type birthday;struct date_type birthday;也是错误的。也是错误的。72.2.结构体变量的初始化结构体变量的初始化 所谓所谓结构体变量初始化结构体变量初始化,就是在定义结构体变量的同时,就是在定义结构体变量的同时,对其成员变量赋初值,对其成员变量赋初值,在赋值时应注意按顺序及类型依次为在赋值时应注意按顺序及类型依次为每个结构体成员指定初始值。每个结构体成员指定初始值。结构体初始化的一般结构体初始化的一般格式格式为:为:struc
9、t struct 结构体类型名结构体类型名 结构体变量结构体变量=初始化值初始化值;说明说明(1)(1)初始化数据之间用逗号分隔。初始化数据之间用逗号分隔。(2)(2)初始化数据的个数一般与成员的个数相同,若小于成员初始化数据的个数一般与成员的个数相同,若小于成员数,则剩余的成员将被自动初始化为数,则剩余的成员将被自动初始化为0 0(若成员是指针,则(若成员是指针,则初始化为初始化为NULLNULL)。)。(3)(3)初始化数据的类型要与相应成员变量的类型一致。初始化数据的类型要与相应成员变量的类型一致。初始化时只能对整个结构体变量进行,不能对结构体类型中初始化时只能对整个结构体变量进行,不能
10、对结构体类型中的某个成员进行初始化赋值。的某个成员进行初始化赋值。8例:例:struct date_type struct date_type int year;int year;int mouth;int mouth;int day;int day;;struct stud_typestruct stud_typechar name10;char name10;long num;long num;char sex;char sex;struct date_type birthday;struct date_type birthday;float score;float score;char
11、address10;char address10;main()main()struct stud_type struct stud_type student1=wang,196103,m,1978,10,12,98,Xian;student1=wang,196103,m,1978,10,12,98,Xian;struct stud_type struct stud_type studentstudent2 2=liu,196105,m,1980,9,22,88,Benjing;=liu,196105,m,1980,9,22,88,Benjing;96.2.2 6.2.2 结构体变量的引用结构体
12、变量的引用1.1.对结构体变量成员的引用对结构体变量成员的引用 在在C C语言程序中,语言程序中,不准许对结构变量不准许对结构变量整体整体进行各种运算、赋值进行各种运算、赋值或输入输出操作,而只能是对其成员进行此类操作。或输入输出操作,而只能是对其成员进行此类操作。引用结构体变量成员的一般引用结构体变量成员的一般形式形式:结构体变量名结构体变量名.成员名成员名其中其中.是结构体成员运算符,其优先级别最高,结合性是自左至是结构体成员运算符,其优先级别最高,结合性是自左至右。由此对结构体成员就完全可以像操作简单变量一样操作它。右。由此对结构体成员就完全可以像操作简单变量一样操作它。如:如:对上例定
13、义的结构体变量对上例定义的结构体变量student1student1或或student2student2,可作如下的赋可作如下的赋值操作:值操作:student1.name10=wang;student1.name10=wang;student1.num=196103;student1.num=196103;student1.sex=m;student1.sex=m;student1.birthday.year=1978;student1.birthday.year=1978;student1.birthday.mouth=10;student1.birthday.mouth=10;stude
14、nt1.birthday.day=12;student1.birthday.day=12;student1.score=98;student1.score=98;102.2.对结构体变量整体的引用对结构体变量整体的引用 结构体变量和简单变量相比,除了上面所述在参加各种结构体变量和简单变量相比,除了上面所述在参加各种运算、赋值或输入输出方式上有所不同外运算、赋值或输入输出方式上有所不同外即是由结构体即是由结构体变量成员完成,其它同简单变量一样,如:变量成员完成,其它同简单变量一样,如:(1)(1)可以相互赋值,但注意相互赋值的两个结构体变量必须可以相互赋值,但注意相互赋值的两个结构体变量必须是同
15、一个结构体类型;是同一个结构体类型;如:如:student1=student2;student1=student2;(2)(2)可作为函数的形参、实参或函数返回值,详见下节。可作为函数的形参、实参或函数返回值,详见下节。116.2.3 6.2.3 结构体变量作为函数参数结构体变量作为函数参数1.1.结构体变量成员作函数参数结构体变量成员作函数参数结构体变量中的所有成员都可作为函数参数结构体变量中的所有成员都可作为函数参数struct struct stud_typestud_type char name10;char name10;long num;long num;char sex;char
16、 sex;student1;student1;现将结构体变量现将结构体变量student1student1的三个成员分别传递给函数的三个成员分别传递给函数func1(),func2(),func3()func1(),func2(),func3():func1(student1.name);func1(student1.name);func2(student1.num);func2(student1.num);func1(student1.sex);func1(student1.sex);12若需要将成员地址传递给函数,则只需在其前加取地址符若需要将成员地址传递给函数,则只需在其前加取地址符“&
17、”“&”。如如:func1(student1.name);func2(&student1.num);func1(&student1.sex);其中字符数组名其中字符数组名name代表其成员地址,故不许要写代表其成员地址,故不许要写“&”。2.2.结构体变量整体作函数参数结构体变量整体作函数参数老板本的老板本的C C系统不允许用结构体变量作函数参数,只允许用指向结系统不允许用结构体变量作函数参数,只允许用指向结构体变量的指针作函数参数(第构体变量的指针作函数参数(第7 7章),传递的是结构体变量的首章),传递的是结构体变量的首地址。而地址。而ANSI CANSI C取消了这一限制取消了这一限制,
18、规定按值传递方式规定按值传递方式。在函数调用。在函数调用时,系统为形参结构体变量分配存储空间,并从相应的实参结构体时,系统为形参结构体变量分配存储空间,并从相应的实参结构体变量中取得各成员的值,若对形参中结构体变量各成员值进行修改,变量中取得各成员的值,若对形参中结构体变量各成员值进行修改,并不能修改实参结构体变量各成员的值。这里要注意,实参和形参并不能修改实参结构体变量各成员的值。这里要注意,实参和形参结构体变量类型应当完全一致。结构体变量类型应当完全一致。136.3 6.3 结构体数组结构体数组6.3.1 6.3.1 结构体数组的定义与初始化结构体数组的定义与初始化1.1.结构体数组的定义
19、结构体数组的定义 在定义结构体数组时其定义方法与定义结构体变量方法类似,在定义结构体数组时其定义方法与定义结构体变量方法类似,也有三种形式。也有三种形式。定义如下:定义如下:struct date_type struct date_type int year;int mouth;int day;int year;int mouth;int day;;struct stud_typestruct stud_type char name10;char name10;long num;long num;char sex;char sex;struct date_type birthday;struc
20、t date_type birthday;float score;float score;char address10;char address10;struct stud_type student3;struct stud_type student3;14由此就定义了一个结构体数组由此就定义了一个结构体数组student3student3,它有它有3 3个个元素,每个元素都是元素,每个元素都是struct stud_typestruct stud_type类型,各占类型,各占3535个字节(个字节(10+4+1+(2+2+2)+4+10=3510+4+1+(2+2+2)+4+10=35)。)
21、。152.2.结构体数组的初始化结构体数组的初始化 结构体数组在定义的同时可以初始化。其一般格式结构体数组在定义的同时可以初始化。其一般格式是在定义之后紧跟一个用花括号括起来的一组初始数据,是在定义之后紧跟一个用花括号括起来的一组初始数据,为了增强可读性,最好使每一个数组元素的初始数据也为了增强可读性,最好使每一个数组元素的初始数据也用花括弧括起来,以此来区分各个数组元素。用花括弧括起来,以此来区分各个数组元素。对上所定义的结构体数组对上所定义的结构体数组studentstudent初始化如下:初始化如下:stuct stud_type student2=wang,196103,stuct s
22、tud_type student2=wang,196103,m,1978,10,12,98,xian,m,1978,10,12,98,xian,zhang,196102,f,1977,1,10,87,Beijingzhang,196102,f,1977,1,10,87,Beijing;16说明说明(1)(1)可以将一个结构体数组元素赋值给同一结构体类型数组中另一可以将一个结构体数组元素赋值给同一结构体类型数组中另一个元素,或赋给同一类型的变量。个元素,或赋给同一类型的变量。如如:struct stud_type student3,student1struct stud_type student
23、3,student1;现在就定义了一个结构体数组现在就定义了一个结构体数组studentstudent,又定义了一个结构体变又定义了一个结构体变量量student1student1,则下面的赋值合法。则下面的赋值合法。studentlstudentlstudent0student0;student0=student1;student0=student1;studnet1=student1;studnet1=student1;(2)(2)不能把结构体数组元素作为一个整体直接进行输入或输出。不能把结构体数组元素作为一个整体直接进行输入或输出。如如 printf(%d,student0)printf
24、(%d,student0);或或scanf(%d,&student0)scanf(%d,&student0);只能以单个成员为对象进行输入输出,只能以单个成员为对象进行输入输出,如:如:scanf(%s,student0.name)scanf(%s,student0.name);scanf(%ld,scanf(%ld,student0.num)student0.num);printf(%s%ldn,student0.name,student0.num)printf(%s%ldn,student0.name,student0.num);17例 统计后选人选票struct person char
25、name20;int count;leader3=“Li”,0,“Zhang”,0,”Wang“,0;main()int i,j;char leader_name20;for(i=1;i=10;i+)scanf(%s,leader_name);for(j=0;j3;j+)if(strcmp(leader_name,leaderj.name)=0)leaderj.count+;for(i=0;i(y)?(x):(y).main()int a,b,c,d,t;.t=MAX(a+b,c+d);宏展开:t=(a+b)(c+d)?(a+b):(c+d);int max(int x,int y)retur
26、n(xy?x:y);main()int a,b,c,d,t;.t=max(a+b,c+d);例例用宏定义和函数实现同样的功能用宏定义和函数实现同样的功能36l带参的宏与函数区别带参宏函数处理过程不分配内存简单的字符置换分配内存先求实参值,再代入形参处理时间编译时程序运行时参数类型无类型问题定义实参,形参类型程序长度变长不变运行速度不占运行时间调用和返回占时间37l9.2 文件包含功能:一个源文件可将另一个源文件的内容全部包含进来一般形式:#include “文件名”或#include#include “file2.c”file1.cfile2.cfile1.cfile2.cABA处理过程:预编
27、译时,用被包含文件的内容取代该预处理命令,再对“包含”后的文件作一个源文件编译 直接按标准目录搜索“”先在当前目录搜索,再搜索标准目录可指定路径38被包含文件内容l源文件(*.c)l头文件(*.h)宏定义数据结构定义函数说明等文件包含可嵌套#include “file2.c”file1.cAfile3.cC#include “file3.c”file2.c Bfile1.cAfile3.cfile2.c39例 文件包含举例/*powers.h */#define sqr(x)(x)*(x)#define cube(x)(x)*(x)*(x)#define quad(x)(x)*(x)*(x)*(x)#include#include d:fengyibkcpowers.h#define MAX_POWER 10void main()int n;printf(numbert exp2t exp3t exp4n);printf(-t-t-t-n);for(n=1;n=MAX_POWER;n+)printf(%2dt%3dt%4dt%5dn,n,sqr(n),cube(n),quad(n);40作业:作业:1、6.1、6.2、6.3、6.42、6.9、6.10、6.1141