第9章结构体和共用体12-07_第1页
第9章结构体和共用体12-07_第2页
第9章结构体和共用体12-07_第3页
第9章结构体和共用体12-07_第4页
第9章结构体和共用体12-07_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

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

文档简介

1、博学谷让IT教学更简单,让IT学习更有效第9章 结构体和共用体学习目标u 掌握结构体类型与变量的定义及初始化u 掌握结构体变量的引用u 掌握结构体与数组、指针、函数等结合使用u 掌握共用体变量的定义与引用u 理解结构体与共用体的内存分配机制前面章节所学的数据类型都是分散的、互相独立的,例如定义int a和char b两个变量,这两个变量是毫无内在联系的,但在实际生活和工作中,经常需要处理一些关系密切的数据,例如,描述公司一个员工的姓名、部门、职位、电话、E-mail地址等,由于这些数据的类型各不相同,因此,要想对这些数据进行统一管理,仅靠前面所学的基本类型和数组都很难实现。为此,C语言提供了另

2、外两种构造类型,分别是结构体和共用体,本章将围绕这两种构造类型进行详细地讲解。9.1 结构体类型和结构体变量9.1.1 结构体类型定义结构体是一种构造数据类型,把不同类型的数据整合在一起,每一个数据都称为该结构体类型的成员。在程序设计中,使用结构体类型时,首先要对结构体类型的组成进行描述,结构体类型的定义方式如下所示:struct 结构体类型名称数据类型 成员名1;数据类型 成员名2;数据类型 成员名n;在上述语法结构中,“struct”是定义结构体类型的关键字,其后是所定义的“结构体类型名称”,在“结构体类型名称”下的大括号中,定义了结构体类型的成员项,每个成员是由“数据类型”和“成员名”共

3、同组成的。例如,为了描述一组学生信息,该信息由学号(num)、姓名(name)、性别(sex)、年龄(age)、地址(address)等组成,我们可以使用下列语句定义一个名称为Student的结构体类型:struct Studentint num;char name10;char sex;int age;char address30;在上述结构体类型的定义中,结构体类型Student由5个成员组成,分别是num、name、sex、age和address。值得一提的是,结构体类型中的成员,也可以是一个结构体变量,例如,在学生信息中增加一项出生日期的信息,具体代码如下:struct Dateint

4、 year;int month;int day;struct Studentint num;char name10;char sex;struct Date birthday; stu1;在上述代码中,我们首先定义了结构体类型Date,该结构体类型由year、month、day三个成员组成;然后定义了结构体变量stu1,其中的成员birthday是Date结构体类型。student的类型结构如图9-1所示。图9-1 结构体类型Student的类型结构注意:1、 结构体类型定义以关键字struct开头,后面跟的是结构体类型的名称,该名称的命名规则与变量名的命名规则相同。2、 定义好一个结构体类型

5、后,并不意味着立即分配一块内存单元来存放各个数据成员,它只是告诉编译器,该结构体类型是由哪些数据类型的成员构成,各占多少个字节,按什么格式存储,并把它们当作一个整体来处理。 3、 结构体类型定义末尾括号后的分号不可缺少。4、 结构体类型的成员可以是一个结构体变量,但不能是自身结构体类型的变量。 9.1.2 结构体变量的定义上个小节只是定义了结构体类型,它仅相当于一个模型,其中并无具体数据,系统也不会为它分配内存空间。为了能在程序中使用结构体类型的数据,应该定义结构体类型的变量,并在其中存放具体的数据。下列是定义结构体变量的三种方式。1、 先定义结构体类型,再定义结构体变量定义好结构体类型后,就

6、可以定义结构体变量了,定义结构体变量的语法格式如下所示:struct 结构体类型名 结构体变量名;例如:struct student stu1, stu2; 上述示例定义了结构体类型变量stu1和stu2,这时变量stu1和stu2具有了结构体特征,它们各自存储了一组基本类型的变量,具体如图9-2所示。图9-2 变量stu1、stu2的存储结构从图9-2中可以看出,变量stu1和stu2分别占据了一块连续的内存空间。2、 在定义结构体类型的同时定义结构体变量该方式的作用与第一种方式相同,其语法格式如下所示:struct 结构体类型名称数据类型 成员名1;数据类型 成员名2;数据类型 成员名n;

7、 结构体变量名列表;例如:struct studentint num;char name10;char sex; stu1, stu2;上述代码在定义结构体类型student的同时,也定义了结构体类型变量stu1和stu2。其中变量stu1和stu2中包含的成员的数据类型都是一样的。3、 直接定义结构体变量除了上述两种方式外,我们还可以直接定义结构体变量,其语法格如下所示:struct数据类型 成员名1;数据类型 成员名2;数据类型 成员名n; 结构体变量名列表;例如:structint num;char name10;char sex; stu1, stu2;上述代码同样定义了结构体变量st

8、u1和stu2,但采用这种方式定义的结构体是没有类型名称,我们称之为匿名结构体。注意:结构体类型是用户自定义的一种数据类型,它同前面所介绍的简单数据类型一样,在编译时对结构体类型不分配空间。只有用它来定义某个变量时,才会为该结构体变量分配结构体类型所需大小的内存单元。9.1.3 结构体变量的内存分配结构体变量一旦被定义,系统就会为其分配内存。结构体变量占据的内存大小是按照字节对齐的机制来分配的。字节对齐就是字节按照一定规则在空间上排列。通常情况下,字节对齐满足两个原则,具体如下:(1)结构体的每个成员变量相对于结构体首地址的偏移量,是该成员变量的基本数据类型(不包括结构体、数组等)大小的整数倍

9、,如果不够,编译器会在成员之间加上填充字节。接下来通过一个案例来打印出每个成员变量的地址,如例9-1所示。例9-1 1 #include <stdio.h> 2 / 直接定义结构体变量 3 struct 4 5 char a; 6 double b; 7 int c; 8 short d; 9 s; 10 void main() 11 12 printf("成员变量a的地址:%dn", &s.a); 13 printf("成员变量b的地址:%dn", &s.b); 14 printf("成员变量c的地址:%dn&qu

10、ot;, &s.c); 15 printf("成员变量d的地址:%dn", &s.d); 16 printf("成员变量d的地址:%dn", &s+1; 17 运行结果如图9-3所示。图9-3 运行结果从图9-3中可以看出,结构体变量中成员变量的地址都被打印出来了。结构体变量S中各成员在内存中所占内存如图9-4所示。图9-4 结构体变量中各成员所占内存图接下来根据图9-3和图9-4来逐步分析每个成员变量的地址:l 成员变量a的地址是3703968,同时这也是结构体变量s的首地址;l 成员变量b的地址是3703976,相对于结构体变

11、量的首地址的偏移量是8个字节。这是因为成员变量b的基本数据类型是double型,其偏移量应该是8(sizeof(double))的倍数,所以a变量后面被填充了7个字节;l 成员变量c的地址是3703984,相对于结构体变量的首地址的偏移量是16,是变量a与变量b所占内存大小之和,正好也是4(sizeof(int))的倍数;l 成员变量d的地址是3703988,相对于首地址的偏移量是20字节,是变量a、b、c所占内存大小之和,正好也是2(sizeof(short))的倍数。(2)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如果不够,编译器会在最末一个成员之后加上填充字节。经过例9-1的分

12、析,可以计算出结构体变量s的内存大小是22,但是这并不符合字节对齐的第二项准则,下面将例9-1中的结构体变量在内存中的大小打印出来,如例9-2所示。例9-2 1 #include <stdio.h> 2 struct 3 4 char a; 5 double b; 6 int c; 7 short d; 8 s; 9 void main() 10 11 printf("结构体变量s在内存中的大小:%dn", sizeof(s); 12 运行结果如图9-5所示。图9-5 运行结果从图9-5中可以看出,结构体变量s的内存大小为24字节,而非22字节。这是因为,结构体

13、的总大小应该是最宽基本类型成员大小的整数倍。成员变量中最宽基本类型的大小为8(sizeof(double)),所以d后面被填充了2个字节,结构体变量s所占内存大小为24字节。其内存分配如图9-6所示。图9-6 结构体s占内存的总大小需要注意的是,如果结构体中有构造类型变量,如结构体中有char类型数组成员,则其偏移量是按数组中的元素类型为基准,即偏移量是1(sizeof(char))的倍数。如果是int类型数组,则偏移量是4(sizeof(int))的倍数。关于结构体变量的分配,不同的编绎器有不同的分配规则,读者了解即可,在实际应用中可用sizeof()运算符很快捷的求出结构体变量的大小。9.

14、1.4 结构体变量的初始化由于结构体变量中存储的是一组类型不同的数据,因此,为结构体变量初始化的过程,其实就是为结构体中各个成员初始化的过程。根据结构体变量定义方式的不同,结构体变量初始化的方式可分为两种。1、在定义结构体类型和结构体变量的同时,对结构体变量初始化,具体示例如下:struct Studentint num;char name10;char sex;stu=20140101,"Zhang San",'M' ;上述代码在定义结构体变量stu的同时,就对其中的成员进行了初始化。2、定义好结构体类型后,对结构体变量初始化,具体示例如下:struct

15、Studentint num;char name10;char sex;struct Student stu = 20140101,"Zhang San",'M'在上述代码中,首先定义了一个结构体类型Student,然后在定义结构体变量时,为其中的成员进行初始化。M脚下留心:初始化一部分成员变量在对结构体初始化时,如果只初始化其中一部分成员,则要对前面的成员初始化,后面的成员可以空余,因为给成员变量赋值时,编绎器是从按成员从前往后匹配,而不是按数据类型自动去匹配。可以给一部分成员初始化,然后将各个成员打印出来,如例9-3所示。例9-3#include <

16、;stdio.h>struct Studentint num;char name10;char sex;stu = 20140101, 'M' ;void main() printf("num = %dn", stu.num);printf("name = %sn", );printf("sex = %cn", stu.sex);运行结果如图9-7所示。图9-7 运行结果如图9-7所示,在结构体变量stu中只对num和sex赋值,但在输出所有成员的值时,M却赋值给了name,sex没有值。9.1.

17、5 结构体变量的引用定义并初始化结构体变量的目的是使用结构体变量中的成员。在C语言中,引用结构体变量中一个成员的方式如下所示:结构体变量名.成员名;例如,下列的语句用于引用结构体变量stu1中num成员:stu1.num;为了帮助大家更好地掌握结构体变量的使用,接下来通过一个案例来输出结构体变量中所有成员的值,如例9-4所示。例9-4 1 #include <stdio.h> 2 #include <stdlib.h> 3 struct Student 4 5 char name50; 6 int age; 7 ; 8 void main() 9 10 struct S

18、tudent s = "Zhang San", 23; 11 s.age = 24; 12 printf("%s %dn", , s.age); 13 运行结果如图9-8所示。图9-8 运行结果 从图9-8中可以看出,结构体变量中成员name和age的值被输出了。9.2 结构体数组一个结构体变量可以存储一组数据,例如一个学生的序号、姓名、性别等数据。如果有10个学生的信息需要存储,可以采用结构体数组。与前面讲解的数组不同,结构体数组中的每个元素都是结构体类型的,它们都是具有若干个成员的项。本节将针对结构体数组的定义、引用及初始化方式进行详细地

19、讲解。9.2.1 结构体数组的定义假设一个班有20个学生,如果我们需要描述这20个学生的信息,可以定义一个长度为20的Student类型数组,与定义结构体变量一样,可以采用三种方式定义结构体数组stus。 1、 先定义结构体类型,后定义结构体数组,具体示例如下:struct Studentint num;char name10;char sex;struct Student stus20;2、 在定义结构体类型的同时定义结构体数组,具体示例如下:struct Studentint num;char name10;char sex; stus20;3、 直接定义结构体数组,具体示例如下:stru

20、ct int num;char name10;char sex; stus20;9.2.2 结构体数组的初始化结构体数组的初始化方式与数组类似,都是通过为元素赋值的方式完成的。由于结构体数组中的每个元素都是一个结构体变量,因此,在为每个元素赋值的时候,需要将其成员的值依次放到一对大括号中。例如,定义一个结构体数组students,该数组有3个元素,并且每个元素有num,name,sex三个成员,可以采用下列两种方式对结构体数组students初始化。1、先定义结构体数组类型,然后初始化结构体数组,具体示例如下:struct Studentint num;char name10;char sex

21、;struct Student students3 = 20140101, "Zhang San",'M', 20140102, "Li Si",'W' 20140103, "Zhao Liu",'M'2、在定义结构体数组的同时,对结构体数组初始化,具体示例如下:struct Studentint num;char name10;char sex; students3 = 20140101, "Zhang San",'M', 20140102, &qu

22、ot;Li Si",'W',20140103, "Zhao Liu",'M'当然,使用这种方式初始化结构体数组时,也可以不指定结构体数组的长度,系统在编译时,会自动根据初始化的值决定结构体数组的长度。例如,下列初始化方式也是合法的。struct Studentint num;char name10;char sex; Student students = 20140101, "Zhang San",'M', 20140102, "Li Si",'W',20140

23、103, "Zhao Liu",'M'9.2.3 结构体数组的引用结构体数组的引用是指对结构体数组元素的引用,由于每个结构体数组元素都是一个结构体变量,因此,结构体数组元素的引用方式与结构体变量类似,其语法格式如下所示:数组元素名称.成员名; 例如,要引用9.2.2小节中结构体数组student第一个元素的num成员,可以采用下列方式:student0.num;为了帮助读者更好地掌握结构体数组的引用,接下来通过一个案例来输出结构体数组中的所有成员,如例9-5所示。例9-5 1 #include <stdio.h> 2 #include <s

24、tdlib.h> 3 struct Student 4 5 char name50; 6 int studentID; 7 ; 8 void main() 9 10 struct Student s2 = "Zhang San", 20140000, "Li Si", 20140001; 11 for (int i = 0; i < 2; i+) 12 13 printf("%s %dn", , si.studentID); 14 15 运行结果如图9-9所示。图9-9 运行结果在例9-5中,首先定义了一个长

25、度为2的结构体数组s,并对数组中的元素进行了初始化。然后使用for循环,依次输出了s0和s1中的成员值。9.3 结构体指针变量在第6章学习指针时,指针指向的都是基本数据类型。其实,指针还可以指向结构体,被称为结构体指针变量,它的用法与一般指针没有太大差异,本节将围绕结构体指针变量进行详细讲解。9.3.1 结构体指针变量在使用结构体指针变量之前,首先需要定义结构体指针,结构体指针的定义方式与一般指针类似,例如,下列语句定义了一个Student类型的指针。struct Student s = "Zhang San", 20140100, 'M', 93.5;st

26、ruct Student *p = &s;在上述代码中,定义了一个结构体指针p,并通过“&”将结构体变量s的地址赋值给p,因此,p就是指向结构体变量s的指针。当程序中定义了一个指向结构体变量的指针后,就可以通过“指针名à成员变量名”的方式来访问结构体变量中的成员,接下来通过一个案例来演示结构体指针的用法,如例9-6所示。例9-6 1 #include <stdio.h> 2 #include <stdlib.h> 3 struct Student 4 5 char name50; 6 int studentID; 7 ; 8 void main

27、() 9 10 struct Student s = "Zhang San", 20140000; 11 struct Student *p = &s; 12 printf("%s %dn", p->name, p->studentID); 13 运行结果如图9-10所示。图9-10 运行结果在例9-6中,首先定义了一个结构体类型变量s,并将变量s中的成员name初始化为Zhang San,studentID 初始化为20140000。然后,定义了一个结构体指针p,并将p指向s的地址,最后,通过p->name访问成员name和s

28、tudentID的值。从图9-10中可以看出,使用结构体指针同样可以访问结构体变量中的成员。9.3.2 结构体数组指针指针可以指向结构体数组,即将结构体数组的起始地址赋给指针变量,这种指针就是结构体数组指针,例如,下面语句定义了Student结构体的一个数组和该数组的指针。struct Student stu110,*p=&stu1;在上述代码中,p是一个Student结构体数组指针,从定义上看,它和结构体指针没什么区别,只不过指向的是结构体数组。为了帮助读者更好地掌握结构体数组指针的用法,接下来通过一个案例来演示如何使用结构体数组指针输出多个学生的信息,如例9-7所示。例9-7 1

29、#include <stdio.h> 2 #include <stdlib.h> 3 struct student 4 5 int num; 6 char name20; 7 char sex; 8 int age; 9 stu3= 10 201401001,"Wang Ming",'M',19, 11 201401002,"Zhang Ning",'W',23, 12 201401003,"Wang Ming",'M',19; 13 void main() 14

30、 15 struct student *p; 16 printf("numttnamettsextagen "); 17 for(p=stu;p<stu+3;p+) 18 19 printf("%ldt%-12st%-2ct%4dn",p->num,p->name,p->sex,p->age); 20 21 运行结果如图9-11所示。图9-11 运行结果在例9-7中,第312行代码用于初始化结构体数组stu,在第17行代码中,“p=stu”用于将p指向结构体数组stu的第一个元素,“p+”用于将指针指向下一个元素。第19行代

31、码,通过“->”用于获取某个成员的值。从图9-11中可以看出,程序输出了结构体数组stu中所有元素的成员值。9.4 结构体类型数据在函数间的传递在函数间不仅可以传递简单的变量、数组、指针等类型的数据,还可以传递结构体类型的数据。本节将针对结构体类型数据在函数间的传递进行详细讲解。9.4.1 结构体变量作为函数参数结构体变量作为函数参数的用法与普通变量类似,都需要保证调用函数的实参类型和被调用函数的形参类型相同。结构体变量作函数参数时,也是值传递,被调函数中改变结构体成员变量的值,主调函数中不受影响。如例9-8所示例9-8 1 #include <stdio.h> 2 stru

32、ct Student 3 4 char name50; 5 int studentID; 6 ; 7 void change(struct Student stu) 8 9 strcpy(stu->name, "lisi"); 10 stu.studentID = 2; 11 12 void main() 13 14 struct Student student = "Zhang San", 1 ; 15 change(student); 16 printf("name = %s studentID = %dn", studen

33、, student.studentID); 17 运行结果如图9-12所示。图9-12 运行结果在例9-8中,定义了一个用于改变数据的change()函数,该函数需要接收一个结构体类型的参数。从代码第15行可以看出,当将结构体变量作为参数传递给函数时,其传参的方式与普通变量相同。在主调函数中调用change()函数后,主函数中结构体中成员的值并没有改变。9.4.2 结构体数组作为函数参数函数间不仅可以传递一般的结构体变量,还可以传递结构体数组。接下来通过一个案例来演示如何使用结构体数组作为函数参数传递数据,如例9-9所示。例9-9 1 #include <stdio.h>

34、; 2 struct Student 3 4 char name50; 5 int studentID; 6 ; 7 void printInfo(struct Student stu,int length) 8 9 for (int i = 0; i < length; i+) 10 11 printf("name: %sn", ); 12 printf("id: %inn", stui.studentID); 13 14 15 void main() 16 17 struct Student students3 = "

35、;Zhang San", 1 , 18 "Li Si",2, 19 "Wang Wu", 3 ; 20 printInfo(students, 3); 21 运行结果如图9-13所示。图9-13 运行结果在例9-9中,由于无法通过数组直接获取到其长度,因此,在定义的printfInfo()函数中,需要传递两个参数,其中一个是结构体数组,另一个是数组的长度。printfInfo()函数接收到传递来的数组名和长度后,使用for循环,将结构体数组中的所有成员输出。9.4.3 结构体指针作为函数参数结构体指针变量用于存放结构体变量的首地址,所以将指针作

36、为函数参数传递时,其实就是传递结构体变量的首地址,在被调函数中改变结构体成员的值,那么主调函数中结构体成员的值也会被改变。如例9-10所示。例9-10 1 #include <stdio.h> 2 struct Student 3 4 char name50; 5 int studentID; 6 ; 7 void change(struct Student* stu) 8 9 strcpy(stu->name, "lisi"); 10 stu->studentID = 2; 11 12 void main() 13 14 struct Studen

37、t student = "Zhang San", 1 ; 15 change(&student); 16 printf("name = %s studentID = %dn", , student.studentID); 17 运行结果如图9-14所示。图9-14 运行结果在例9-10中,定义了一个改变数据的change()函数,该函数需要接收一个结构体指针类型的参数,由于结构体指针作为函数参数时,需要传递的是结构体变量的首地址,因此,在代码第15行中,通过“&”运算符获取结构体变量student的首地址,然后将其

38、作为参数传递给change()函数。在change()函数中改变结构体变量成员的值,则main()函数中的结构体成员值也随着改变了。9.5 union共用体共用体又叫联合体,是一种特殊的数据类型,它允许多个成员使用同一块内存。灵活地使用共用体可以减少程序所使用的内存。本节将针对共用体进行详细地讲解。9.5.1 共用体数据类型的定义在C语言中,共用体类型同结构体类型一样,都属于构造类型,它在定义上与结构体类型十分相似,定义共用体类型的语法格式如下所示:union 共用体类型名称 数据类型 成员名1; 数据类型 成员名2; 数据类型 成员名n;在上述语法格式中,“union”是定义共用体类型的关键

39、字,其后是所定义 “共用体类型名称”,在“共用体类型名称”下的大括号中,定义了共用体类型的成员项,每个成员是由“数据类型”和“成员名”共同组成的。例如下面这段代码:union data int m; float x; char c; ;上述代码定义了一个名为data的共用体类型,该类型由三个不同类型的成员组成,这些成员共享同一块存储空间。9.5.2 共用体变量的定义共用体变量的定义和结构体变量的定义类似,假如要定义两个data类型的共用体变量a和b,则可以采用下列三种方式。1、先定义共用体类型,再定义共用体变量,具体示例如下:union data int m; float x; char c;

40、union data a,b;2、在定义共用体类型的同时定义共用体变量,具体示例如下:union data int m; float x; char c;a,b;3、直接定义共用体类型变量,具体示例如下:union int m; Double x; char c;a,b; 上述三种方式都用于定义共用体变量a和b, 和结构体变量的定义相同。&多学一招:共用体内存分配共用体的内存分配必须要符合两项准则,具体如下:1、 共用体的内存必须大于或等于其成员变量中大数据类型(包括基本数据类型和数组)的大小2、共用体的内存必须是最宽基本数据类型的整数倍,如果不是,则填充字节。接下来通过两个共用体的内

41、存分析来解释上述准则。(1)成员变量都是基本数据类型的共用体,具体如下union int m; float x; char c;a;共用体a的内存大小如图9-15所示。图9-15 共用体a的内存大小共用体a的内存大小是最大数据类型所占的字节数,即int和float的大小,所以共用体a的内存大小为4字节。(2)成员变量包含数组类型的共用体,具体如下union int m; float x; char c; char name5;b;共用体b的内存大小如图9-16所示。图9-16 共用体b的内存大小共用体b的内存大小是按最大数据类型char name5来分配, char name5占5个字节。共用

42、体b的内存大小还必须是最宽基本数据类型的整数倍,所以填充3个字节,共8个字节。关于共用体变量的内存大小,读者可以通过sizeof()来验证。9.5.3 共用体变量的初始化和引用在共用体变量定义的同时,只能对其中一个成员的类型值进行初始化,这与它的内存分配也是相应的。共用体变量初始化的方式如下所示:union 共用体类型名 共用体变量=其中一个成员的类型值从上述语法格式可以看出,尽管只能给其中一个成员赋值,但必须用大括号括起来。例如,下列语句用于对data类型的共用体变量a进行初始化。union data a=8; 完成了共用体变量的初始化后,就可以引用共用体中的成员了,共用体变量的引用方式与结

43、构体类似,例如,下列代码定义了一个共用体变量a和一个共用体指针p。union data int m; float x; char c;union data a, *p=&a;如果要引用共用体变量中的m成员,则可以使用下列方式:a.m; / 引用共用体变量a中的成员m p->m / 引用共用体指针变量p所指向的变量成员m需要注意的是,虽然共用体变量的引用方式与结构体类似,但两者是有区别的,其主要区别是,在程序执行的任何特定时刻,结构体变量中的所有成员是同时驻留在该结构体变量所占用的内存空间中,而共用体变量仅有一个成员驻留在共用体变量所占用的内存空间中。接下来通过一个案例来验证,如例

44、9-11所示。例9-11 1 #include <stdio.h> 2 union Data 3 4 int i; 5 char j; 6 ; 7 void main() 8 9 union Data d;/定义了一个union 10 d.i = 15; 11 printf("d.i = %dn", d.i); 12 printf("d.j = %dn", d.j); 13 printf("d = %dn", d); 14 15 d.j = 'a' 16 printf("d.i = %dn&quo

45、t;, d.i); 17 printf("d.j = %dn", d.j); 18 printf("d = %dn", d); 19 20 printf("d.i的地址%pn", &d.i); 21 printf("d.j的地址%pn", &d.j); 22 printf("d的地址%pn", &d); 23 运行结果如图9-17所示。图9-17 运行结果在例9-11中,定义了一个Data类型的共用体变量d,其中包含了两个int类型的变量i和char类型的变量j,当将i赋

46、值为15时,则此时结构体d中只有一个值15,取i的值、j的值和结构体变量d的值,其实都是取对应内存中的同一个值。当将j的值为字符a时,则此时d对应的内存中只有字符a,取i,j,d的值都是97。最后打印d、i、j的地址,三者的地址是相同的,更进一步说明共用体变量在任何时该都只有一个成员值在内存中。9.6 Typedef给数据类型取别名在前面章节中,讲解了C语言提供的各种数据类型和用户自己声明的结构体、共用体、指针类型等。除了这些数据类型,C语言还允许用户使用typedef关键字为现有数据类型取别名。使用typedef关键字可以方便程序的移植,减少对硬件的依赖性。接下来将针对typedef关键字进

47、行详细地讲解。使用typedef关键字语法格式如下:typedef 数据类型 别名;在上述语法格式中,数据类型包括基本数据类型、构造数据类型、指针等,接下来针对这几项进行详细讲解。1、为基本类型取别名使用typedef关键字为int类型取别名,示例代码如下:typedef int ZX;ZX i,j,k;上面的语句将int数据类型定义成ZX,则在程序中可以用ZX定义整型变量。2、为数组类型取别名使用typedef关键字为数组取别名,示例代码如下:typedef char NAME10;NAME class1,class2;上面的语句定义了一个可含有10个字符的字符数组名NAME,并用NAME定

48、义了两个字符数组class1和class2,等效于char class110和char class210。3、为结构体取别名使用typedef关键字为结构体类型Student取别名,示例代码如下:typedef struct Student int num; char name10; char sex;STU;STU stu1; 上面的语句定义了一个Student类型的结构体STU,STU stu1;语句等效于struct Student stu1;语句。需要注意的是,使用typedef关键字只是对已存在的类型取别名,而不是定义了新的类型。有时也可以用宏定义来代替typedef的功能,但是宏定

49、义是由预处理完成的,而typedef是在编译时完成的,使用typedef更加灵活。9.7 进阶案例求学生平均成绩学习完了结构体与共用体的相关知识,接下来通过一个计算平均成绩的案例来加深对结构体的理解,具体需求如下:l 一个小组中有3个学生,每个学生修4门课程(三个学生修的课程相同)l 在程序中输入这3个同学的4门课程成绩,程序能自动计算出这4门课程的小组平均成绩接下来用代码来实现上述功能,如例9-12所示。例9-12 1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<stdlib.h> 4

50、5 typedef struct stu 6 char name20; /学生姓名 7 float score4; /4门课成绩 8 STU; 9 10 void main() 11 12 int i, j; 13 float sum = 0, avg; 14 STU stu3; /定义一个结构体数组,数组中有3个元素 15 16 /从键盘输入学生姓名及成绩 17 for (i = 0; i < 3; i+) 18 19 printf("请输入第%d个学生的姓名及四门课成绩:n", i + 1); 20 scanf("%s", ); 21 for (j = 0; j < 4; j+) 22 scanf("%f", &stui.scorej); 23 24 25 /将3个学生的每科成绩相加,然后求平均成绩 26 for (j = 0; j < 4; j+) 27 28 for (i = 0; i < 3;

温馨提示

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

评论

0/150

提交评论