任务描述
实际问题中,经常需要对一些类型不同但又相互关联的数据进行处理。比如,对一个学生而言,他的学号(num)、姓名(name)、性别(sex)、年龄(age)、成绩(score)等数据都与该学生有联系。如果将num、name、sex、age、score 分别定义成相互独立的简单变量,则无法反映它们之间的内在联系;又因为这些数据彼此类型不同,而数组只能对同种类型的成批数据进行处理,所以,此时也无法使用数组。这就需要有一种新的数据类型,它能将具有内在联系的不同类型的数据组合成一个整体,在C语言里,这种数据类型就是“结构体”。
结构体属于构造数据类型,它由若干成员组成,成员的类型既可以是基本数据类型,也可以是构造数据类型,而且可以互不相同。由于不同问题需要定义的结构体中包含的成员可能互不相同,所以,C语言只提供定义结构体的一般方法,结构体中的具体成员由用户自己定义。这样,编程人员可以根据实际需要定义各种不同的结构体类型。
知识学习
(1)结构体的定义
结构体遵循“先定义后使用”的原则,其定义包含两个方面,一是定义结构体类型;二是定义该结构体类型的变量。
1)结构体类型的定义
功能:定义一种结构体类型。
例如,图8.1所示结构体类型可有如下定义:
图8.1 struct student 结构体类型组织结构图
说明:
①“结构体类型名”与“成员名”都遵循标识符命名规则。
②成员类型可以是除本身所属结构体类型外的任何已有数据类型。
③在同一作用域内,结构体类型名不能与其他变量名或结构体类型名重名。
④同一个结构体各成员不能重名,但允许成员名与程序中的变量名、函数名或者不同结构体类型中的成员名相同。
⑤结构体类型的作用域与普通变量的作用域相同:在函数内定义,则仅在函数内部起作用;在函数外定义,则有全局作用域。
⑥结构体类型定义的末尾必须有分号。
(2)结构体变量的定义、引用和初始化
1)结构体变量的定义
①先定义结构体类型,再定义结构体变量。如
②定义结构体类型的同时定义结构体变量。如
③直接定义结构体变量。如
说明:
①结构体类型与结构体变量是两个不同的概念。前者只声明结构体的组织形式,本身不占用存储空间;后者是某种结构体类型的具体实例,编译系统只有定义了结构体变量后才为其分配内存空间。
②结构体变量各成员存储在一片连续的内存单元中。
③可以用sizeof 测出某种基本类型数据或构造类型数据在内存中所占用的字节数,如printf("%d",sizeof(struct student));。
2)结构体变量的引用
①使用成员运算符引用结构体变量的成员。
格式:结构体变量名.成员名
功能:引用结构体变量中指定名称的成员变量,如
struct student stu1,stu2;
int age;
stu1.num=1001;
gets(stu1.name);
scanf("%d",&stu1.birthday.year);
age=2006 -stu1.birthday.year;
②使用指针运算符和成员运算符引用结构体变量的成员,如
struct student stu,*p=&stu;
(*p).num=10001;
scanf("%s",(*p).name);
scanf("%f",&(*p).score);
③使用指向运算符“->”引用结构体变量的成员,如(www.xing528.com)
struct student stu,*p=&stu;
p->num=10001;
scanf("%s", p->name);
scanf("%f",&p->score);
printf("age of %s is %d\n",stu.name,age);
④将结构体变量作为一个整体进行操作,如
struct student stu1,stu2,*p=&stu1;
stu2 =stu1;
printf("the address of struct student variable stu2 is %x",&stu2);
说明:
①“(*p).成员名”“p->成员名”与“stu.成员名”等价,不过后两种方式更直观。
②成员运算符“.”与指向运算符“->”的优先级相同,都高于指针运算符“*”。
③不能将结构体变量当作一个整体进行输入、输出或赋值,如
struct date date1,date2;
date1 ={1988,8,5};
scanf("%d%d%d",&date2);
printf("%d%d%d",date2);
3)结构体变量的初始化
在定义结构体变量的同时,按照所属结构体类型的组织形式依次写出全部或部分成员变量的初始值。如:
struct student stu1 ={1001,"Zhang San",'M',{1988,8,10},580};
struct student stu2 ={1002,"Li Ping",'F',1989,2,5,595};
struct student stu3 ={1002,"Li Ping",'F',1989};
说明:
①初始化前,结构体变量各成员的取值是随机的。
②花括号内初值的顺序、类型要与结构体成员的顺序和类型一致。
③初始化时,花括号内的数据不能包含变量。如以下程序片段的最后一行不正确:
(3)结构体变量程序举例
例8.1 输入一个学生的信息并显示。
注意:
若连续输入两个字符或者先输入一个字符串后输入一个字符,则输入第二个字符的控制符%c 前应加一个空格。如语句scanf(" %c",&stu.sex)中,格式控制符%c 之前的空格不能省略,否则,两次输入之间的分隔符将被作为第二个字符的输入加以处理。
例8.2 在函数input 中输入一个学生的信息,在函数list 中显示。
任务总结
结构体是由同种类型或者不同类型的数据成员所构成的一类构造数据类型。
①struct 是结构体关键字。
②结构体名是用户自定义。
③大括弧内的数据是结构体的成员。
④每个结构体成员必须由数据类型说明和结构体成员名组成。
⑤整个结构体类型声明结束后以“;”结尾。
⑥结构体类型的声明可以在程序中的任何地方。但是如果是在某个函数内部声明,其作用范围只能在函数内部起作用。如果从程序一开始处就声明,其作用范围是整个源文件。
⑦结构体要先声明再定义结构体变量。
⑧结构体变量的引用形式:结构体变量名.成员名。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。