结构与联合学习课件_第1页
结构与联合学习课件_第2页
结构与联合学习课件_第3页
结构与联合学习课件_第4页
结构与联合学习课件_第5页
已阅读5页,还剩68页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论