第十一章 结构体与共用体
11.1 结构体的定义与引用
1.定义结构体定义有n个成员的结构体类型的一般形式:
struct 结构体类型标识符
{ 类型标识符1 成员名1;
类型标识符2 成员名2;
….. …….
类型标识符n 成员名n;
}
例1:
要求定义关于学生通讯录的结构体类型struct_name1,其中包括以下数据:姓名(长度为10的字符数组)、性别(字符型)、地址(长度为20的数组)、电话(整型)
struct student {
char name[10];
char sex;
char addr[20];
int tel;
};
2,定义结构体类型变量
⑴ 定义变量的一般形式:
step1,定义好一个结构体类型后
step2,定义变量
struct 结构体类型标识符 变量名列表;
注:关键字struct 与结构体类型标识符一起使用。
Struct struct_name1 stu1,stu2;
⑵直接定义结构体变量:
struct student {
char name[10];
char sex;
char addr[20];
} stu1,stu2;
11.2结构体变量的使用
1,成员的引用形式为:
结构体变量名.成员名 //,称成员运算符
例1,定义两个变量 struct student stu1,stu2;
引用 strcpy(stu1.name,”李 红”);
stu1.sex=’M’;
strcpy(stu1.addr,”湛江师范学院”);
思考:是否可以写成student1.name=“宋 红”;
如何输出
2.结构体变量的初始化除了可以像上述那样为结构变量的成员一一赋值外,还可以在结构变量定义时对其进行初始化,
struct date
{
int month;
int day;
int year;
} stu1={10,22,89};
又如:
struct date stu2={1,25,88};
两个相类型的结构体变量可以互相赋值,stu2=stu1;
3.结构的嵌套
结构的成员可以是另一个结构.引用内层结构的成员时要包含两个结构变量的名字.
struct date
{
int month;
int day;
int year;
}
struct student {
char name[10];
char sex;
char addr[20];
date birthday;
}
struct student student1={“李 红”,’M’,”湛江师范学院”,{9,23,80}};
printf(“birthday is %d-%d-%d”,student1.birthday.month,
student1.birthday.day,student1.birthday.year)
11.3 结构体数组数组的每个元素是结构体类型.
Struct date birthday[3]={{1,3,1977},{12,23,199},{11,12,1980}};
Birthday[0].month=5;
Birthday[0].day=24;
Birthday[0].year=1988;
例2.设李红、王建和赵明三个同学某学年考了8门课,现在要求分别统计出这三名同学该学年的总成绩,并按8门课总成绩的高低排序输出。
struct name /* 定义结构体类型 */
{ char name[8]; /* 姓名 */
float score; /* 8门课总成绩 */
};
main()
{
int i,j;
float x;
struct name emp,stu[]={{“li hong”,0},{“wang”,0},{“zhao”,0}};
for (i=1; i<=8;i++)
{ printf(“\n输入第%d门课的成绩:\n”,i);
for (j=0;j<3;j++)
{ printf(“姓名:%s 成绩为:”,std[j].name);
scanf(“%f”,&x);
std[j].score = std[j].score +x;
}
}
for ( i=0; i<2; i++)
for ( j=i+1; j<3; j++)
if (std[i].score<std[j].score)
{ temp=std[j];
std[j]=std[i];
std[i]=temp;
}
/* 输出结果 */
for ( i=0; i<3; i++)
printf(,\n 姓名:%s 总成绩:%6.1f”,
std[i].name,std[i].score);
}
11.4指向结构体变量的指针
1.定义:
指向结构体指针的定义,与结构体变量的定义完全类似。
struct date
{
int month;
int day;
int year;
}
struct date *p,birthday;
2.引用,
指针引用结构体中的成员变量:
(*p).成员名
或 p->成员名 //更直观
struct date *p,birthday={4,22,199};
p=&birthday;
p->month=6;
p->day=9;
p->year=1988;
3,指向结构体数组的指针
struct date *p,birthday[3]={{4,22,1999},{6,23,1978},{9,23,1999}};
p=birthday;
思考:赋值语句
p=std+1;和p++;
代表指针p指向哪里?
11.5 结构与函数
结体变量可以象其他类型的变量一样作为参数传递给其它函数,或者从被调函数中将函数值返回调用处。
例3.有一个结构体变量stu,内含学生学号、姓名和3门成绩,要求在main函数中赋值,在另一printscore函数中将期打印出来
#include <string.h>
#define Format,%d\n%s\n%f\n%f\n%f\n”
Struct student
{ int num;
char name[20];
float score[3];
};
Main()
{
void printscore(struct student);
struct student stu;
Stu.num=1234;
strcpy(stu.name,”Li li”);
Stu.score[0]=67.5;
Stu.score[1]=89;
Stu.score[2]=78.9;
printscore(stu);
}
Void printscore(struct student stu)
{
printf(format,stu.num,stu.name,stu.score[0],stu.score[0],stu.score[0]);
}
11.6 链表
1.链表定义
所谓链表,是指一种动态的进行存储分配的一种数据结构。
2.链表的建立
(1) 定义节点的结构:
struct date
{
int month;
int day;
int year;
struct date *next;
}
(2) 创建一个空表.
Struct date *head;
Head=NULL;
(3) 向系统申请分配一个节点空间,建立表头。
malloc(size)函数,在内存的动态存储区中分配一个长度为size的连续空间。
Struct date *p1,*p2;
p2=(struct date *) malloc(siceof(struct date);
(4)将新接点的指针成员赋值为空,若是空表,将新接点连接到表头;若是非空表,将新节点接到表尾。
p2->month=9;p2->day=12;p2->year=1988;p2->next=NUlLL;
p1=p2;
head=p2;
p2=(struct date *) malloc(siceof(struct date);
p2->month=5;p2->day= 2;p2->year=1989;p2->next=NUlLL;
p1->next=p2;
p1=p2;
(5) 插入新接点,重复第(3)步。
3.链表的输出
p2=head;
while (p2!=NULL)
{ printf(,%d-%d-%d”,p2->month,p2->day,p2->year);
p2=p2->next;
}
4.增加结点分三种情况:
(1)在表头增加一个结点;
(2) 在两个结点之间增加一个结点
(3)在链表最后增加一个节点。
5,结点的删除
(1) p1指向要删除结点的前一结点1
(2) p2指向要删除的结点(p2=p1->next )
(3) 将p2指向的结点从链表中删除(p1->next=p2->next)
(4) 调用free(p2)释放删除结点所指向的内存空间。
11.7 共用体所谓“共用体”类型,是指使几个不同的变量共同占用同一段内存的数据类型。
1.共用体的定义
(1)直接定义共用体变量,其一般形式为:
union
{
类型标识符1 成员名1;
类型标识符2 成员名2;
……. …….
类型标识符n 成员名n;
} 变量名表;
(2)先定义共用体类型标识符,再定义变量。
一般形式为:
union 共用体类型标识符
{
类型标识符1 成员名1;
类型标识符2 成员名2;
…… …….
类型标识符n 成员名n;
};
union 共用体类型标识符 变量名表;
2.共用体变量的引用
共用体变量.成员名
例如:定义了如下的共用体
变量
union var_type
{
int i;
float x;
char c;
}comm;
引用情况举例:
comm.i = 5;
comm.x =5.5;
comm.c=‘a’;
printf(“%c”,comm.c);
可以在定义其他数据类型中使用共用体类型。
struct student
{ int num;
char name[10];
char sex;
char job;
union
{ int class
char position[10];
}category;
} person[10];
引用方法:
Person[i].num=1234;
Strcpy(Person[i].name,”lili”);
Person[i].category.class=12;
Printf(“%s”,Person[i].category.position);
head p2
9
12
1988
XXX
5
2
1989
NULL
11.1 结构体的定义与引用
1.定义结构体定义有n个成员的结构体类型的一般形式:
struct 结构体类型标识符
{ 类型标识符1 成员名1;
类型标识符2 成员名2;
….. …….
类型标识符n 成员名n;
}
例1:
要求定义关于学生通讯录的结构体类型struct_name1,其中包括以下数据:姓名(长度为10的字符数组)、性别(字符型)、地址(长度为20的数组)、电话(整型)
struct student {
char name[10];
char sex;
char addr[20];
int tel;
};
2,定义结构体类型变量
⑴ 定义变量的一般形式:
step1,定义好一个结构体类型后
step2,定义变量
struct 结构体类型标识符 变量名列表;
注:关键字struct 与结构体类型标识符一起使用。
Struct struct_name1 stu1,stu2;
⑵直接定义结构体变量:
struct student {
char name[10];
char sex;
char addr[20];
} stu1,stu2;
11.2结构体变量的使用
1,成员的引用形式为:
结构体变量名.成员名 //,称成员运算符
例1,定义两个变量 struct student stu1,stu2;
引用 strcpy(stu1.name,”李 红”);
stu1.sex=’M’;
strcpy(stu1.addr,”湛江师范学院”);
思考:是否可以写成student1.name=“宋 红”;
如何输出
2.结构体变量的初始化除了可以像上述那样为结构变量的成员一一赋值外,还可以在结构变量定义时对其进行初始化,
struct date
{
int month;
int day;
int year;
} stu1={10,22,89};
又如:
struct date stu2={1,25,88};
两个相类型的结构体变量可以互相赋值,stu2=stu1;
3.结构的嵌套
结构的成员可以是另一个结构.引用内层结构的成员时要包含两个结构变量的名字.
struct date
{
int month;
int day;
int year;
}
struct student {
char name[10];
char sex;
char addr[20];
date birthday;
}
struct student student1={“李 红”,’M’,”湛江师范学院”,{9,23,80}};
printf(“birthday is %d-%d-%d”,student1.birthday.month,
student1.birthday.day,student1.birthday.year)
11.3 结构体数组数组的每个元素是结构体类型.
Struct date birthday[3]={{1,3,1977},{12,23,199},{11,12,1980}};
Birthday[0].month=5;
Birthday[0].day=24;
Birthday[0].year=1988;
例2.设李红、王建和赵明三个同学某学年考了8门课,现在要求分别统计出这三名同学该学年的总成绩,并按8门课总成绩的高低排序输出。
struct name /* 定义结构体类型 */
{ char name[8]; /* 姓名 */
float score; /* 8门课总成绩 */
};
main()
{
int i,j;
float x;
struct name emp,stu[]={{“li hong”,0},{“wang”,0},{“zhao”,0}};
for (i=1; i<=8;i++)
{ printf(“\n输入第%d门课的成绩:\n”,i);
for (j=0;j<3;j++)
{ printf(“姓名:%s 成绩为:”,std[j].name);
scanf(“%f”,&x);
std[j].score = std[j].score +x;
}
}
for ( i=0; i<2; i++)
for ( j=i+1; j<3; j++)
if (std[i].score<std[j].score)
{ temp=std[j];
std[j]=std[i];
std[i]=temp;
}
/* 输出结果 */
for ( i=0; i<3; i++)
printf(,\n 姓名:%s 总成绩:%6.1f”,
std[i].name,std[i].score);
}
11.4指向结构体变量的指针
1.定义:
指向结构体指针的定义,与结构体变量的定义完全类似。
struct date
{
int month;
int day;
int year;
}
struct date *p,birthday;
2.引用,
指针引用结构体中的成员变量:
(*p).成员名
或 p->成员名 //更直观
struct date *p,birthday={4,22,199};
p=&birthday;
p->month=6;
p->day=9;
p->year=1988;
3,指向结构体数组的指针
struct date *p,birthday[3]={{4,22,1999},{6,23,1978},{9,23,1999}};
p=birthday;
思考:赋值语句
p=std+1;和p++;
代表指针p指向哪里?
11.5 结构与函数
结体变量可以象其他类型的变量一样作为参数传递给其它函数,或者从被调函数中将函数值返回调用处。
例3.有一个结构体变量stu,内含学生学号、姓名和3门成绩,要求在main函数中赋值,在另一printscore函数中将期打印出来
#include <string.h>
#define Format,%d\n%s\n%f\n%f\n%f\n”
Struct student
{ int num;
char name[20];
float score[3];
};
Main()
{
void printscore(struct student);
struct student stu;
Stu.num=1234;
strcpy(stu.name,”Li li”);
Stu.score[0]=67.5;
Stu.score[1]=89;
Stu.score[2]=78.9;
printscore(stu);
}
Void printscore(struct student stu)
{
printf(format,stu.num,stu.name,stu.score[0],stu.score[0],stu.score[0]);
}
11.6 链表
1.链表定义
所谓链表,是指一种动态的进行存储分配的一种数据结构。
2.链表的建立
(1) 定义节点的结构:
struct date
{
int month;
int day;
int year;
struct date *next;
}
(2) 创建一个空表.
Struct date *head;
Head=NULL;
(3) 向系统申请分配一个节点空间,建立表头。
malloc(size)函数,在内存的动态存储区中分配一个长度为size的连续空间。
Struct date *p1,*p2;
p2=(struct date *) malloc(siceof(struct date);
(4)将新接点的指针成员赋值为空,若是空表,将新接点连接到表头;若是非空表,将新节点接到表尾。
p2->month=9;p2->day=12;p2->year=1988;p2->next=NUlLL;
p1=p2;
head=p2;
p2=(struct date *) malloc(siceof(struct date);
p2->month=5;p2->day= 2;p2->year=1989;p2->next=NUlLL;
p1->next=p2;
p1=p2;
(5) 插入新接点,重复第(3)步。
3.链表的输出
p2=head;
while (p2!=NULL)
{ printf(,%d-%d-%d”,p2->month,p2->day,p2->year);
p2=p2->next;
}
4.增加结点分三种情况:
(1)在表头增加一个结点;
(2) 在两个结点之间增加一个结点
(3)在链表最后增加一个节点。
5,结点的删除
(1) p1指向要删除结点的前一结点1
(2) p2指向要删除的结点(p2=p1->next )
(3) 将p2指向的结点从链表中删除(p1->next=p2->next)
(4) 调用free(p2)释放删除结点所指向的内存空间。
11.7 共用体所谓“共用体”类型,是指使几个不同的变量共同占用同一段内存的数据类型。
1.共用体的定义
(1)直接定义共用体变量,其一般形式为:
union
{
类型标识符1 成员名1;
类型标识符2 成员名2;
……. …….
类型标识符n 成员名n;
} 变量名表;
(2)先定义共用体类型标识符,再定义变量。
一般形式为:
union 共用体类型标识符
{
类型标识符1 成员名1;
类型标识符2 成员名2;
…… …….
类型标识符n 成员名n;
};
union 共用体类型标识符 变量名表;
2.共用体变量的引用
共用体变量.成员名
例如:定义了如下的共用体
变量
union var_type
{
int i;
float x;
char c;
}comm;
引用情况举例:
comm.i = 5;
comm.x =5.5;
comm.c=‘a’;
printf(“%c”,comm.c);
可以在定义其他数据类型中使用共用体类型。
struct student
{ int num;
char name[10];
char sex;
char job;
union
{ int class
char position[10];
}category;
} person[10];
引用方法:
Person[i].num=1234;
Strcpy(Person[i].name,”lili”);
Person[i].category.class=12;
Printf(“%s”,Person[i].category.position);
head p2
9
12
1988
XXX
5
2
1989
NULL