当前位置:首页 >> 其它课程 >> 第12章 结构体共用体和用户定义类型

第12章 结构体共用体和用户定义类型


第十二章 结构体、共用体、用户定义类型

13.1 用typedef说明一种新类型名 13.2 结构体 13.3 共用体

13.1 用typedef说明一种新类型名
typedef语句形式: typedef 类型名 标识符; 用户定义的标识符, 用作新的类型名

已经存在的类型标识符

功能:用“标识符”来为已存在的“类型名”命名,并未 产生新的数据类型。 例如:typedef char *CHAR; CHAR p; 等价于 char *p; typedef int NUM[10]; NUM n; 等价于 int n[10];

说明: 1.typedef 没有创造新数据类型 2.typedef 是定义类型,不能定义变量 3.typedef 与 define 不同 define 预编译时处理 简单字符置换 typedef 编译时处理 为已有类型命名

13.2 结构体
结构体:是一种自定义的构造数据类型。 用途:把不同类型的数据组合成一个整体。

13.2.1 结构体类型定义:
struct { [结构体名]

合法标识符 可省:无名结构体

struct是关键字, 不能省略 };

类型标识符 成员名; 成员类型可以是 类型标识符 成员名; 基本型或构造型 …………….

num

2字节



name

20字节 1字节 2字节 4字节



struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; };

sex age score

…..

addr

30字节

结构体类型的定义

结构体类型定义描述结构 的组织形式(图纸),不分配内存

13.2.2
?

结构体变量的定义
一般形式:
struct { 结构体名

(1)、先定义结构体类型,再定义结构体变量



类型标识符 成员名; 类型标识符 成员名; ……………. 例 #define STUDENT struct student }; STUDENT struct student struct 结构体名 变量名表列;

{ int num; int num; char name[20]; char name[20]; char sex; char sex; int age; int age; float score; float score; char addr[30]; char addr[30]; }; }; STUDENT stu1,stu2; struct student stu1,stu2; {

?

(2)、定义结构体类型的同时定义结构体变量
一般形式:
struct 结构体名 { 类型标识符 成员名; 类型标识符 成员名; ……………. }变量名表列;

例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2;

?

(3)、直接无名结构体的同时定义结构体变量
一般形式:
struct { 类型标识符 类型标识符 ……………. }变量名列表;

成员名; 成员名;

例 struct { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2;

用无名结构体直接定义变量只能一 次 通常用在不需要再次定义此类型结 构变量

?

(4)、使用typedef说明一个结构体类型名,再用 新类型名定义变量
一般形式:
typedef struct { 类型标识符 成员名; 类型标识符 成员名; ……………. }标识符; 标识符 变量名列表;

例 typedef {

struct int num; char name[20]; char sex; int age; float score; char addr[30]; }student; student std,pers[3],*pstd;

?

说明
?

结构体类型与结构体变量概念不同
? ?

类型:不分配内存; 类型:不能赋值、存取、运算;

变量:分配内存 变量:可以

结构体成员名(域名)与程序中变量名地位相同 ? 结构体可嵌套 例 struct date struct student {例int month; { int day; int num; char name[20]; int year; }; struct date int month; birthday struct{student num name birthdayyear int day; num name month day { int num; month day year int year; char name[20]; }birthday; struct date birthday; }stu; }stu;
?

12.2.3结构体变量的初始化 和其他类型的变量相同,在定义结构体变量时 struct 结构体名 赋初值
形式一:
{ 类型标识符 成员名; 类型标识符 成员名; ……………. }; struct 结构体名 结构体变量={初始数据};

例 struct student { int num; char name[20]; char sex; int age; char addr[30]; }; struct student stu1={112,“Wang Lin”,?M?,19, “200 Beijing Road”};

?

形式二:

struct {

结构体名

类型标识符 成员名; 类型标识符 成员名; ……………. }结构体变量={初始数据};

例 struct student { int num; char name[20]; char sex; int age; char addr[30]; }stu1={112,“Wang Lin”,?M?,19, “200 Beijing Road”};

?

形式三:

struct { 类型标识符 成员名; 类型标识符 成员名; ……………. }结构体变量={初始数据};

例 struct { int num; char name[20]; char sex; int age; char addr[30]; }stu1={112,“Wang Lin”,?M?,19, “200 Beijing Road”};

12.2.4 结构体变量的引用
?

引用规则

例 struct 结构体变量不能整体引用,只能引用变量成员 student ? { int num; 引用方式: 结构体变量名.成员名 例 struct student char name[20]; student 例 struct sex; struct {char 例 int student num; stu1.num=10; { int printf(“%d,%s,%c,%d,%f,%s\n”,stu1); (?) stu1.birthday.month=12; {intchar name[20]; num; int num; struct student age; 例 成员(分量)运算符 char date { char name[20]; name[20]; num; struct int ? 可以将一个结构体变量赋值给另一个结构体变量 float score; 优先级: 1 { charmonth; char sex;name[20]; stu1.score=85.5; int sex; 结合性:从左向右 Lin”,?M?,19,87.5,“DaLian”}; (?) stu1={101,“Wan char addr[30]; int char ? 结构体嵌套时逐级引用 age; sex; birthday int age; int day; if(stu1==stu2) charnum name }stu1,stu2; …….. (?) month day year stu1.score+=stu2.score; floatyear; float score; int score; int age; stu2=stu1; (stu1.age++; ) char addr[30]; char addr[30]; float score; }birthday; }stu1,stu2; }stu1,stu2; addr[30]; }stu1,stu2; char }stu1,stu2;

12.2.5 结构体数组
1、结构体数组的定义和初始化 定义:三种形式:
num

形式一: 形式二: 形式三: name 25B stu[0] struct student struct student struct sex { int num; { int num; { int num; age char name[20]; char name[20]; char name[20]; num char sex; char sex; char sex; nameage; int age; int age; int stu[1] }; sex }stu[2]; }stu[2]; struct student stu[2]; age

初始化:与其他类型的数组赋初值的方法相同

分元素初始化: 顺序初始化: struct student struct 例 struct student { { int num; int num; int {num; char name[20]; char name[20]; char name[20]; char sex; char sex; char sex; int age; int age; int age; }stu[ ]={{……},{……},{……}}; }; }; struct student stu[ ]={{100,“Wang Lin”,?M?,20}, struct student stu[ ]={100,“Wang Lin”,?M?,20, {101,“Li Gang”,?M?,19}, 101,“Li Gang”,?M?,19, {110,“Liu Yan”,?F?,19}}; 110,“Liu Yan”,?F?,19};
全部初始化时维数可省

2、结构体数组引用 引用方式: 结构体数组名[下标].成员名
num 25B name sex age num name sex age stu[0]

struct student { int num; char name[20]; char sex; int age; }str[3];

strcpy(stu[0].name,”ZhaoDa”);

stu[1]

stu[1].age++;

12.2.6 向函数传递结构体型数据

函数之间的参数传递也可以是结构体型数据,既可以通过 参数传送结构体变量的成员,也可以通过参数传递整个结构 体变量。 1.向函数传递结构体变量的成员 若结构体变量的成员是基本类型,则作函数的实参时的 用法与普通变量作函数的实参的用法相同,形参与实参之间 仍然是“值传递”的方式。

2.向函数传递结构体变量
ANSI C允许函数之间传递结构体变量。若实参是结构 体变量,那么形参也应是同类型的结构体变量。系统将为结 构体类型的形参开辟相应的存储单元,并将实参中各成员的 值赋给对应的形参成员。 “值传递”



(main) (main) (main) a :27 a :27 a :27 struct data a :27 b: 3 b: b: 3 { int a, b, c; }; 3 cb: 3 c :30 :30 c :30 main() c :30 { void func(struct data); (func) copy (func) struct data arg; a :27 a :18 arg.a=27; arg.b=3; arg.c=arg.a+arg.b; b: 3 printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); b: 5 c :30 c :90 printf("Call Func()....\n");
func(arg); printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); } void func(struct data parm) { printf("parm.a=%d parm.b=%d parm.c=%d\n",parm.a,parm.b,parm.c); printf("Process...\n"); parm.a=18; parm.b=5; parm.c=parm.a*parm.b; printf("parm.a=%d parm.b=%d parm.c=%d\n",parm.a,parm.b,parm.c); printf("Return...\n"); }

用结构体变量作函数参数

arg arg arg arg

parm parm

3.传递结构体的地址 结构体变量的地址作为实参传递,那么形参应是基类型 相同的结构体类型的指针。系统将为结构体类型指针开辟一 个存储单元,存放实参结构体变量的地址值。 “地址传递” typedef struct { char s[10]; int t; }ST; getdata(ST *p) { scanf(“%s%d”,p->s,&p->t) } main() { ST a; getdata(a); printf(“%s,%d”,a.s,a.t); }

例 指向结构体的指针变量 指向结构体变量的指针 typedef struct student ? 定义形式:struct 结构体名 *结构体指针名; { long struct student *p; int num; 例 char name[20]; char sex; ? 使用结构体指针变量引用成员形式 struct student 存放结构体变量在内存的起始地址 float score; p num }ST;{ int num; (*结构体指针名).成员名 结构体指针名->成员名 结构体变量名.成员名 struct student name stu1; char name[20]; main() stu struct student sex *p=&stu1; 例 char sex; int n; {ST stu_1,*p; ? int *p=&n; 指向运算符 stu1.num=101; age (*p).num=101 int age; p=&stu_1; 优先级: }stu; *p=10; 1 ? n=10 stu_1.num=89101; 结合方向:从左向右 struct student *p=&stu; strcpy(stu_1.name,"Li Lin"); p->sex='M'; p->score=89.5; printf("\nNo:%ld\nname:%s\nsex:%c\nscore:%f\n", (*p).num,p->name,stu_1.sex,p->score); }

12.2.7

结构体和指针

若有:struct { int 注意: a; char *s; }x,*p=&x;变量x的成员a,指针成员s已正确赋值 (*p).a 等价于 p->a ++p->a; 等价于++(p->a);p所指变量x中成员a增1 (p++)->a;等价于p++ ->a;访问p所指变量x中成员a之后,指针p增1。 *p->s 引用变量x中s所指存储单元
*p->s++ (*p->s)++ *p++ ->s 引用了s所指存储单元之后,s指针加1 使得s所指向的存储单元的值增1 访问了s所指存储单元之后,使p增1

12.2.8 利用结构体变量构成链表
1、链表的特点:
?

?

?

?

链表是一种动态的进行存储分配的数据结构,程序执行 中,可以在需要时开辟存储单元,在不需要时释放存储 单元。 链表的结点包含数据域和链接域,数据域用来保存数据 信息,链接域用来保存该结点的后继结点或前驱结点的 地址。 一个链表用一个头指针来保存该链表的首地址,即第一 个结点的地址。头指针是一个链表的标志。 此链表只能从当前节点找到后继节点,故称为单链表。

一个单链表的逻辑示意图:

【e12_1】一个简单的单链表。 typedef struct slist { int data; struct slist *next; }SLIST; main() {SLIST n1,n2,n3,*head,*p; head=&n1; n1.data=1; n1.next=&n2; n2.data=2; n2.next=&n3; n3.data=3; n3.next=0; printf("\n"); for(p=head;p!= '\0';p=p->next) printf("%3d",p->data); }

2、建立单链表

主要步骤为:
生成只含有头结点的空链表; ? 然后读取数据信息,生成新结点,将数据存放于新 结点中, 插入新结点到单链表中 ? 重复第二步,直到输入结束。 根据新结点插入到链表的位置的不同,建立链表 的方式, 分为在表尾插入的方法和在表头插入的方法。 ? 表尾插入:
?

e12_2.c
?

表头插入:

e12_3.c

e12_2.c SLIST *CreateList ( ) {SLIST *p,*head,*q; int x; head = (SLIST *)malloc (sizeof(SLIST)); //生成头结点 p=head; //尾指针指向头结点 scanf(“%d”,&x); while (x!=-1) { q = (SLIST *)malloc (sizeof(SLIST)); q->data=x; p->next=q; p=q; scanf(“%d”,&x); } p->next=NULL; return head; }

e12_3c SLIST *CreateList ( ) {SLIST *p=NULL,*head,*q; int x; scanf(“%d”,&x); while (x!=-1) { q=(SLIST *)malloc (sizeof(SLIST)); q->data=x; q->next=p; p=q; scanf(“%d”,&x); } head= (SLIST *)malloc(sizeof(SLIST)); /*建立头节点*/ head->next=p; return head; }

3、在单链表中插入结点
设指针变量s指向待插入结点,假设指定结点为p。
?

插入到指定结点之后: ① s??next=p??next; ② p??next=s;

?

插入到指定结点之前:首先要找到p的前驱结点q。

p202 14.8

4、在单链表中删除结点
在一个单链表中删除指定结点,首先要找到该结 点的前驱结点,然后修改前驱结点的指针域指向待删 结点的后继结点,然后释放被删结点。

12.3

共用体

公用体类型说明和变量定义与结构体方式完全相 同,不同的是公用体变量的所有成员占有同一个存储 空间。 12.3.1 共用体类型 定义形式: union 共用体名
{ 类型标识符 类型标识符 ……………. }; 100地址开始 i ch 成员名; 成员名;



union data { int i; char ch; float f; };

f

类型定义不分配内存

12.3.2 共用体变量的定义 1、共用体变量的定义
形式一: union data { int i; char ch; float f; }; union data a,b,c,*p,d[3];
i ch f

形式二: union data { int i; char ch; float f; }a,b;
i ch f

形式三: union { int i; char ch; float f; }a,b,c;

a 共用体变量任何时刻 只有一个成员存在

b 共用体变量定义分配内存, 长度=最长成员所占字节数

2 共用体变量引用
?

引用方式:
共用体指针名->成员名 (*共用体指针名).成员名

共用体变量名.成员名

? 引用规则 union data a.i a.ch a.f ? 不能引用共用体变量,只能引用其成员 { int i; p->i p->ch p->f ? 共用体变量中起作用的成员是最后一次存放的成员 char ch; ? 不能在定义共用体变量时初始化 float 例 union f; 例 a.i=1; (*p).i (*p).ch (*p).f 例 float x; 例 union i; { int ? }; 可以用一个共用体变量为另一个变量赋值 a.ch=?a?; { union ch; int i; union data a,b,c,*p,d[3]; d[0].i d[0].ch d[0].f char a.f=1.5; { char ch; char ch; float f; int i; float (?编译通过,运行结果不对) printf(“%d”,a.i); }a,b; f; float f; }a; a.i=1; a.ch=?a?; }a={1,?a?,1.5}; (?)a.f=1.5; a=1; (?) b=a; (?) x=a.f; (?)

例e12_4.c 将一个整数按字节输出 main() { union int_char { int i; char ch[2]; }x; x.i=16961; printf("i=%o\n",x.i); printf("ch0=%o,ch1=%o\n ch0=%c,ch1=%c\n", x.ch[0],x.ch[1],x.ch[0],x.ch[1]); }
运行结果: i=16961 ch0=101,ch1=102 ch0=A,ch1=B
高字节 低字节 01000010 01000001

01000001 01000010

ch[0] ch[1]

?

结构体与共用体
?

区别: 存储方式不同
变量的各成员同时存在

struct node { char ch[2]; int k; }a; union node { char ch[2]; int k; }b;
?

ch k

a

ch k

b
任一时刻只有一个成员存在

联系: 两者可相互嵌套

(50)以下叙述中错误的是( )。[2006年4月选择第50题] A.可以通过typedef增加新的类型 B.可以用typedef将已存在的类型用一个新的名字来代表 C.用typedef定义新的类型名后,原有类型名仍有效 D.用typedef可以为各种类型起别名,但不能为变量起别名 (26)有以下程序段 [2006年4月选择第26题] struct st {int x;int *y;}*pt; int a[]={l,2},b[]={3,4}; struct st c[2]={10,a,20,b}; pt=c; 以下选项中表达式的值为11的是 A)*pt->y B)pt->x C)++pt->x D)(pt++)->x

2006-9选择

选c

选d

选b


更多相关文档:

14结构体、共用体和用户定义类型(修订版)

第十四章 结构体共用体和用户定义类型 考点 82 结构体变量的定义和初始化 一、结构体 结构体是一种由多个成员组成的集合。 定义一个结构体的格式: struct ...

第十四章 结构体、共用体和用户定义类型

第十四章 结构体共用体和用户定义类型 结构体、 到目前为止,我们已经介绍了 C 语言中的基本类型(整型、字符 型、实型、双精度型和空值型)以及派生类型(指针...

第11课 用户构造的三种数据类型(用户定义,结构体,共用体)

第十一课 用户构造的三种数据类型(用户定义,结构体,共同体) 一、 用 typedef 说明一种新类型说明形式: typedef 类型名 标识符; 如:typedef int INTEGER; ...

c语言教案27(结构体、共用体和用户定义类型2)

语句和共同体 教学回顾 备 注辅导教师 主讲教师 教学过程教学内容与进程 教学方法的 运用与说明 第 14 章一、回顾: 结构体共用体和用户定义类型(2) typedef ...

第14部分 结构体共用体和用户定义类型

B.s2.age=s1.age; D.printf(“%o”,&s1); -3- 第 14 部分 结构体共用体和用户定义类型 12、设有以下定义: struct stru { int a; long b; char ...

...第12章结构体和共用体(2013级亲测正确)

中国石油大学(华东)C语言在线测评答案 第12章结构体和共用体(2013级亲测正确)_院校资料_高等教育_教育专区。12.1 修改学生的各科成绩给定程序通过定义并赋初值的...

c语言教案26(结构体、共用体和用户定义类型1)

第 14 章一、回顾: 结构体共用体和用户定义类型(1) 字符串的输入和输出运用理实一体 化,解决学生 出现的疑难问 题 二、用 typedef 说明一种新类型名 三...

第10-1课 用户定义类型、结构体、共用体

第10-1 课 用户定义类型结构体共用体 一、教学过程 1、C 语言允许用 typedef 说明一种新类型名 【格式】 typedef 类型名 标识符 【说明】 “类型名”必...

第十二章 结构体与共用体

第十二章 结构体与共用体 隐藏>> C 语言程序设计教案 结构体与共用体内容 主要...项,C 语言没有提供这样的数据结构,因此用户必须在程序 中建立所需结构体类型。...

结构体和共用体 参考答案

结构体和共用体 参考答案_理学_高等教育_教育专区。实验八班级: 结构体及其应用姓名: 成绩: 学号: 一. 实验目的 1、掌握结构体数据类型定义和使用。 2、掌握...
更多相关标签:
网站地图

文档资料共享网 nexoncn.com copyright ©right 2010-2020。
文档资料共享网内容来自网络,如有侵犯请联系客服。email:zhit325@126.com