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
(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】分析以下代码
#include
struct 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 5
struct 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】分析以下代码及运行结果。
#include
int 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】分析以下代码及运行结果。
#include
union 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;
}
来源:oschina
链接:https://my.oschina.net/u/2968148/blog/782304