第9章 结构体和共用体
9.1 结构体
【学习目标】
(1)掌握结构体的类型定义方法
(2)掌握定义的结构体类型变量和指针变量的引用方法
(3)掌握结构体类型数组的定义及数组元素的引用
实例45 结构体类型变量、指针变量的定义与引用——我的个人信息
【实例任务】
定义一个结构体类型,然后定义两个自定义结构体类型的变量,通过引用这两个变量输出个人信息。程序的运行结果如图9-1所示。
图9-1 程序运行结果
【程序代码】
#include "stdio.h" main() { typedef struct {int num; char *name; char sex; float score; }STU; STU girl1, girl2,*girl3; /*定义结构体类型*/ girl1.num=102; girl1.name="lihong"; printf("请输入性别和成绩:"); scanf("%c%f",&girl1.sex,&girl1.score); girl2=girl1; /*可以为结构体类型的变量整体赋值*/ girl3=&girl1; /*可以让结构体类型的变量指向结构体类型的变量*/ printf("输出我的学号、姓名、性别、成绩的个人信息为:\n"); printf("%10d%10s %c %.2f",girl2.num,girl2.name,girl2.sex,girl2.score); printf("\n通过指针变量输出我的学号、姓名、性别、成绩的个人信息为:\n"); printf("%10d%10s %c %.2f",girl3->num,girl3->name,(*girl3).sex,(*girl3).score); } |
【相关知识】
1.结构体类型的定义
前面学过众多的类型定义符,它们的共同特点定义的变量在内存中的空间大小都是固定的。现实生活和工作中,这种单一表现有很大的局限性,结构体类型是在应用原有类型的基础上,用户构造的一种类型,其成员丰富,引用时可以整体引用。以前学过的数组在定义后所有数组元素都属同一类型,而本章所学结构体各个成员可以是不同类型。它的定义形式为:
struct 结构体标识符
{ 类型名 成员变量名1;
类型名 成员变量名2;
………
类型名 成员变量名n;}
这里,struct是定义结构体类型的关键字,结构体标识符要求是合法的C语言标识符。实例中,定义了一个记录个人信息的结构体,有num、name、sex、score这4个成员。
2.结构体类型的变量和指针变量的定义
结构体类型的变量定义方法有多种。可以在定义结构体的同时定义结构体类型的变量;也可以先定义结构体类型,然后再定义相应的变量;也可以通过typedef关键字先为定义的结构体类型命个新名字,再用新名字定义结构类型的变量。
对于结构体类型的变量,定义时在内存空间中为其分配存储空间,分配时按先后顺序连续分配,所占空间总的大小为所有成员所占空间大小的和值。
实例中,是在定义的同时,为结构体类型命个新名字STU,然后用新名字直接定义结构体类型的变量和指针变量,这样多次定义时比较简洁。
struct stu
{int num;
char *name;
char sex;
float score;
}s,*p;
以上程序段是在定义结构体类型的同时定义结构体类型的变量
struct stu
{int num;
char *name;
char sex;
float score; };
struct stu s,*p;
以上程序段是先定义好结构体类型,然后再单成立一条语句定义结构体类型的变量。
struct stu
{int num;
char *name;
struct date
{ int year;
int month;
int day;}birthday;
char sex;
float score;
}s,*p;
以上程序段是结构体类型的嵌套定义,引用时分层引用,不可越层。
struct stu
{ int num;
char *name;
char sex;
float score;
}s={101,"lihong",'F',95.5},*p;
以上程序段是在定义结构体类型变量的同时对变量进行了初始化。
结构体类型定义时,可以用关键字typedef为定义的结构体类型变量新命一个名字,然后可以用这个新名字来定义结构类型的变量。如实例中的如下定义形式
typedef struct
{int num;
char *name;
char sex;
float score;
}STU;
STU girl1, girl2,*girl3; /*定义结构体类型变量*/
typedef还可以为其他类型起个别名,如int、char等,均可以为之起别名。如:
typedef char NAME[10];
NAME p1,p2;
相当于如下定义:
char p1[10],p2[10];
3.结构体成员的引用
结构体成员的引用与数组元素的引用相似,对各个成员要分别引用。结构体成员引用的运算符有“*”和“->”,引用形式如下:
结构体变量名.结构体成员
结构体变量指针->结构体成员
(*结构体变量指针).结构体成员
实例中,相对应的表达式有:
girl2.num
girl3->num
(*girl3).sex
实例46 结构体类型的数组的定义与引用——成绩统计
【实例任务】
嵌套定义一个结构体,定义一个结构类型的变量并赋初值,编程输出学生的信息并输出每位同学的平均成绩和总成绩。程序运行结果如图9-2所示。
图9-2 程序运行结果
【程序代码】
#include "stdio.h" struct birthday {int year; int month; int day;}; struct student { char name[10]; struct birthday date; int chinese; int math; int english; int ave; int count; }stu[5]={ {"李一",1980,5,12,69,82,91}, {"李二",1981,6,26,73,68,81}, {"李三",1980,12,7,88,81,75}, {"李四",1981,7,30,77,95,61}, {"李五",1980,1,22,96,71,64}}; /*嵌套定义结构体类型,定义结构体类型数组的同时进行初始化*/ main() { char *p[10]={"姓名","出生年月","语文","数学","英语","平均分","总分"}; int i; for(i=0;i<5;i++)< span=""> {stu[i].count=stu[i].chinese+stu[i].math+stu[i].english; stu[i].ave=(stu[i].count)/3; } printf("五名同学的成绩表:\n"); for(i=0;i<7;i++)< span=""> printf("%-12s",p[i]); for(i=0;i<5;i++)< span=""> printf("\n%-12s%-4d-%-2d-%-6d%-12d%-12d%-12d%-12d%-12d",stu[i].name,stu[i].date.year,stu[i].date.month,stu[i].date.day,stu[i].chinese,stu[i].math,stu[i].english,stu[i].ave,stu[i].count); } |
【相关知识】
1.结构体类型数组的定义
结构体类型一旦定义好后,就可以和C语言固有类型一样定义数组,只是每个数组元素都是该结构体类型。
实例中,在定义结构体类型student的同时定义结构体类型的数组,并为每个数组元素赋初值。每个数组元素都是结构体类型,赋值时按各成员的顺序依次赋值。且每个数组元素的值用{}括起来。
当定义的结构体类型的二维数组时,要分行赋值,详见实例中为stu[5]数组的赋值过程。
2.结构体类型数组元素的引用
结构体类型数组元素引用时,要指明引用哪个数组元素的哪个成员,如表达式stu[i].count就是引用数组元素stu[i]的count成员。
当结构体类型数组元素为结构体类型指针变量赋值时,可以直接取该数组元素的地址,让该指针变量指向该数组元素,则可以通过指针变量引用数组元素的各个成员。