? 5.1 结构体
5.2 共用体
5.3 枚举类型第五章 复杂构造数据类型
5.1 结构体
5.1 结构体的引出及使用
特点:数据与数据之间有关联,是一个整体。
职工编号 姓名 性别 民族 出生日期 职称 学历 单位 工龄
1997025 孙杰 男 汉 1974.9 讲师 大学 信息 9
学生信息:学号,姓名,性别,年龄,入学成绩,所属学院等信息。
如,0501,李明,男,19,610,信息
5.1.1 结构体的引出及使用如何表示这样的数据信息?
由一些逻辑相关,但数据类型不同的分量 组成的一组数据,定义为 结构体。
学号 姓名 性别 年龄 入学成绩 所属学院
int num char name[10] char sex int age int score char institute[20]
一、结构体的引出学生信息:学号,姓名,性别,年龄,入学成绩,所属学院等信息。
如,0501,李明,男,19,610,信息
5.1.1 结构体的引出及使用例 5-1 输入三个学生的信息,并输出。
#include <stdio.h>
void main( )
{ struct student
{ int num ;
char name[10] ;
char sex;
int age;
int score ;
char institute[20]
};
struct student s1,s2,s3;
定义学生的结构体类型定义 3个结构体类型的变量,
用来存放 3个学生的信息
5.1.1 结构体的引出及使用
void main( )
{,
scanf(“%c %d %d %d”,&s1.sex,&s1.num,&s1.age,&s1.score);
gets(s1.name);
gets(s1.institute);
scanf(“%c %d %d %d”,&s2.sex,&s2.num,&s2.age,&s2.score);
gets(s2.name); gets(s2.institute);
scanf(“%c %d %d %d”,&s3.sex,&s3.num,&s3.age,&s3.score);
gets(s3.name); gets(s3.institute);
输入一个学生的信息
printf(“%6d %10s %2c %3d,,s1.num,s1.name,s1.sex,s1.age);
printf(“%5d %20s \n”,s1.score,s1.institue);
printf(“%6d %10s %2c %3d,,s2.num,s2.name,s2.sex,s2.age);
printf(“%5d %20s \n”,s2.score,s2.institue);
printf(“%6d %10s %2c %3d,,s3.num,s3.name,s3.sex,s3.age);
printf(“%5d %20s \n”,s3.score,s3.institue);
}
输出学生信息
struct student
{ int num ;
char name[10] ;
char sex;
int age;
int score ;
char institute[20]
};
二、结构体的定义及使用
5.1.1 结构体的引出及使用注意,定义了结构体类型,仅仅是定义了数据的组织形式,创立了一种 数据类型 。但并不会为这种结构体类型分配内存空间只有定义了结构体变量,才会为变量分配空间。
注意不要忘了分号成员表列
1、结构体类型的定义,
struct 结构体类型名
{ 数据类型 成员名 1;
数据类型 成员名 2;
:,
数据类型 成员名 n;
} ;
关键字用户定义的标识符
5.1.1 结构体的引出及使用
2,定义结构体变量的方法
(1) 先定义结构体类型,再定义变量
struct student
{ char name[10] ;
int age ;
int s1,s2 ;
} ;
struct student st1,st2 ;
st1
st2
name
age
s1
s2
name
age
s1
s2
内存中结构体变量占有一片连续的存储单元,其占用的字节数可用 sizeof 运算符 算出,
printf(“%d\n”,sizeof(struct student) ) ;
printf(“%d\n”,sizeof(st1) ) ;
结构体变量 st1和 st2各自都需要 16个字节的存储空间结构体类型定义结构体变量定义
5.1.1 结构体的引出及使用
2,定义结构体变量的方法
(2) 定义结构体类型同时定义变量
struct student
{ char name[10] ;
int age ;
int s1,s2 ;
} st1,st2 ;
(3) 直接定义结构体变量
struct
{ char name[10] ;
int age ;
int s1,s2 ;
} st1,st2 ;
注意,这里没有结构体类型名这种方式有时使用并不方便因此不建议大家采用定义结构体变量
5.1.1 结构体的引出及使用例,struct date
{ int year ;
int month ;
int day ;
} ;
struct stud
{ char name[10] ;
struct date birthday ;
int s1,s2 ;
} ;
结构体类型可以嵌套定义或,struct stud
{ char name[10] ;
struct date
{ int year ;
int month ;
int day ;
} birthday ;
int s1,s2 ;
} ;
5.1.1 结构体的引出及使用
3、结构体变量的引用格式,结构体变量名,成员名
struct student
{ char name[10] ;
int age ;
int s1,s2 ;
} ;
struct student st1 ;
strcpy(st1,name,“Mary” );
st1,age = 21 ;
st1,s1 = 78 ;
st1,s2 = 86 ;
说明:
(1) 一般情况下都是对结构体变量的成员进行赋值和输入 \输出
(2) 特殊情况下结构体变量可以进行整体赋值
(3) 可以引用结构体变量的地址和其成员的地址
struct date
{ int year ;
int month ;
int day ;
} ;
struct stud
{ char name[10] ;
int age ;
struct date birthday;
int s1,s2 ;
} ;
struct stud st2 ;
int age,year ;
strcpy(st2,name,“John”) ;
st2,age = 20 ;
st2,birthday,year = 1980 ;
st2,birthday,month = 11 ;
st2,birthday,day = 23 ;
st2,s1 = 89 ;
st2,s2 = 95 ;
age = 24 ;
year = 2000 ;
可以定义与结构体成员名相同名字的变量,它们之间不会发生混乱
相同类型的结构体变量可以进行 整体赋值
struct date
{ int year ;
int month ;
int day ;
} ;
struct stud
{ char name[10] ;
int age ;
struct date birthday;
int s1,s2 ;
} ;
struct stud st1,st2,st3;
strcpy(st1,name,“John”) ;
st1,age = 20 ;
st1,birthday.year = 1980 ;
st1,birthday.month = 11 ;
st1,birthday.day = 23 ;
st1,s1 = 89 ;
st1,s2 = 95 ;
st2=st1;
strcpy(st3,name,“Mary”);
st3,age=20;
st3,birthday=st1,birthday;
st3,s1 = 76;
st3,s2 = 85;
注意要正确赋值的条件是变量 st1已经有了数据
5.1.1 结构体的引出及使用
5.1.1 结构体的引出及使用
4、结构体变量的初始化
struct student
{ char name[10] ;
int age ;
int s1,s2 ;
} st1={“Mary”,21,78,86} ;
struct stud
{ char name[10] ;
struct date birthday ;
int s1,s2 ;
} ;
struct stud st2={,John”,1980,11,23,89,95 } ;
struct student
{ char name[10] ;
int age ;
int s1,s2 ;
} ;
struct student st1;
st1={“Mary”,21,78,86} ;初始化,正确错误。 C不允许这么做!
为什么?
初始化,正确
5,结构体变量的输入 输出
C语言不允许结构体变量整体进行输入和输出,
只能对结构体变量的成员进行输入和输出
gets( st1,name ) ;
scanf(,%d%d%d”,&st1,birthday,year,
&st1,birthday,month,&st1,birthday,day ) ;
scanf (,%d%d%d”,&st1,age,&st1,s1,&st1,s2 ) ;
puts( s1,name ) ;
printf(,%4d”,st1,age );
printf(,%d,%d,%d”,st1,birthday,year,
st1,birthday,month,st1,birthday,day ) ;
printf(“%4d %4d\n”,st1,s1,st1,s2 ) ;
5.1.1 结构体的引出及使用
5.1.2 结构体数组的引出及引用学号 姓名 性别 年龄 入学成绩 所属学院
0501 李明 男 19 610 信息
0502 张莉 女 19 595 信息
0503 王涛 男 20 580 控制一、结构体数组的引出一个结构体变量只能存放一个学生的信息,对于多个学生的信息,可以使用一个结构体数组来存放,
结构体数组的每个元素是一个结构体类型的变量。
定义结构体数组的方法,
结构体类型 数组名 [数组的长度 ];
5.1.2 结构体数组的引出及引用例 5-2 输入 30个学生的信息,并输出
#include <stdio.h>
void main( )
{ struct student
{ int num ;
char name[10] ;
char sex;
int age;
int score ;
char institute[20]
};
struct student s[30];
int i;
for (i=0;i<30;i++)
{ scanf(“%c %d %d %d”,&s[i].sex,
&s[i].num,&s[i].age,&s[i].score);
gets(s[i].name);
gets(s[i].institute);
}
for (i=0;i<30;i++)
{ printf(“%6d %10s %2c %3d,,s[i].num,
s[i].name,s[i].sex,s[i].age);
printf(“%5d %20s\n”,
s[i].score,s[i].institue);
}
}
5.1.2 结构体数组的引出及引用二、结构体数组的定义及使用
1、定义结构体数组
(1) 先定义结构体类型再定义结构体数组
struct student
{ char name[10] ;
int age ;
int s1,s2 ;
} ;
struct student st[6] ;
(2) 定义结构体类型的同时定义结构体数组
struct student
{ char name[10] ;
int age ;
int s1,s2 ;
} st[6] ;
(3) 直接定义结构体数组
struct
{ char name[10] ;
int age ;
int s1,s2 ;
} st[6] ;
不提倡使用该方法
5.1.2 结构体数组的引出及引用
2、结构体数组的初始化将每个数组元素的数据用花括号 { } 括起来
struct student
{ char name[10] ;
int age ;
int s1,s2 ;
} ;
struct student st[3]={ {“Mary”,21,78,86},
{“Alex”,20,90,80},{“Mike”,19,75,68} };
Mary
21
78
86
Alex
20
90
80
Mike
19
75
68
st[0]
st[1]
st[2]
5.1.2 结构体数组的引出及引用
(2) 数组元素之间可以整体赋值也可以将一个元素赋给一个相同类型的结构体变量
struct student st[3]={ {“Mary”,21,78,86},{“Alex”,…} } ;
struct student x ;
st[2] = st[0] ;
x = st[1] ; 都是结构体变量的整体赋值形式
3,结构体数组的引用
(1) 引用某个数组元素的成员例,puts( st[0],name ) ;
printf(“%d,%d”,st[1],age,st[1],s1 ) ;
(3)输入和输出操作只能对数组元素的 成员 进行分析,
假设有 3个候选人,共有 100个人投票定义一个结构体数组,它有 3个元素代表
3个候选人,每个元素有 2个成员,一个是候选人名字,一个是得票数 (初始时为 0)
例 5-3 设计一个对候选人得票进行统计的程序候选人 票数
li 0
zhao 0
ma 0
有 100张选票,输入选票上的名字,然后判断是谁的名字,就将谁的票数加 1,重复 100次最后输出结构体数组
5.1.3 结构体程序举例例 4-22 程序代码#include<stdio.h>
#include <string.h>
struct person
{ char name[10];
int count;
};
void main( )
{ struct person cand[3]={{“Li”,0},{“Zhao”,0},{“Ma”,0}};
int i,j; char cname[20];
for(i=0; i<100; i++)
{ scanf(“%s”,cname);
for(j=0; j<3; j++)
if( strcmp(cname,cand[j].name)= =0) cand[j].count++;
}
for(i=0; i<3; i++)
printf(“%10s,%d\n”,cand[i].name,cand[i].count);
}
定义候选人的结构体类型对结构体数组进行初始化
//输入选票上的名字
//若有 100人投票,则循环 100次
//将选票上的名字依次和候选人的名字比较
//选票上名字和某个候选人名字相同时,其票数加 1
5.1.3 结构体程序举例例 5-4 按成绩对学生信息进行从高到底的排序
#include <stdio.h>
#define N 30
struct stud
{ int n ;
char name[10] ;
int s ;
};
void input(struct stud a[ ])
{ int i ;
for ( i=0 ; i<N ; i++)
scanf(“%d %s %d”,&a[i].n,a[i].name,&a[i].s) ;
}
void output(struct stud a[ ])
{ int i ;
for ( i=0 ; i<N ; i++)
printf(“%4d %10s %4d”,a[i].n,a[i].name,a[i].s) ;
}
注意 a[i].name前不加 &,因
name是数组名,因用 %s,
输入时名字不能加空格
5.1.3 结构体程序举例
void sort(struct stud a[ ] )
{ int i,j ;
struct stud temp;
for ( i=0 ; i<N-1 ; i++)
for ( j=i+1 ; j<N ; j++)
if ( a[i].s<a[j].s )
{ temp=a[i] ; a[i]=a[j] ; a[j]=temp ; }
}
void main( )
{ struct stud st[N];
input(st);
sort(st);
output(st);
}
注意进行比较的是元素 a[i]
和 a[j]的成绩成员 s,但进行交换的是元素 a[i]和 a[j]
5.1.4 结构体与指针一,指向结构体变量的指针
1,定义
struct student
{ char name[20] ;
int age ;
int s1,s2 ;
} ;
struct student stu,*p ;
p = &stu ;
2,成员的引用格式
(1) 结构体变量名,成员名
stu,name
gets( stu,name );
(*p),age = 21 ;
p -> s1 = 87 ;
p -> s2 = 90 ;
(2) (*指针变量名 ),成员名
(*p),age
(3) 指针变量名 -> 成员名
p -> s1
5.1.4 结构体与指针二,指向结构体数组的指针
1,定义 struct student a[3],*p ;
2,使用 for ( p=a ; p<a+3 ; p++ )
{ gets( p->name ) ;
scanf(,%d%d%d”,&p->age,&p->s1,&p->s2); }
三,结构体变量作为函数参数
1,函数实参和形参都用结构体变量,参数之间为 值传递实参结构体变量 各成员的值依次传给 形参结构体变量
2,返回结构体类型值的函数定义格式,结构体类型名 函数名 ( 形参表 )
{ 函数体 ; }
例,struct student funct ( int x,float y )
{ 函数体 ; }
注意 结构体类型是已经定义好的
5.1.4 结构体与指针
#include <stdio.h>
#define N 5
struct stud
{ char name[10] ;
int s[3] ;
int sum,ave ;
} ;
struct stud count (struct stud x)
{ int i ;
x.sum = 0 ;
for ( i = 0; i<3 ; i++ )
x.sum = x.sum + x.s[i] ;
x.ave = x.sum / 3 ;
return(x);
}
例 5-5,求学生成绩的总分和平均分 (结构体变量作参数 )
//定义学生的结构体类型
//计算学生三门课的总分
//返回学生的全部信息
//结构体变量作参数返回结构体类型的值
5.1.4 结构体与指针
void main ( )
{ struct stud a[N] ;
int j ;
for ( j=0; j<N; j++ )
scanf(“%s%d%d%d,,a[j].name,&a[j].s[0],
&a[j].s[1],&a[j].s[2] );
for ( j=0; j<N; j++)
a[j]=count ( a[j] ) ;
for ( j=0; j<N; j++)
printf(“%10s%4d%4d%4d%6d%4d\n”,a[j].name,
a[j].s[0],a[j].s[1],a[j].s[2],a[j].sum,a[j].ave );
}
//函数调用,将 a[j]的值传给 count函数的参数 x,并将返回值赋给 a[j]
//输入 N个学生的信息
//定义结构体数组 a,存放 N个学生的信息