8_1 结构体的概念和结构体变量
_1.1 结构体的概念
C语言中允许用户自己构造由不同数据类型的数据所组成的集合体,称为结构体。结构体属于数据类型,每一个结构体有一个名字,称为结构体名。一个结构体由若干成员(也称域)组成,每个成员的数据类型可以相同,也可不同。
_1.2 结构体类型的定义
struct <结构体类型名>
{
类型标识符 成员名1;
类型标识符 成员名2;
……
};
例:
struct student{ char number[10]; char name[20]; char sex; int age; float score1; float score2;};
注:末尾的“;”切记不丢失。
_1.3 结构体类型变量的定义
(1) 先定义结构体类型,再定义结构变量
struct student{ char number[10]; char name[20]; char sex; int age; float score1; float score2;};struct student s1, s2; /*定义student类型的结构体类型变量s1, s2*/
特点:可以将结构体类型的定义放到一个文件中(一般为.h头文件),如:#include<struct.h>
(2) 在定义结构类型的同时定义结构变量。
struct student{ char number[10]; char name[20]; char sex; int age; float score1; float score2;}s1, s2;
(3)不定义结构类型,直接定义结构变量。
struct{ char number[10]; char name[20]; char sex; int age; float score1; float score2;}s1, s2;
嵌套定义:
struct date { int month; int day; int year;};struct employee{ char name[10]; char sex[3]; int age; struct date birthday; char address[30]; char tel[12];}employee;
_1.4 结构体变量的引用
引用结构体成员方法如下:
结构体变量名.成员名
【例】:
s1.age=18;gets(s1.name);
_1.5 结构体变量的初始化
struct student{ char number[10]; char name[20]; char sex; int age; float score1; float score2;};struct student s1,s2={"1002","WangHua","M",19,86,89 };
【例8-1】分析以下代码
#includestruct curriculum{ char name[30]; float credit; float grade;};struct student{ char id[8]; char name[20]; struct curriculum course;}s1={"1003","LiHong","C",4,87};int main(){ struct student s2; printf("请输入s2的信息:\n"); printf("学号\t 姓名\t 课程名\t 学分\t 成绩\n"); scanf("%s\t%s\t%s\t%f\t%f",s2.id,s2.name,s2.course.name,&s2.course.credit,&s2.course.grade); printf("\n两名学生的信息如下:\n\n学号\t姓名\t课程名\t学分\t成绩\n"); printf("%s\t%s\ t%s\t%.lf\t.2f\n",s1.name,s1.course.name,s1.course.credit,s1.course.grade); printf("%s\t%s\t%s\t%.lf\t.2f\n",s2.name,s2.course.name,s2.course.credit,s2.course.grade); return 0;}
8.2 结构体数组
_2.1 结构体数组的定义
struct student{ char number[10]; char name[20]; char sex; int age; float score1; float score2;};struct student stu[50]; /*定义数组stu*/
_2.2 结构体的初始化
(1)在定义的时候赋初值
(2)定义完成后,用循环语句赋初值
_2.3 结构体数组举例
【8-2】 对候选人得票的统计程序
设有候选人3名,N名选民参加投票,选民投票输入候选人的姓名。投票结束后,输入候选人得票结果。
#include#include #define N 5struct condidate { char name[10]; int count;}person[3]={ {"LiMing",0},{"WangFeng",0}}; int main(){ int i,j,invalid=0; char name[10]; for (i=1;i<=N;i++) { printf("请输入候选人姓名:"); gets(name); for(j=0;j<3;j++) if (strcmp(name,person[j].name)==0) { person[j].count++; break; } if (j==3) invalid++; } printf("\n投票人数%d票,有效票%d票,无效票%d票。\n",N,N-invalid,invalid); printf("得票情况:\n"); for(i=0;i<3;i++) printf("%10s:%d票\n",person[i].name,person[i].count); return 0;}
8_3 结构体指针
_3.1 结构体指针与指向结构体变量的指针变量的概念
形式:struct 结构体名 *指针变量名 如:
struct student *p;
_3.2 用指向结构体变量的指针变量引用结构体变量的成员
【例8-3】分析以下代码及输出结果。
#include#include struct student { char number[10]; char name[20]; float score1; float score2;};void output (struct student x){ printf("number\tname\tscore1\tscore2\n"); printf("%s\t%s\t%.2f\t%.2f\n",x.number,x.name ,x.score1 ,x.score2);}int main(){ struct student s1={"1001","ZhaoMin",70,65}; struct student *p=&s1; printf("初始信息如下:\n"); output (*p); p->score1 =80.5; p->score2 =95; printf("\n修改后信息如下:\n"); output (s1); return 0;}
_3.3 用指向结构体变量的指针变量引用结构数组元素
【例8-4】分析以下代码及输出结果
_3.4 用指向结构体变量的指针变量作为函数参数
(1)结构体指针变量只能指向该结构体类型的变量,而不能指向结构体类型变量的成员。
(2)结构体数组名作函数实参是“地址传递”方式的函数调用。
(3)结构体变量作函数实参是“值传递”方式的函数调用。
(4)结构体指针变量作函数实参是“值传递”方式的函数调用,只不过传递的是一个地址值。
(5)注意理解和区别运算符“.”和“->”。“.”是成员运算符,它的左边应为结构体变量,而“->”是指向成员运算符,它的左边应为结构体指针。如:“p->score1”“*p.score1”以及“s1.score”三者是等价的。
_3.5 用指向结构体变量的指针变量处理链表
1. 链表的基本结构
链表中每一个节点的数据类型都是一个自引用结构体类型(同一类型的数据)。如:
struct node{ char Tel[20]; char Tel[12]; struct node *next ;};
2. 链表的基本操作
建立链表,链表的输出,在链表中插入、删除、查找或统计节点等。
8.4 枚举类型和共用体类型简介
_4.1 枚举类型
1. 枚举类型的定义
定义形式:enum 枚举类型名 { 枚举表;};
(1)定义枚举类型时,“枚举表”中每个枚举常量的名称必须是唯一的。
(2)枚举类型是用标识符表示的整型常量的集合,枚举常量是自动设置值的符号常量,起始值为0;如:
enum months {JAN ,FEB ,MAR ,APR ,MAY ,JUN ,JUL ,AUG ,SEP ,OCT ,NOV ,DEC};
其中,各枚举常量的值被依次自动设置为整数0~11。
(3)也可以采用在定义时指定常量初值,如:
enum months {JAN=1 ,FAB ,MAR ,APR ,MAY ,JUN ,AUG ,SEP ,OCT ,NOV ,DEC };
后面的值会自动自增,也可以在中间或其他位置指定不同的值。
(4)完成定义后,其值就不可更改了,但可以作为整型常量使用。
2. 枚举类型变量的定义
形式:enum 枚举类型名 枚举变量名列表;如:
enum weekday{sun,mon,tue,wed,thu,fri,sat};enum weekday week;
另:与结构体类似,可以在定义枚举类型时定义枚举变量,如:
enum weekday{sun,mon,tue,wed,thu,fri,sat}week;
也可以不声明枚举类型的名称,而直接定义该类型的枚举变量。如:
enum {sun,mon,tue,wed,thu,fri,sat}week;
3. 枚举变量的引用
【例8-16】分析以下代码及运行结果。
#includeint main(){ enum weekday {SUM,MON,TUE,WED,THU,FRL,SAT}; enum weekday date1,date2,date3; date1=SAT; date2=WED; date3=SUM; printf("date1=%d,date2=%d,date=%d\n",date1,date2,date3); return 0;}
_4.2 共用体类型
1 .共用体类型的定义:
union<共用体名>
{成员表列};
2. 共用体变量的定义
与结构体类型的定义相似;如:
(1)先定义共用体类型,再定义变量。
union data{ float v; Short int n; char c;};union data u1,u2;
(2)两者同时定义,如:
union data{ float v; Short int n; char c;}u1,u2;
(3)同时定义,省去共用体名,如:
union{ float v; Short int n; char c;}u1,u2;
注:该方法定义的共用体类型不能再用来定义另外的共用体类型变量。
3. 共用体变量的引用以及共用体类型数据的特点
只能逐个引用共用体变量的成员。
格式为:u1.v , u2 .n , u1.c
(1)系统采用覆盖技术,实现内存共享,所以在某一时刻存放的、起作用的是最后一次存入的成员值。
(2)共用体变量与其他各成员的地址相同。
【例8-8】分析以下代码及运行结果。
#includeunion u{ char u1; short u2;};int main(){ union u a={0x9741}; printf("1.%c %x\n",a.u1,a.u2); a.u1 ='a'; printf("2.%c %x\n",a.u1,a.u2); return 0;}