




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
8结构与联合主要内容:结构类型与结构变量结构指针结构数组结构与函数联合与位段主要内容:结构类型与结构变量结构指针结构数组结构与函数联合与位段1-1结构类型利用变量只能处理单个数据利用数组可以处理多个同类型的数据–通过结构类型将不同类型数据组合成一个有机的整体10001
ZhangsanBeijingIDnameintchar
[
]M
18char
intchar
[
]87.5sex
age
addr
scorefloat1-1结构类型结构类型是一种将不同数据类型的变量说明(称为结构类型的成员)组织起来所形成的一种新的构造类型struct
student{int
num;char
name
[20];char
sex;int
age;
char
addr[30];float
score;};#include
<stdio.h>struct
student{3.
int
num;charname
[20];4.
char
sex;intage;5.
char
addr[30];floatscore;6.
};7.
void
main(void){8.
int
i;struct
student
cs[5]
=
{{1,
"Zhao",
"F",
20,
"D1-401",
86.5},{2,
"Qian",
"M",
19,
"D8-201",
79},{3,
"Sun",
"M",
19,
"D8-201",
98},{4,
"Li",
"F",
19,
"D1-401",
89},{5,
"Zhou",
"M",20,
"D8-201",
50}};for(i
=
0;
i
<
5;
i++)9.10.11.12.13.14.15.printf("%d\t%s\t%c\t%d\t%s\t%f\n",
cs[i].num,
cs[i].name,
cs[i].sex,cs[i].addr,
cs[i].score);16.
}1-1结构类型结构类型的使用包含两个阶段:
设计结构类型:在程序设计中,要先确定结构类型的所有成员通过定义结构类型将这些成员组织起来,形成新的数据类型使用结构类型:通过结构类型来声明对应的结构变量、结构指针、或结构数组对结构变量、结构指针、或结构数组中成员的操作最终完成所需要解决的计算任务1-1结构类型结构类型的声明:struct结构类型名{成员声明表};
成员列表包含结构体的所有成员的声明成员声明形式:类型名成员名;类型名可以是除本结构类型以外的其他任何类型struct
student{int
num;char
name
[20];char
sex;int
age;
char
addr[30];float
score;};1-1结构类型同一结构内的成员不能同名,但成员可以与结构外部的变量同名,也可以与其他结构的成员同名char
name[20];struct
student{int
num;char
name
[20];char
addr[30];};struct
teacher{int
num;char
name
[20];char
addr[30];};1-1结构类型注意:
结构类型声明用于创建用户自定义数据类型,不进行存储分配sizeof(struct
student)的值?1-2结构类型的命名用typedef可以为一个已知的结构类型命名typedef
struct
point
{int
x;int
y;}
point;将结构类型struct
point命名为pointpoint
u,v;与struct
point
u,v;等价1-2结构类型的命名用typedef也可以为一个匿名结构类型进行命名typedef
struct
{int
x;int
y;}
point;将匿名结构类型命名为pointpoint
u,
v;1-3结构类型的嵌套结构成员也可以是其他结构,形成结构的嵌套struct
student{int
num;char
name
[20];struct
date{int
year;int
month;int
day;}birthday;char
addr[30];};struct
date{int
year;int
month;int
day;}struct
student{int
num;char
name
[20];struct
date
birthday;char
addr[30];};1-4结构变量的声明数据类型为结构类型的变量简称为结构变量或结构结构变量的声明有两种方式:先声明结构类型,再声明结构变量在声明结构类型的同时声明结构变量1-4结构变量的声明(1)结构类型和结构变量分别声明struct
student{int
num;char
name
[20];struct
date{int
year;int
month;int
day;}birthday;char
addr[30];};struct
student
ZhangSan;static
struct
student
a1,
a2,
a3;struct
student
a[100];struct
student
*pstu;一般形式:存储类型
struct结构类型名结构变量列表;1-4结构变量的声明(2)结构类型和结构变量同时声明struct
student{int
num;char
name
[20];struct
date{int
year;int
month;int
day;}birthday;char
addr[30];}ZhangSan,
a1,
a[100],
*psth;如果结构类型只使用一次,则结构类型名student可以省略,成为匿名结构类型1-4结构变量的声明(2)结构类型和结构变量同时声明static
struct
point
{int
x;int
y;}
p1,
p2;在声明结构类型structpoint的同时,声明了structpoint类型的静态结构变量p1和p21-5结构变量的初始化声明结构变量同时可以对其进行初始化–初始化所用的初值由初值表提供struct student
{charcharname[10];sex;short
age;int
score[2];}
student1={"zhang
san","m",18,{80,90}};struct student
student2
=
{""Li
Si",
"m",18,
{85,91}};注意:初值表中各初始化表达式的类型应与定义成员的类型一一对应1-6结构变量的存储空间结构成员在内存中连续存放,成员的存储分配按照从上向下、同一声明中从左向右的顺序进行,每个成员所占存储空间的大小由其类型确定struct
student
ZhangSan;addr30bnum2name20year2irthdaymonth26day21-6结构变量的存储空间结构变量的大小是指一个结构变量占用的存储空间的字节数–一般等于一个结构变量所有成员的存储字节数的总和当需要使用结构的大小时,通常应使用sizeof运算符来计算课后学习:存储边界对齐相关知识1-6结构变量的存储空间sizeof运算符是一个单目运算符,用于计算指定类型数据的大小,即所需要占据存储的字节数由sizeof运算符构成的表达式有两种形式。即: sizeof
(表达式)表达式可以是任意表达式或者:sizeof(数据类型名)数据类型是除void外的任何数据类型的类型名1-6结构变量的存储空间float
x;
const
int
YES=1;
struct
student
st,
sts[30];sizeof(char)
1,sizeof(short)
2,sizeof(float)
4,sizeof(x)
4,sizeof(YES)
2,sizeof(struct
student)
21或22,sizeof(st)sizeof(sts)21或22,(21或22)*30struct
student{long
num;char
name
[10];char
sex;int
age;float
score;};思考:结构类型包含指针成员时的情况1-7结构的引用包括对结构变量的引用和对结构变量中成员的引用两个方面
对结构变量的引用包括结构变量的赋值操作、取地址操作和间访操作,以及结构变量作为函数的参数及返回值
对结构变量中成员的引用则需要通过成员选择运算符“.”来实现1-7-1结构变量的引用同类型的结构变量可以相互赋值–赋值操作将右端结构变量中各个成员的值一一赋给左端结构变量的各个成员例:struct
student
st1
=
{"zhang
san",
"m",
18,
{80,
90}};
struct
student
st2
=
{"Li
Si",
"m",
18,
{85,
91}},
st3;
st3
=
st1;
st1
=
st2;
st2
=
st3;st1={"zhang
san","m",18,{80,90}};是否合法?课后学习:浅拷贝、深拷贝1-7-1结构变量的引用可以通过
&
获取结构变量的地址,如:struct
student
st1,
st2,
*p
=
&st1;通过
*
对指针所指结构变量进行间访操作,如:*p
=
st2;1-7-2结构成员的引用C提供成员选择运算符“.”支持对成员的访问和操作成员选择表达式的一般形式是:结构变量名.成员名其中:
“.”是一个双目操作符,其左操作数是结构变量,右操作数是结构变量的成员
“.”操作符具有最高优先级,由它构成的成员选择表达式在任何地方都是一个整体,表示对结构变量中成员的访问1-7-2结构成员的引用struct
student
st1;strcpy(,"zhang");
scanf("%s",
);s1.sex="m";s1.age=18;s1.score[0]=80;s1.score[1]=87;scanf("%c",
&s1.sex);scanf("%d",
&s1.age);scanf("%d",
&s1.score[0]);scanf("%d",
&s1.score[1]);1-7-3嵌套结构的引用嵌套结构中成员的成员同样采用“.”操作符访问“.”操作符的使用个数与嵌套结构的层数相等
“.”操作符的结合性是从左至右struct
date{int
year,
month,
day;}struct
student{int
num;char
name
[20];struct
date
birthday;char
addr[30];};struct student
st1,
st2;st1.birthday.day
=
16;st1.birthday.year
=
1980;(st1.birthday).day与st1.(birthday.day)有什么区别?例根据平面上点的结构类型构造平面上线段的嵌套结构类型,说明对嵌套结构变量中结构成员的成员的引用,并求线段的长度4./*平面上点的结构类型*//*
x,y是点的坐标*/7.8.9.#include
"stdio.h"#include
"math.h"struct
point{int
x,
y;5.
};6.
struct
line{char
name[6];struct
point
start;struct
point
end;/*平面上线段的嵌套结构类型*//*线段名称*//*线段的起点*//*线段的终点*/10.
};11.11.11.
void
main(void){struct
line
a
=
{"abc",
{1,
1},
{10,
10}};double
dx2,
dy2,
length;11.11.11.11.11.printf("line
name
is
%s\n",
);printf("starting
point:(%d,
%d)\n",
a.start.x,
a.start.y);printf("endpoint:(%d,
%d)\n",
a.end.x,
a.end.y);scanf("%s",
);scanf("%d%
d%",
&a.start.x,
&a.start.y);11.11.11.11.11.a.end.x
=
100;
a.end.y
=
100;dx2
=
(a.end.x
-
a.start.x)
*
(a.end.x
-
a.start.x);dy2
=
(a.end.y
-
a.start.y)
*
(a.end.y
-
a.start.y);length
=
sqrt(dx2
+
dy2);printf("the
tength
is
%lf\n",
length);11.
}1-7-3嵌套结构的引用int
x,
y;}point;typedef
struct{point
start;point
end;}line;通过结构嵌套,利用已有结构定义新的结构,实现代码复用typedef
struct{typedef
struct{int
r;point
center;}circle;typedef
struct{point
a;line
l;}plain;plain
p
=
{{1,
1},
{{5,
5},
{10,
15}}};p.a.x
=
10;
p.l.start.x
=
100;主要内容:结构类型与结构变量结构指针结构数组结构与函数联合与位段2结构指针struct
student
b,
*
pb
=
&b;pb
=
&a;结构指针是指以结构类型为基类型的指针,即结构型指针struct
date{int
year,
month,
day;};struct
student{int
num;char
name
[20];struct
date
birthday;char
addr[30];}a,
*pa
=
&a;2结构指针与数组型指针一样,可以通过指针访问结构变量的成员(1)利用“*”和“.”实现间接访问struct
student
a,
b,
*pa
=
&a,
*pb
=
&b;*pa
=
*pb;strcpy((*pa).name,
"Zhangsan");scanf("%s",(*pa).addr);scanf("%d",
&(*pa).num);(*pa).name与*的区别?2结构指针判断下列语句对错
(*pa).num=12345; (*pa).name[0]="c";*((*pa).addr
+
2)
=
"6";++*((*pa).addr
+
3);*((*pa).addr
+
3)++;(*pa).addr
=
"12011";2结构指针(2)利用成员选择运算符“->”实现对结构成员的访问形式:结构指针名->成员名“->”是双目运算符,具有最高优先级,左结合
“->”的左操作数是结构类型的指针,右操作数为结构成员结构指针名->成员名等价于(*结构指针名).成员名2结构指针struct
student
a,
*pa
=
&a;↔pa->namepa->num↔↔a.num↔↔(*pa).name(*pa).numa.birthday.year↔(*pa).birthday.yearpa->birthday.year↔(pa->birthday).year设有多种类型成员的嵌套结构类型声明如下:date{year;month[12];day;structintcharshort};struct
mul_type{charintfloatcharcharstructstructc;n;d;s[12];*ps;date
a;date
*pa;}m
=
{"a",100,3.14f,"myabcdefg",m.s,{2007,"July",
29},&m.a},*pm=&m;pm->pa->yearm.a.year(*pm).pa->yearm.pa->yearpm->a.year(*pm->pa).year(*m.pa).year(*(*pm).pa).year;等价主要内容:结构类型与结构变量结构指针结构数组结构与函数联合与位段3结构数组结构数组是由相同结构类型的元素构成的数组
一维结构数组是一种应用十分广泛的数据结构,一般情况下都使用一维结构数组
一维结构数组特别适合描述通信录、登记表、成绩单以及编译程序处理的符号表等二维表格数据二维表格中的每一行对应结构数组的一个元素,每一列对应一种属性,代表一个结构成员的类型一维结构数组中的元素又称为记录3结构数组学生情况登记表student[0]student[1]student[2]…student[29]numnamesexagescore2129500张三m1883.52129501李四m1990.52129502王红f1885.0……………2129529程萍f1987.03-1结构数组的声明结构数组的声明与一般数组的声明类似struct
student
cs[5]
={{2129500,"张三","m",18,83.5},{2129501,"李四","m",18,90.5},{2129502,"王红","m",18,85.0},{2129503,"田亮","m",19,87.0},{2129504,
"张灵",
"f",
18,
81.5},};struct
student{long
num;char
name
[10];char
sex;int
age;float
score;}class1[40];3-2结构数组的使用结构数组的使用指对结构数组元素的引用和元素中成员的访问及操作–引用结构数组中的元素与引用普通数组元素的形式完全一样for(i
=
0;
i
<
2;
i++){printf("%s\t",
class2[i].num);printf("%s\t",
class2[i].name);printf("%c\t",
class2[i].sex);}3-2结构数组的使用struct
student
class1[30],
*p;例1:for(p
=
class1;
p
<
&class1[30];
p++){printf("\n%10ld%15s%4c%6hd%8.1f",
p->num,p->name,
p->sex,
p->age,
p->score);}例2:p
=
class1;(*p).num或(p+0)->num 表示引用class1[0].num(*(p+i)).num或(p+i)->num表示引用class1[i].num(*++p).num或(++p)->num 表示引用class1[1].num主要内容:结构类型与结构变量结构指针结构数组结构与函数联合与位段4结构与函数结构作为函数的参数结构作为函数的返回值4-1结构作为函数参数将结构的信息传递给函数有以下途径:将结构成员作为函数参数仅用到结构的单个成员将整个结构变量作为函数参数(传值)函数对结构变量的副本进行操作用指向结构变量的指针作参数(传址)对较大的结构变量传递效率较高,仅传递一个指针将结构数组作为函数的参数4-1-1结构成员作为函数参数例如:–对2个物理量,量纲相同时可以进行物理量的相加操作typedef
struct{double
size;char
dimension[12];}motion;double
add_motion_size(double,
double);motion
b
=
{12.5,
"m/s"},
c
=
{26.7,
"m/s"},
d;d.size
=
add_motion_size(b.size,
c.size);4-1-2结构变量作为函数参数例如:–对2个物理量,量纲相同时可以进行物理量的相加操作typedef
struct{double
size;char
dimension[12];}motion;double
add_motion_size(motion
u,
motion
v);motion
b
=
{12.5,
"m/s"},
c
=
{26.7,
"m/s"},
d;d.size
=
add_motion_size(b,
c);4-1-3结构指针作为函数参数例如:–对2个物理量,量纲相同时可以进行物理量的相加操作typedef
struct{double
size;char
dimension[12];}motion;double
add_motion_size(motion
*u,
motion
*v);motion
b
=
{12.5,
"m/s"},
c
=
{26.7,
"m/s"},
d,
*pb=&b,*pc=&c;d.size
=
add_motion_size(pb,
pc);4-1-4结构数组作为函数参数结构数组作为函数的参数时一定要用结构指针,形参应该声明为数组元素结构类型的指针实参用结构数组名或者结构数组首元素的地址例 结构数组作为函数的参数的应用举例:设计一个货物结构类型,定义对应的结构数组。先进行数据输入并显示输入的数据,然后对价格按照降序排序并显示排序后的结果1.2.#include
"stdio.h"#define
N
33.typedef
struct
{4.5.6./*货物编码*//*名称*//*价格*/7.long
code;char
name[20];float
price;}GOODS;8.9.voidinput(GOODS
*p,
int
n);void
sort(GOODS
*p,
int
n);void
display(GOODS
*p,
int
n);void
main(void){12.13.GOODS
meat[N];input(meat,N);
/*结构数组名作为实参*/14.15.display(&meat[0],
N);sort(meat,
N);display(meat,
N);16.17.
}18.18.18.18.
voidinput(GOODS
*p,int
n){int
i;
float
tmp;for(i
=
0;
i
<
n;
i++){scanf("%ld",
&p[i].code);18.18.18.18.scanf("%s",
(p+i)->name);scanf("%f",
&tmp);(*(p+i)).price
=
tmp;}18.
}18.
void
sort(GOODS
*p,
int
n){18.int
i,
j;
GOODS
t;18.18.18.for(i
=
0;
i
<
n-1;
i++)for(j
=
i
+
1;
j
<
n;
j++)if((p
+
i)->price
<
(p
+
j)->price){18.18.
t
=
*(p
+
i);
*(p
+
i)
=
*(p
+
j);
*(p
+
j)
=
t;}18.
}35.35.35.
void
display(GOODS
*p,
int
n)
{int
i;for(i
=
0;
i
<
n;
i++){35.printf("%ld\t",
(*(p
+
i)).code35.35.printf("%s\t",
(p
+
i)->name);printf("%f\n",
p[i].price);35.}35.
}4-2结构作为函数返回值包括三种形式:将结构成员作为函数返回值将整个结构变量作为函数返回值用指向结构变量的指针作函数返回值函数返回类型应与要返回的对象的类型一致4-2-1结构成员作为函数返回值例如:typedef
struct{double
size;char
dimension[12];}motion;double
get_motion_size(motion
u){return
u.size;}date
get_student_birthday(student
stu){return
stu.birthday;}4-2-1结构变量作为函数返回值例如:motion
get_motion(void){motion
a;printf("inputthe
value
of
member
size
and
dimension\n");scanf("%lf",
&a.size);scanf("%s",
a.dimension);return
a;}typedef
struct{double
size;char
dimension[12];}motion;4-2-1结构指针作为函数返回值例如:typedef
struct{double
size;char
dimension[12];}motion;motion
*
get_motion(void){static
motion
a;printf("inputthe
value
of
member
size
and
dimension\n");scanf("%lf",
&a.size);scanf("%s",
a.dimension);return
&a;}主要内容:结构类型与结构变量结构指针结构数组结构与函数联合与位段5-1联合以变量、数组、结构为载体的数据所代表的含义是固定不变的实际应用中,有些信息需要在不同场合表现为不同的数据,如学生基本信息中与年龄相关的信息可以是实际年龄或出生日期,分别为整型和字符串–C语言通过联合类型来实现5-1联合联合类型的变量由多个成员组成
这些成员并不同时存在,而是在不同时刻拥有不同的成员在同一时刻仅拥有其中一个成员
联合变量的成员可以是任何类型的数据,包括任何基本类型、指针类型、数组类型、结构类型或其它联合类型5-1联合除了用关键字union取代struct之外,联合类型在语法形式上与结构完全相同例:union
chl{char
c;short
h;long
l;};5-1联合union
chl
v
=
{"9"},
w
=
{"a"};联合在同一时刻它只拥有其中的一个成员,在初始化时只能对第1个成员进行初始化,初值表中只能包含与第1个成员数据类型相同的一个初值union
chl{char
c;short
h;long
l;}v
=
"9",
w
=
"a";#include
"stdio.h"union
chl{charc;shorth;longl;1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.};void
show(union
chl
*pu);void
show_memory(union
chl
*pu);void
main(void){union
chl
u;printf("sizeofu
is
%d\n",
sizeof(u));u.l
=0x31323334L;show(&u);show_memory(&u);u.h
=
0x3638;show(&u);show_memory(&u);18.
}19.
void
show(union
chl
*pu){19.
printf("char
format:
%c\n",
(*pu).c);19.
printf("int
format:
%hx\n",
pu->h);19.
printf("long
format:
%lx\n",
(*pu).l);19.
}19.
voidshow_memory(union
chl
*pu){19.
char
*p
=
(char
*)pu;19.
int
i
=
0;19.
while(i
<
4)19.
{19.
printf("addr
%dth
byte
of
u
is
0x%p\t",
i,
p+i);19.
printf("the
ASCII
in
%dth
byte
of
u
is
%c\n",
i,
*(p+i));19.
i++;19.
}19.
}注意:使用联合变量时,必须知道当前有效成员联合的大小大于或等于最长成员的字节数可以声明联合类型的指针。如:union
chl
v,
*pv
=
&v;注意:
联合所有成员的地址和联合变量的地址都相同,不同成员指针值(地址值)的类型是不相同的
即:&u,&u.c,&u.h,&u.l的地址都相同。而&u的数
据类型是union
chl
*;&u.c的数据类型是char
*;&u.h的数据类型是int
short
*;&u.l的数据类型是long
int
*5-1联合可以通过联合变量和“.”操作符,以及指向联合变量的指针和“->”操作符来引用联合成员对联合成员的引用形式为:(1)联合变量名.成员名(2)(*指向联合变量的指针).成员名(3)指向联合变量的指针->成员名例如:u.c或(*pu).c或pu->c都表示引用联合成员c,类型是char
u.c="a",(*pu).h=0x3839,以及pu->l=0x31323334L分别表示对联合u的成员c、h、l的赋值操作5-1联合联合中允许存储不同类型的数据,对某个时刻存储的数据,其所允许的操作也有所不同,有些操作对该类型的数据是相容的,但有些操作却不相容(得不到正确结果)由于语法上合法,编译器对这种情况不会报错,但运算的结果却不正确5-1联合5-2位段位段(bitfield)是指由多个相邻的二进制位可以组成的结构或者联合中的整型或无符号整型成员以位段为成员的结构称为位段结构组成位段的二进制位的数目成为该位段的宽度,它是一个非负的整型常量表达式位段结构在操作系统,编译程序,计算机接口的C语言编程方面使用较多5-2位段例如,stdio.h中关于文件状态成员flags的取值就规定了1为读状态,2为写状态,4为缓冲数据状态等。这些数据都
是一些值很小的整数,没有必要用int(16bit)或char(8bit)量来存储每一个值通常对若干个特征中的每个特征按照取值的大小分配合适的二进制位,然后将它们封装到一个int或char变量中。这样就可以通过位段名对相应的二进制位或位串进行操作,而不必采用位运算考虑十字路口的交通灯,颜色枚举类型的声明如下:enum
color{
OFF
=
0,
RED
=
1,
YELLOW
=
2,
GREEN
=
3}
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 有效排痰护理 2
- 造口并发症及处理
- 心肺复苏知识培训
- 浙江省2023~2024学年高二数学下学期返校联考试题含答案
- 贵州省黔西南州金成实验学校2024−2025学年高一下学期3月检测 数学试卷(含解析)
- 江苏省盐城市大丰区新丰初级中学2025届学业水平模拟考试化学试题仿真模拟试题A卷含解析
- 内蒙古丰州职业学院《食品工艺综合实验》2023-2024学年第一学期期末试卷
- 九州职业技术学院《矿床地球化学》2023-2024学年第二学期期末试卷
- 四川省成都实验高级中学2025届高三年级5月统测模拟试卷含解析
- 西交利物浦大学《理论力学B》2023-2024学年第二学期期末试卷
- 地基基础规范8章
- 从敦煌壁画看中国古代山水画的发展演变
- DB12-537-2014企业事业单位内部治安保卫规范
- 建筑工地项目部人员职责划分表
- 工程量确认单表样
- 劳动争议调解仲裁法解析
- 海因环氧树脂的制备及其应用
- 数字化语音存储与回放系统(毕业设计)
- 造林典型设计
- 肾脏内科疾病诊疗指南
- 一般现在时和现在进行时练习题
评论
0/150
提交评论