清华大学C语言谭浩强第7章.ppt_第1页
清华大学C语言谭浩强第7章.ppt_第2页
清华大学C语言谭浩强第7章.ppt_第3页
清华大学C语言谭浩强第7章.ppt_第4页
清华大学C语言谭浩强第7章.ppt_第5页
已阅读5页,还剩122页未读 继续免费阅读

下载本文档

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

文档简介

第7章复合结构类型,第7章 复合结构类型,7.1 结构体类型的概述 7.2 结构体类型的定义 7.3 结构体变量的定义及内存分配 7.4 结构体变量的初始化和引用 7.5 结构体数组 7.6 结构体变量和结构体数组成员的访问 7.7 指向结构体类型数据的指针 7.8 结构体型与函数 7.9 用递归结构处理链表 7.10 共用体型 7.11 枚举类型 7.12 用typedef定义类型,7.1结构体类型的概述,所谓“结构体类型”是由不同数据类型变量组成的集合体,相当于其他高级语言中的记录。 结构体类型的数据由若干称为“成员”的数据组成,每个成员既可以是一个基本数据类型的数据,也可以是另一个构造类型的数据。 例如:定义一个婴儿的出生证明的结构体。 struct baby char name20; /* 婴儿姓名 */ char sex; /* 性别 */ char date20; /* 出生日期 */ char num30; float weight; /* 出生时的体重 */ char place30; /* 出生地 */ ;,7.2结构体类型的定义,1. 结构体类型的定义说明 2. 定义结构体类型时需要注意的问题 3. 结构体型的嵌套定义,1.结构体类型的定义说明,结构体类型定义的一般格式为: struct 结构体名 数据类型1 成员名1; 数据类型2 成员名2; 数据类型3 成员名3; 数据类型n 成员名n; ;,其中,struct是关键字, struct连同其后的结构体标识符一起称为结构体类型名或结构体名; 结构体名是用户定义的标识符,其命名原则应符合标识符的书写规定; 数据类型可以是基本类型说明符,也可以是已定义过的结构体类型名,还可以是后面将要介绍的共用体型等; 成员名也是用户自定义的标识符,用来标识所包含的成员名称; 各成员的定义语句放在花括号中; 花括号后面的分号是整个定义语句的结尾。,例7.1 将学籍管理记录定义成一个名为struct student的结构体类型。 struct student char number5,*name;/* 学号和姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /*总分 */ char *speciality /*专业 */; char school31; /*学校 */ ;,2.定义结构体类型时需要注意的问题,(1)类型与变量是不同的概念,不要混淆。 (2)每个成员都必须有自己的数据类型。 (3)结构体中的成员可以单独使用。 (4)结构体成员可以和程序中的其他标识符同名,也可以和另一个结构体的成员同名。 (5)结构体类型定义的位置,可以在函数内部,也可以在函数外部。 (6)结构体中的成员名可以与程序中的变量名相同,但两者并不代表同一对象。 (7)注意结构体和数组之间的区别: 数组里放的都是类型相同的数据(例如在一个箱子里放的全是苹果); 而结构体中可以放不同类型的数据(例如在一个箱子里既放有苹果,又放有桃、香蕉等不同的水果)。,3.结构体型的嵌套定义,结构体型的定义可以嵌套,即某个结构体型成员的数据类型可以说明为另一个已定义过的结构体类型。 例如将上面定义的结构体类型中的成员“age”改为出生日期“birthday”。 由于出生日期包含年、月、日三个整型数据,可以将它定义成另外一个名为struct date的结构体类型的变量,并将该变量作为结构体类型struct student的一个成员,即 struct date int year; int month; int day; ;,/*struct student 结构体的定义如下*/ struct student char num5,*name; char sex; struct date birthday; float score; char *speciality; char school31; ; 也可以写成嵌套定义的形式:,struct student char number5, *name; char sex; struct date int year; int month; int day; birthday; float score; char *speciality; char school31; ;,7.3结构体变量的定义及内存分配,7.3.1 结构体变量的定义 7.3.2 结构体类型的内存分配模式,7.3.1结构体变量的定义,1.先定义结构体,后定义变量 2.在定义结构体类型的同时定义变量 3.直接说明结构体变量,1.先定义结构体,后定义变量,例如,为学生信息定义两个变量m和n,程序如下: struct student int num; char name20; int age; char sex; char place20; ; struct student m,n;/*定义结构体变量m和n*/,上述程序就说明了两个struct student 型的变量m和n为。 也可以在定义变量的同时,对变量赋初值,例如,上面的例子中定义的语句可以改写成如下赋初值的形式: struct student m=20041,“wangtai”,18,m, “江西“, n=20043,“zhaoli“,16, f , “福建“; 这种方法是将类型定义和变量定义分别进行的,是一种比较常用的定义方法。,2.在定义结构体类型的同时定义变量,这种方法是在说明结构体变量的同时定义结构体变量。这种形式定义的一般格式为: struct 结构体名 成员列表 变量名列表;,3.直接说明结构变量,直接说明结构体类型变量的一般格式为: struct 成员表列 变量名表列; 这种方法与第二种方法的区别在于第三种方法中省去了结构体名,而在后面直接给出结构体变量。,例如: struct int num; char name20; int age; char sex; char place20; m=20041,“wangtai“,18,m, “江西“, n=20043,“zhaoli“,16,f, “福建“;,7.3.2结构体类型的内存分配模式,结构体类型的内存分配模式随该类型中包含的成员不同而不同,需要的内存字节数等于各个成员所需要的内存字节数的总和。 一旦定义了结构体类型的变量或数组后,就要按这种结构体类型的内存分配模式占用内存。,7.4.1 结构体变量的初始化 7.4.2 结构体变量的引用,7.4结构体变量的初始化和引用,7.4.1. 结构体变量的初始化,结构体变量的初始化形式与前面介绍的数组相似,只要把对应各成员的初值放在花括号(即初值表)中即可。,例7.2 结构体变量的初始化。 #include struct student int number; char name20; char sex; struct date int year; int month; int day; birthday; float score; char speciality11; char school31; ;,main() struct student st1=“1001“,“Liming“,0,1983,10,25,573, “Computer“,“3th High School,Beijing“; /*结构体变量st1的定义和初始化*/ printf(“%4d %-10s %c %4d %2d %2d %.2f %-10s %sn“, st1.number,,st1.sex,st1.birthday.year, st1.birthday.month,st1.birthday.day,st1.score, st1.speciality,st1.school); /*输出结构体变量st1的各数据项*/ ,程序运行结果为: 1001 Liming 0 1983 10 25 573.00 Computer 3th High school,Beijing,结构体变量初始化后,C编译系统按结构体成员的顺序将各个初值置于各成员对应的存储单元,如表7-2所示。,表7-2 结构体变量初始化存储示意,注意:对结构体变量初始化时,不允许跳过前面的成员只给后面的成员赋初值,但可以只给前面的成员赋初值,后面未赋初值的成员自动赋零值(字符型数组赋空串)。,7.4.2 结构体变量的引用,不能直接使用结构体变量,只能通过引用其中的成员来实现对结构体变量的使用。 引用结构体变量成员的一般形式为: 结构体变量名.成员名 例如: “m.num”表示m变量中的num成员,即m的num成员项。 如果成员本身又是一个结构体,则必须逐级找到最低级的成员才能使用。例如: “m.birthday.month”表示m变量中的birthday成员中的month成员,即m变量出生的月份成员可以在程序中单独使用,与普通变量的使用完全相同。,例7.3结构体变量成员的引用。 #include “string.h“ struct student /* 定义student类型的变量 */ int num; char name20; char sex; float score; ; main() struct student m; m.num=20048; /* 给结构体变量x的成员num赋值 */ strcpy(,“zhangsan“); /* 用strcpy给结构体变量x的成员name 赋值 */,m.sex=f; /* 给结构体变量x的成员sex赋值 */ m.score=95; /* 给结构体变量x的成员score赋值 */ printf(“num=%d name=%s sex=%c score=%f“, m.num, , m.sex, m.score); /*输出结构体变量m的各数据项的值*/ ,该程序的运行结果如下: num=20048 name=zhangsan sex= f score=95.000000,7.5结构体数组,7.5.1结构体数组的定义 7.5.2结构体数组的初始化,7.5.1结构体数组的定义,1.间接定义 2.直接定义,1.间接定义,先定义结构体类型,再用结构体类型名定义该类型的数组,这是一种间接定义的方式。 例如: struct student int num; char name20; char sex; float score; ; struct student stu 3;,2.直接定义,在定义结构体类型的同时定义该类型的数组,这是一种直接定义的方式。 例如: struct student char number5, *name; char sex; struct date int year; int month; int day; birthday; float score; char *speciality; char school31; st1,st210,*p1;,在直接定义时,也可以在struct后面不带结构体标识符,这种结构体类型称为无名结构体类型。例如: struct char number5, *name; char sex; struct date int year; int month; int day; birthday; float score; char *speciality; char school31; st1,st210,*p1;,说明:有名结构体类型和无名结构体类型比较: (1)有名结构体类型的类型名可以使用多次,可以用它去定义其他的同类型变量、数组或指针。 (2)无名结构体类型只能使用一次,不能用无名结构体类型再去定义其他的变量、数组或指针。,7.5.2结构体数组的初始化,结构体数组的初始化相当于给若干个结构体变量初始化,只要将各个元素的初值顺序放在内嵌的花括号中即可。当整个数组的各个元素都有初始化数据时,内嵌花括号也可以省略。 例7.5以三个学生为例计算学生的平均成绩和及格人数。 #include struct student int num; char name20; char sex;,float score; stu3= 11,“Liang tao“,t,80, 13,“Zhao jun“,f,97.5, 14, “Hai kang“,f,58; /*定义结构体数组并初始化各个数据项的内容*/ main() int i,j=0; float average,sum=0; for(i=0;i=60) j+=1; /*统计及格人数*/ printf(“the sum is %fn“,sum); average=sum/3; /*求平均成绩*/ printf(“the average is %fncount=%dn“, average,j); ,该程序的最后运行结果如下: the sum is=235.500000 the average is =78.500000 count=2,7.6 结构体变量和结构体数组成员的访问,7.6.1访问结构体成员运算符 7.6.2 访问结构体成员的方法,7.6.1访问结构体成员运算符,1.“.”运算符 2.“-”运算符,1.“.”运算符,“.”运算符称点运算符。 当用结构体变量名或结构体数组元素访问其成员时,要用“.”运算符。 例如:“m.age”表示访问m的成员age的值。,2.“”运算符,“”运算符由一个减号和一个大于号组成。 当用结构体指针或结构体数组名等地址量访问其成员时,要用“”运算符。 例如: (n+1)-age表示访问n1的成员age的值。 说明: “.”运算符和“-”运算符都是二元运算符,它们和“( )”、“ ”一起处于最高优先级,结合性均为从左至右。,7.6.2 访问结构体成员的方法,1.访问结构体变量的成员 2.访问结构体数组元素的成员,1.访问结构体变量的成员,若已定义了一个结构体变量及指向它的指针,可以使用以下三种方法访问该结构体变量的成员: 结构体变量名.成员名 结构体指针名成员名 (*结构体指针名).成员名,2.访问结构体数组元素的成员,若已定义了一个结构体数组及指向它的指针, 则可以用数组名(相当于指针)、数组元素名(相当于变量)或指向该数组的指针,并通过相应的运算符“.”或“-”来访问该数组元素的各个成员。 主要有以下几种形式: 结构体数组元素.成员名 结构体数组名成员名 结构体指针名成员名 (*结构体指针名).成员名,3.访问嵌套的结构体成员,若结构体成员是内嵌的结构体时,必须用若干个“.”或“”来顺序地逐层定位到最里层的成员。 假设有一个结构体变量及指向它的结构体指针,该结构体变量的成员含有另一个结构体变量,则访问内嵌成员的形式有以下几种: 结构体变量名.内嵌结构体变量名.成员名 结构体指针名内嵌结构体变量名.成员名 (*结构体指针名). 内嵌结构体变量名.成员名,下面以结构体类型struct student为例,说明访问结构体成员的各种等价表示形式。若 struct student/*定义结构体*/ char number5, *name; char sex; struct date int year; int month; int day; birthday; float score; char *speciality; char school31; ; struct student st1,st210,*p1= 则访问结构体成员(包括变量、数组、指针和内嵌结构)的各种等价形式列于表7-3。,表7-3 结构体成员访问形式示例,7.7指向结构体类型数据的指针,7.7.1结构体指针的初始化 7.7.2结构体指针的应用,7.7.1结构体指针的初始化,可以通过用结构体变量的首地址或结构体数组的数组名作结构体类型指针的初值,从而使其指向对应的结构体变量或结构体数组。,7.7.2结构体指针的应用,1.指向结构体变量的指针 2.指向结构体数组的指针,1.指向结构体变量的指针,一个结构体变量的指针就是该变量所占有的内存的起始地址。 可以设一个指针变量,用来指向一个结构体变量。 此时该指针变量的值是结构体变量的起始地址。,例7.6指向结构体变量指针的应用。 #include main() struct student /*定义结构体*/ int num; char name20; char sex; float score; ; struct student stuone; /*定义结构体变量*/ struct student *p; /*定义结构体指针*/,p= /*用指针的方式输出stuone中各个成员的数据值*/ ,程序的输出结果为: num:10871 name:Mary sex:F score:98.00 num:10871 name:Mary sex:F score:98.00,2.指向结构体数组的指针,对结构体数组及其元素也可以使用指针来指向。 例7.7指向结构体数组指针的应用。 #include main() struct baby int bornnum; char name20; char sex; char place20; ;,struct baby bab2=201,“Lile“,M, “Jiangshu“, 112,“Zhaoliang“, F,“Sandong“; /*定义结构体数组并初始化*/ struct baby *p; /*定义结构体指针*/ for(p=bab;pbornnum,p-name, p-sex,p-place); ,程序的运行结果为: bornnum:201 name:Lile sex:M place:Jiangshu bornnum:112 name:Zhaoliang sex:F place:Sandong,7.8 结构体型与函数,7.8.1 结构体型的数据作函数的参数 7.8.2 结构体型的函数,7.8.1结构体型的数据作函数的参数,1. 结构体变量的成员作参数 2. 结构体变量作参数 3. 指向结构体变量(或数组)的指针作参数,1.结构体变量的成员作参数,调用函数将单个结构体成员传递给被调用函数的用法与普通变量做参数一样主要有以下三种形式: (1)如果该结构体成员是简单变量,则被调用函数对应的形参应该是同类型的简单变量。 (2)如果该结构体成员是变量的地址,则被调用函数中对应的形参应该是指针变量。 (3)如果该结构体成员是数组或指向数组的指针,则被调用函数对应的形参应该是数组名或指针。,例7.8假设学生的三门课成绩已保存在一个结构数组中,要求用子程序计算并返回三门课的总分。在主程序main()中先定义一个结构体类型,再创建一个结构体数组,并将该数组的成员score(数组)传递到子程序add()中,由add()计算总分并返回。 #include main() struct stu; /*定义结构体*/ char name80; int score3; int total; ; struct stu student3; /*定义结构体数组*/ int i; printf(“Please enter three stuname and three score for the three stu:n“);,for(i=0;i3;i+) /*将学生的课程成绩输入结构体数组中*/ scanf(“%s“,); scanf(“%d%d%d“, ,程序的运行情况为: Please enter three stuname and three score for the three stu: zhangli 98 90 97 wanghong 89 88 98 liufei 78 89 97,The score_ table of the three students is : zhangli 98 90 97 285 wanghong 89 88 98 275 liufei 78 89 97 264 在上述程序中要传递的成员是一个数组,因此需要将该数组的各个元素作为单个变量来传递。,2.结构体变量作参数,调用函数将结构体变量整体传递给被调用函数时,采用的是“值传递”的方式。 此时将结构体变量所占内存单元的内容全部顺序传递给形参(形参必须是同类型的结构体变量)。具体可以采用以下三种形式: (1)实参和形参都是结构体变量名。 (2)实参是结构体变量的地址,形参是相同结构体类型的指针。 (3)实参和形参都是相同结构体类型的指针。,例7.9用结构体变量的地址作为实参调用函数的应用举例。 #include struct score /*定义课程分数的结构体*/ int math; int chinese; int english; ; struct information /*定义学生信息的结构体*/ int num; char name20; struct score sco; int average_score; ;,void getinfo(struct information *p); /* getinfo函数的说明*/ void comp(struct information *p); /* comp函数的说明*/ main() struct information exam; /*定义结构体变量exam*/ getinfo(,scanf(“%s“,p-name); /*输入学生的名字*/ printf(“The three score(math,chinese,english) of %s is:n“,p-name); scanf(“%d,%d,%d“,if(p-average_score)=85) /*根据平均成绩判断该学生是否优秀*/ printf(“Excellent!n“); else printf(“General!n“); ,程序的运行情况为: Please enter the information of one student: No:12 Name:Jim The three score(math,chinese,english) of Jim is: 98,90,97 The information about Jim is: No:12 Name:Jim math:98,hinese:90,English:97,average_score:95 Excellent!,3.指向结构体变量(或数组)的指针作参数,用指向结构体变量(或数组)的指针作为实参,将结构体变量(数组)的地址传给形参。可以提高程序的运行效率。 例7.10有一个结构体变量stu,内含学生学号、姓名和3门课的成绩。要求在main函数中赋以值,在另一函数pirnt中将它们打印输出。 #include struct student int num; char name20; int score3; stu=10020,“Mary“,89,98,79; /*定义结构体变量stu并进行初始化*/,void print(struct student *p) /*定义print函数*/ printf(“%dn%sn%dn%dn%dn“,p-num, p-name, p-score0, p-score1, p-score2); /*输出指针p所指学生的输出成绩*/ printf(“n“); main() print( /*调用函数print*/ ,程序的输出结果为: 10020 Mary 89 98 79,7.8.2结构体型的函数,1.结构体型函数 2.结构体指针型函数,1.结构体型函数,结构体型函数定义的一般形式为: struct 结构体名 函数名(形参表) 函数体 例如: struct student function(int x,int y) /*函数头*/ 函数体 上述程序定义了一个struct student结构体类型的函数,它可以将一个结构体变量返回到调用函数。,例7.11一个通讯录中包括联系人的编号、姓名、电话、电子邮件、居住地。根据编号查找并输出查找到的联系人的信息。 #include struct person /*定义结构体数组,并将联系人的相关信息存入该数组*/ int num; char name20; char telephone12; char email40; char addr30; con_person3=9,“Zhangli“,, ““,“Shanghai“, 6,“Jack“,“01089789091“,““, “Bejing“,12,“Qiuzhi“,, ““,“Hangzhou“;,struct person find(int n) /*定义查找函数find*/ int i; for (i=0;con_personi.num!=0;i+) if (con_personi.num=n) return(con_personi); main() int number; struct person result; /*定义结构体变量*/ printf(“Enter the number:“); scanf(“%d“, ,else printf(“Not found!n“); ,程序的运行情况为: Enter the number:12 Name:Qiuzhi TelephoneEmail: Address:Hangzhou Enter the number:9 Name:Zhangli TelephoneEmail: Address:Shanghai Enter the number:1 Not found!,2.结构体指针型函数,结构体指针型函数定义的一般形式为: struct 结构名 *函数名(形参表) 函数体 例如: struct student *function(int x,int y) /*函数头*/ 函数体 ,例7.12将例7.11程序中的结构体型函数改成结构体型指针型函数。 #include struct person /*定义结构体数组并进行初始化赋值*/ int num; char name20; char telephone12; char email40; char addr30; con_person3=9,“Zhangli“,, ““,“Shanghai“, 6,“Jack“,“01089789091“, ““, “Bejing“, 12,“Qiuzhi“,, ““,“Hangzhou“; struct person *find(int n) /*定义函数find*/ int i; for(i=0;con_personi.num!=0;i+),if(con_personi.num=n) return( ,程序的运行情况为: Enter the number:6 Name:Jack Telephone:01089789091 Email: Address:Beijing Enter the number:9 Name:Zhangli TelephoneEmail: Address:Shanghai Enter the number:10 Not found!,7.9 用递归结构处理链表,7.9.1递归结构 7.9.2链表的概念 7.9.3动态链表的基本操作,7.9.1递归结构,如果一个结构体类型的某些成员是该结构体类型的变量、数组或指针,则称之为递归结构,也叫自嵌套结构。 使用最多的递归结构是:结构体的一个成员只能是指向本结构体类型的指针。 例如: struct node int data; struct node *next; 这种递归结构在处理诸如链表这样的数据结构时特别有用。,7.9.2链表的概念,链表是一种动态的数据结构。 单向链表由若干个节点首尾相接而成,每个节点有两个域:数据域data存放数据,指针域next存放下一节点的首地址,如图7-2所示。,单向链表中的节点可用如下递归结构来描述: struct node int data; struct node *next; ; 通过指针将各个节点链接起来,就构成单向链表。 例如,下面的定义和语句可以描述一个含有三个节点的单向链表: struct node int data; struct node *next; a,b,c,*p=,7.9.3动态链表的基本操作,1.建立链表 2.输出链表,1.建立链表,建立链表的过程是: 先建立链表的头节点,并将该头节点作为尾节点,然后不断增加新节点,将新增的节点连接在当前尾节点的后面而作为新的尾节点。 需要设置三个指针,h指向链表的头节点,p指向新建节点,q指向尾节点,如图7-3所示。,2.输出链表,输出链表的过程是: 根据链表的头节点找到下一个节点; 先输出其data域中的数据; 然后根据其next域中的地址,取出后继节点,输出其data域中的数据。 如此不断选取下一个节点,直到链表末尾。,例7.13先建立一个单向链表,将键盘输入的整数1、2、3、4、5、6、7、8、9、10依次存入该链表各个节点的数据域中,当输入整数0时,结束建立链表的操作。然后依次输出链表中的数据,直到链表末尾。 #include struct node /*递归定义单链表的节点*/ int data; struct node *next; ; struct node *creatlist() /*定义创建单链表的函数*/ struct node *h,*p,*q; int a; h=(struct node *)malloc(sizeof(struct node); /*头节点,即链表起始地址*/ p=q=h;,scanf(“%d“, /*取下一个后继节点*/ ,printf(“n“); return; main() struct node *head; head=creatlist(); /*创建链表并保存链表起始地址*/ printlist(head); /*输出链表*/ ,程序运行结果为: 1 2 3 4 5 6 7 8 9 10 0 (键盘输入) -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 (输出结果),7.10共用体型,共用体由若干个数据类型组合而成。和结构体型不同的是,共用体数据中所有成员都占用相同的内存单元,设置这种数据类型的主要目的就是节省内存空间。 例7.14在一个函数的三个不同的程序段中分别使用了字符型变量c1、整型变量d1、单精度型变量f1,这时就可以把它们定义成一个共用体变量un,un中含有三个不同类型的成员。,为了节省空间,假如现在只给三个成员一共分配4个内存单元,那么3个成员之间的对应关系如下图7-4所示。,7.10.1共用体的定义,共用体定义的一般形式为: union 共用体名 数据类型1 成员名1; 数据类型2 成员名2; 数据类型n 成员名n; ; 共用体名是用户自定义的标识符;数据类型通常是前面所使用的基本数据类型,也可以是结构体型、共用体型等构造类型。,例如,以下代码说明了一个共用体un1: union un1 int a100; char m100; float n200; ; 其中,成员a占用了200个单元的内存空间,因为a 为整型,而一个整型占2个单元的空间,所以2100=200。 同理,成员m占用了1100=100个内存单元;成员 n占用了4200=800个内存单元,所以,该共用体 共占用了800个单元空间。,7.10.2共用体变量的定义,共用体变量定义的方法也有三种: (1)先说明共用体,再定义共用体变量。 (2)在说明共用体类型的同时定义共用体变量。 (3)直接定义共用体变量。 例如,将含有10个元素的整型数组m10、字符型数组n35、双精度数据a定义成一个共用体un,然后再定义这个共用体的变量x和y。 下面分别用上述的三种方法进行定义。,(3)定义无名称的共用 体,同时定义变量x和y。 union int m10; char n35; double a; x,y;,(1)先定义共用型,然后再定义变量x和y。 union un int m10; /* 该成员共占用了20个单元空间 */ char n35; /* 该成员共占用了15个单元空间 */ double a; /* 该成员共占用了8个单元空间 */ ; /* 该共用体共占用了20个单元空间 */ union un x,y; /* 定义两个共用体变量x和y */,(2)同时定义共用体un 和变量x、y。 union un int m10; char n35; double a; x,y;,7.10.3共用体变量的引用,1.直接引用 2.通过指向共用体变量的指针进行引用 3.共用体变量与函数,1.直接引用,共用体变量成员的直接引用是通过运算符“.”实现的。其引用的一般格式为: 共用体变量名.成员名 例如: union int m; char ch; double a; x; printf(“%d,%c,%lf“,x.m,x.ch,x.a); 上述printf语句中的x.m、x.ch、x.a是对共用体变量x成员m、ch、a的引用。,2.通过指向共用体变量的指针进行引用,通过指向共用体变量的指针可以对共用体变量的成员进行存取操作。其一般的语法格式为: 指向结构体变量的指针-成员名 或 (*指向结构体变量的指针).成员名 例7.15通过共用体变量的指针对共用体变量中的成员进行引用的应用举例。 #include union stu /*定义共用体*/ char *name; int num; ;,main() union stu *p,stuone; /*定义共用体指针和共用体变量*/ p= /*用指针输出num的值*/ ,程序段的输出结果为: 101,说明:指向共用体变量的指针对共用体变量的操作可以通过强制转换后的指针存取共用体变量的成员,而不必指定成员名。系统会根据强制转换的数据类型给与该类型相同的数据成员赋值。,例7.16通过强制转换后的指针引用共用体变量成员的举例。 #include union worker /*定义共用体*/ float salary; int number; ; main() union worker *p,personone;/*定义共用体指针和共用体变量*/ p= ,程序的运行结果为: 4567.00 112,3.共用体变量与函数,共用体变量本身不能作为函数的参数,但共用体成员可以在函数中进行引用。 而且函数也不能返回共用体变量。 但是指向共用体变量的指针可以作为函数的参数,返回值也可以是指向共用体变量的指针。,例7.17共用体变量的成员和共用体指针作函数参数的应用举例。 #include union traffic char *name; int num; ; void road(char *x) /*定义road函数*/ printf(“The name of traffic is %s!n“,x); void air(union traffic *x) /*定义air函数*/ printf(“The name of traffic is %s!n“,x-name); ,main() union traffic *p,traone;/*定义共用体指针和共用体变量*/ p= /*调用air函数*/ ,程序的运行结果为: The name of traffic is car! The name of traffic is car!,7.10.4共用体类型数据的特点,(1)共用体中的多个成员共用一个内存段,但同一瞬间只有一个成员占用内存段,即每一瞬时只有一个成员存在和起作用,不能所有的成员同时在内存段中起作用。 (2)共用体变量的地址和共用体各个成员的地址都是同一个地址。 例如: unoin sr char ch1; float a; ; union sr str; /*定义共用体变量str*/ 此时,&str、&str.ch1、&str.a的地址值是同一个。,(3)共用体中起作用的成员是最后一次存放的成员。 例如: unoin cc int a; int b; int c; ; unoin cc ch1; /*定义共用体变量ch1*/ ch1.a=2; /*为ch1的成员a赋值*/ ch1.b=3; /*为ch1的成员b赋值*/ ch1.c=4; /*为ch1的成员c赋值*/ 此时若执行以下语句: printf(“%d“,ch1.a); printf(“%d“,ch1.b); printf(“%d“,ch1.c); 则三条语句的输出结果均为4。,(4)共用体类型可以在结构体类型中定义,结构体类型也可以在共用体类型中定义。例如:以下共用体cc的成员中就有结构体类型的变量bb。 unoin cc /*定义共用体*/ int a; char b20; struct dd int i; int j; bb; /*定义结构体变量bb*/ ;,(5)共用体类型可以嵌套定义。例如: unoin aa int a; char b20; unoin bb int i; int j; c; /*定义共用体变量c*/ ;,(6)不能对共用体变量名赋值,也不能通过引用变量名得到一个值。 (7)共用体类型的变量不能作为函数的参数,也不能使函数返回共用体变量。但可以使用共用体变量的指针。 (8)不能在定义共用体变量时对其进行初始化。例如下面的初始化是错误的: unoin cc int a; int b; int c; s=2,3,4;,7.10.5结构体和共用体的区别,结构体和共用体之间存在着以下的区别: (1)结构体和共用体都是由多个不同的数据类型成员组成, 但在同一时刻, 共用体中只存放一个被选中的成员, 而结构体的所有成员都存在。 (2)对共用体的不同成员赋值, 将会造成对其他成员的重写, 原来成员的值就不存在了, 而对于结构体的不同成员赋值是互不影响的。,例7.18共用体和结构体应用举例。 #include main() union /* 定义一个共用体 */ int i; struct /* 在共用体中定义一个结构体 */ char first; char second; sql_1; /* 定义一个结构体变量sql_1 */ number; /* 定义一个共用体变量number */ number.i=0x4445; /* 给共用体变量的成员赋值 */ printf(“%c%c%xn“, number.sql_1.first, number.sql_1.second,number.i);,number.sql_1.first=c; /* 给共用体变量中的结构体成员赋值 */ number.sql_1.second=d; printf(“%xn“, number.i); ,程序的输出结果为: ED4445 6463,说明:从上面的结果可以看出:当给i赋值后, 其低八位是first的值,而高八位是second的值,当给first和second赋字符后, i的值也跟随发生了变化。,7.11枚举类型,7.11.1枚举型的定义 7.11.2枚举变量的定义 7.11.3给枚举常量赋初值 7.11.4枚举中的几条规定,7.11.1枚举型的定义,枚举型定义的一般形式为: enum 枚举名 枚举常量1,枚举常量2,枚举常量n ; 其中的枚举常量是用户给常量取的标识符,有固定的值,在一个含有n个枚举常量的枚举型中,C语言规定枚举常量的值按枚举的顺序分别依次等于0、1、 n-1。 例如,定义一个表示星期的枚举型。 enum week sun,mon,tue,wed,thu,fri,sat ; 上述语句定义了一个名为“week”的枚举类型,该枚举型中有7个枚举常量,分别是:sun、mon、tue、wed、thu、fri和sat,即一周中的七天。每个枚举常量按规定其值从0开始依次为0、1、2、3、4、5、6。,7.11.2枚举变量的定义,枚举变量的定义和结构体相似,有以下三种方式: (1)先定义枚举型,再定义枚举变量。 enum 枚举名 变量名表; 例如: enum traffic train,plane,car,ship ; enum traffic trone,trtwo; 上述语句定义了两个枚举变量:trone和trtwo。 (2)在说明枚举型的同时定义枚举型的变量。 例如: enum traffictrain,plane,car,shiptrone,trtwo; (3)不说明枚举型,直接定义枚举变量。 例如: enum train,plane,car,shiptrone,trtwo;,7.11.3给枚举常量赋初值,枚举常量赋初值的方法是在枚举常量的后面跟上“=整型常量”

温馨提示

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

评论

0/150

提交评论