45
第第第 第第 第第第第 体体 § 9.1 第第 第第 第第 第 体一 第第第第第第 第第 第第第第第第第第第第 第第第 一体 ------- 第第第第第第第 第第 第第第第 struct [ 第第 ] { 第第第第第 第第第第第第第第 第第第……………. }第 第第第第第第第 第第第第第第第 struct 第第第 , 第第第第 第第第第第 第第 : 第第第第

第九章 结构体与共用体

  • Upload
    ilyssa

  • View
    70

  • Download
    4

Embed Size (px)

DESCRIPTION

第九章 结构体与共用体. 9.1 结构体 结构体是 一种 构造 数据类型 用途:把 不同类型 的数据组合成一个整体------- 自定义 数据类型 结构体类型定义. 合法标识符 可省 : 无名结构体. struct [ 结构体名 ] { 类型标识符 成员名; 类型标识符 成员名; ……………. } ;. 成员类型可以是 基本型或构造型. struct 是 关键字 , 不能省略. 2 字节. num. …. name. 20 字节. 1 字节. sex. 2 字节. age. 4 字节. score. - PowerPoint PPT Presentation

Citation preview

Page 1: 第九章  结构体与共用体

第九章 结构体与共用体§ 9.1 结构体

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

结构体类型定义

struct [ 结构体名 ]{ 类型标识符 成员名; 类型标识符 成员名; …………….} ;

成员类型可以是基本型或构造型struct 是关键字 ,

不能省略

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

Page 2: 第九章  结构体与共用体

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

name

num

sex

age

score

addr

2 字节

2 字节

20 字节1 字节

4 字节

30 字节

……

..

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

Page 3: 第九章  结构体与共用体

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

§ 9.2 结构体变量的定义先定义结构体类型,再定义结构体变量

一般形式: struct 结构体名{ 类型标识符 成员名; 类型标识符 成员名; …………….} ;struct 结构体名 变量名表列;

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

Page 4: 第九章  结构体与共用体

定义结构体类型的同时定义结构体变量一般形式:

struct 结构体名{ 类型标识符 成员名; 类型标识符 成员名; …………….} 变量名表列;

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

Page 5: 第九章  结构体与共用体

直接定义结构体变量一般形式:

struct{ 类型标识符 成员名; 类型标识符 成员名; …………….} 变量名表列;

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

用无名结构体直接定义变量只能一次

Page 6: 第九章  结构体与共用体

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

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

结构体可嵌套结构体成员名与程序中变量名可相同,不会混淆

例 struct date { int month; int day; int year; }; struct student { int num; char name[20]; struct date birthday; }stu;

num namebirthday

month day year

例 struct student { int num; char name[20]; struct date { int month; int day; int year; }birthday; }stu;

num namebirthday

month day year

Page 7: 第九章  结构体与共用体

§ 9.3 结构体变量的引用引用规则

结构体变量不能整体引用 , 只能引用变量成员

可以将一个结构体变量赋值给另一个结构体变量结构体嵌套时逐级引用

成员 ( 分量 ) 运算符优先级 : 1结合性 : 从左向右

引用方式: 结构体变量名 . 成员名例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2;

stu1.num=10;

stu1.score=85.5;

stu1.score+=stu2.score; stu1.age++;

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

printf(“%d,%s,%c,%d,%f,%s\n”,stu1); ()

stu1={101,“Wan Lin”,‘M’,19,87.5,“DaLian”}; ()

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

stu2=stu1; ( )

例 struct student { int num; char name[20]; struct date { int month; int day; int year; }birthday; }stu1,stu2;

num namebirthday

month day year

stu1.birthday.month=12;

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

if(stu1==stu2)…….. ()

Page 8: 第九章  结构体与共用体

【例】main(){ struct student { int number; char name[6]; char sex; int age; char address[20]; } ; printf("%d\n ",sizeof(struct student)); } 结果: 31

Page 9: 第九章  结构体与共用体

【例】若有以下定义,则正确的赋值语句为 。 struct complex { float real; float image; }; struct value { int no; struct complex com; }val1;

A) com.real=1; B) val1.complex.real=1;C) val1.com.real=1; D) val1.real=1;

答案: C ) val1.com.real=1

Page 10: 第九章  结构体与共用体

§ 9.4 结构体变量的初始化形式一:

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”};

Page 11: 第九章  结构体与共用体

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

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

Page 12: 第九章  结构体与共用体

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

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

Page 13: 第九章  结构体与共用体

进行所谓“结构体变量赋值”只能逐个成员进行,不能将结构体变量作为一个整体进行输入和输出。如对结构体变量stu ,以下语句是错误的: scanf(“%s,%s,%ld”,stu);

printf(“%s,%s,%ld”,stu);

正确编程:main(){ struct { char name[15]; char class[12]; long num; } stu; scanf("%s",stu.name); scanf("%s",stu.class); scanf("%ld",&stu.num); printf("%s,%s,%ld\n",stu.name,stu.class,stu.num);}

亦可用以下赋值语句:strcpy(stu.name,”wenli”); strcpy(stu.class, “Computer”);stu.num=200113;

但是如果改为stu.name=”wenli” 是错误的。

Page 14: 第九章  结构体与共用体

§ 9.5 结构体数组结构体数组的定义

三种形式:形式一 : struct student { int num; char name[20]; char sex; int age; };struct student stu[2];

形式二 : struct student { int num; char name[20]; char sex; int age; }stu[2];

形式三 : struct { int num; char name[20]; char sex; int age; }stu[2];

num

name

sex

age

num

name

sex

age

stu[0]

stu[1]

25B

Page 15: 第九章  结构体与共用体

结构体数组初始化

例 struct { int num; char name[20]; char sex; int age; }stu[ ]={{……},{……},{……}};

顺序初始化 : struct student { int num; char name[20]; char sex; int age; };struct student stu[ ]={100,“Wang Lin”,‘M’,20, 101,“Li Gang”,‘M’,19, 110,“Liu Yan”,‘F’,19};

例 struct student { int num; char name[20]; char sex; int age; }stu[ ]={{……},{……},{……}};

分行初始化 : struct student { int num; char name[20]; char sex; int age; };struct student stu[ ]={{100,“Wang Lin”,‘M’,20}, {101,“Li Gang”,‘M’,19}, {110,“Liu Yan”,‘F’,19}};

全部初始化时长度可省

结构体数组引用引用方式: 结构体数组名 [ 下标 ]. 成员名 struct student { int num; char name[20]; char sex; int age; }str[3];

stu[1].age++;

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

Page 16: 第九章  结构体与共用体

例 统计后选人选票

struct person{ char name[20]; int count;}leader[3]={“Li”,0,“Zhang”,0,”Wang“,0}; main(){ int i,j; char leader_name[20]; for(i=1;i<=10;i++) { scanf("%s",leader_name); for(j=0;j<3;j++)

if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;

} for(i=0;i<3;i++) printf("%5s:%d\n",leader[i].name,leader[i].count);}

name count

Li

Zhang

Wang

0

0

0

Page 17: 第九章  结构体与共用体

§ 9.6 结构体和指针指向结构体变量的指针

定义形式: struct 结构体名 * 结构体指针名 ;例 struct student *p;

使用结构体指针变量引用成员形式存放结构体变量在内存的起始地址num

name

sex

age

stu

pstruct student { int num; char name[20]; char sex; int age; }stu;struct student *p=&stu;

(* 结构体指针名 ). 成员名 结构体指针名 -> 成员名 结构体变量名 . 成员名

指向运算符优先级 : 1结合方向:从左向右

Ch10_3.c例 指向结构体的指针变量

main(){ struct student { long int num;

char name[20]; char sex; float score;

}stu_1,*p; p=&stu_1; stu_1.num=89101; 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);}

例 int n; int *p=&n; *p=10; n=10

struct student stu1;struct student *p=&stu1;stu1.num=101; (*p).num=101

Page 18: 第九章  结构体与共用体

指向结构体数组的指针例 指向结构体数组的指针struct student{ int num; char name[20]; char sex; int age;}stu[3]={{10101,"Li Lin",'M',18}, {10102,"Zhang Fun",'M',19},

{10104,"Wang Min",'F',20}};main(){ struct student *p; for(p=stu;p<stu+3;p++) printf("%d%s%c%d\n",p->num,p->name,p->sex,p->age);}

numnamesexage

stu[0]

p

stu[1]

stu[2]

p+1

Page 19: 第九章  结构体与共用体

用指向结构体的指针作函数参数用结构体变量的成员作参数 ---- 值传递用指向结构体变量或数组的指针作参数 ---- 地址传递用结构体变量作参数 ---- 多值传递,效率低

Page 20: 第九章  结构体与共用体

struct data{ int a, b, c; };main(){ void func(struct data); struct data arg; arg.a=27; arg.b=3; arg.c=arg.a+arg.b; printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); 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");}

arga :27b: 3c :30

(main)

(func)

parma :27b: 3c :30

copy

arg

a :27b: 3c :30

(main)

(func)

parma :18b: 5c :90

arga :27

b: 3

c :30

(main)

arga :27

b: 3

c :30

(main)例 用结构体变量作函数参数

Page 21: 第九章  结构体与共用体

struct data{ int a, b, c; };main(){ void func(struct data *parm); struct data arg; arg.a=27; arg.b=3; arg.c=arg.a+arg.b; printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); 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");}

arga :18b: 5c :90

(main)

arga :27b: 3c :30

(main)例 用结构体指针变量作函数参数

arga :27b: 3c :30

(main)

(func)

parm****

arga :18b: 5c :90

(main)

(func)

parm****

Page 22: 第九章  结构体与共用体

struct tm { int hours,minutes,seconds;};main(){ struct tm time; time.hours=time.minutes=time.seconds=0; clrscr(); printf("Now, press any key to begin my clock..."); getch(); for(;;) { update(&time); display(&time); }}update(struct tm *t){ (*t).seconds++; if ((*t).seconds==60) { (*t).seconds=0; (*t).minutes++; } if ((*t).minutes==60) { (*t).minutes=0; (*t).hours++; } if((*t).hours==24) (*t).hours=0; delay();}

display(struct tm *t){ clrscr(); printf("%d:",(*t).hours); printf("%d:",(*t).minutes); printf("%d\n",(*t).seconds);}delay(){ long int t; for(t=1;t<=11128000;++t);}

Page 23: 第九章  结构体与共用体

§ 9.7 链表

特点:• 按需分配内存• 不连续存放• 有一个“头指针”( head )变量• 每个结点中应包括一个指针变量,用它存放下一结点的

地址。• 最后一个结点的地址部分存放一个“ NULL” ( 空地址)。

Page 24: 第九章  结构体与共用体

链表结点定义形式

§定义形式: struct student { int number; char name[6]; struct student *next; };

Page 25: 第九章  结构体与共用体

链表操作常用技术语句§p=p->next 在链表结点间顺序移动指针 将 p 原来所指结点中 next 的值赋给 p ,而 p->next 值即下一结点起始地址,故 p=p->next 的作用是使 p 指向下一结点起始地址。 §p2->next=p1 将新结点添加到现在链表中 如果 p2 是链表中的末结点, p1 指新建结点,此句的功能是使 p1 所指新结点变成链表中的新的末结点。 §p2->next=NULL 让 p2 所在结点成为链表中最后结点

Page 26: 第九章  结构体与共用体

示例若已建立下面的链表结构,指针 p指向某单向链表的首结点,如下图所示。struct node

{

int data;

struct node *next;

} *p;

以下语句能正确输出该链表所有结点的数据成员 data 的是 。

A) for ( ;p!=NULL;p++) printf(“%7d,”,p->data); B) for ( ;!p;p=p->next) printf(“%7d,”,(*p).data);

C) while (p) { printf(“%7d,”,(*p).data); p=p->next; } D) while (p!=NULL) { printf(“%7d,”, p->data); p++; }

答案: C

Page 27: 第九章  结构体与共用体

链表指针 p++ 表示什么?main() { struct stu { int num; char *name; int age; }st={12,"ABC",100},*p=&st; clrscr(); printf("%p\n",p++); printf("%p\n",p++); printf("%p\n",p++); printf("%p\n",p++); printf("%d\n",sizeof(st)); }

结果: FFD8 FFDE FFE4 FFEA 6

结论: 若 p 指向某个结构体变量,则 p++ 的功能是将指针p 移到本结点后的存储单元,而不是本结点的下一个成员处。所以链表中不能用 p++ 进行结点间的跳转。

Page 28: 第九章  结构体与共用体

静态链表的建立#define NULL 0struct student{ long num; float score; struct student *next;};main() { struct student a,b,c,*head,*p; a.num=99101;a.score=89.5; b.num=99103;b.score=90; c.num=99107;c.score=85; head=&a; a.next=&b; b.next=&c; c.next=NULL; p=head; do { printf("%ld,%.1f\n",p->num,p->score); p=p->next; }while(p!=NULL);}

注意有关技巧:结点是如何定义的?结点是如何建立的?如何使诸结点形成链表?最后一个结点如何建立?如何从一个结点转到下一结点?如何遍历所有结点?

Page 29: 第九章  结构体与共用体

二、内存分配函数1 、“动态内存分配”的概念 使用户程序能在运行期间动态地申请和释放内存空间,从而更有效地利用内存并提高程序设计的灵活性。 如,为了保证程序的通用性,最大需要建立一个 1000 个元素的字符数组,每个数组元素占 30 个字符,共需 30000 个字节存储空间。但程序某次运行时,可能只使用 30 个数组元素,于是就有 29100 个字节的已分配存储空间被浪费。 此时,可通过动态内存分配技术,将程序设计成运行时才向计算机申请内存,并在用完时立即释放占用的内存空间。 使用动态内存分配技术建立的链表称为“动态链表”。

Page 30: 第九章  结构体与共用体

2 、动态内存分配函数 以下函数在 malloc.h 或 stdlib.h 中定义( n,x 为无符

号整数, p 为指针变量):§ void *malloc(x) 分配一个长度为 x 字节的连续空间,分配成功返回起

始地址指针,分配失败(内存不足)返回 NULL§ void *calloc(n,x) 分配 n 个长度为 x 字节的连续空间(成败结果同上)§ void *realloc(p,x) 将 p 所指的已分配空间大小调整为 x 个字节§ void free(p) 将由以上各函数申请的以 p 为首地址的内存空间全部

释放

Page 31: 第九章  结构体与共用体

动态内存分配函数使用示例

#include "stdlib.h"main( ){ char *p; p=(char *)malloc(17); if (!p) { printf(" 内存分配出错 "); exit(1); } strcpy(p,"This is 16 chars"); /* 如果超过 16 个字符,可能破坏程序其他部分 */ p=(char *)realloc(p,18); if (p==NULL) { printf(" 内存分配出错 "); exit(1); } strcat(p,"."); puts(p); free(p);}

结果:结果: This is 16 This is 16 chars.chars.

Page 32: 第九章  结构体与共用体

#include<stdio.h>#include<malloc.h>main(){int *p,i; p=calloc(10,sizeof(int)); for(i=0;i<10;i++,p++) *p=2*i; p=p-10;clrscr();for(i=0;i<10;i++,p++)printf("%d,",*p); }

Page 33: 第九章  结构体与共用体

动态链表的建立和遍历示例(后进先出的数据结构,即所谓“栈”)

#define NULL 0 struct info{ int data; struct info *next; };main(){ struct info *base,*p; int n; base=NULL;

for(n=0;n<10;n++) for(n=0;n<10;n++) {{ p=(struct info *)malloc(sizeof(struct info));p=(struct info *)malloc(sizeof(struct info)); p->data=n+1;p->data=n+1; p->next=base;p->next=base; base=p;base=p; }} while (p!=NULL)while (p!=NULL) {{ printf("%4d",p->data);printf("%4d",p->data); p=p->next;p=p->next; }}}}

结果: 10 9 8 7 6 5 4 3 2 1

Page 34: 第九章  结构体与共用体

动态链表的建立和遍历示例

#define NULL 0 struct info{

long num;

int score;

struct info *next; };main(){ struct info *head,*p1,*p2; int n=1; clrscr();

head=p1=p2=(struct info *)malloc(sizeof(struct info)); head=p1=p2=(struct info *)malloc(sizeof(struct info)); printf("printf(" 请输入第请输入第 %d%d 个同学的学号和成绩个同学的学号和成绩 :",n++);:",n++); scanf("%ld,%d",&p1->num,&p1->score);scanf("%ld,%d",&p1->num,&p1->score);

while(p1->num!=0)while(p1->num!=0) {{ p1=(struct info *)malloc(sizeof(struct info));p1=(struct info *)malloc(sizeof(struct info)); if(!p1){if(!p1){ printf("printf(" 内存分配出错内存分配出错 ! "); exit();! "); exit(); }} printf("printf(" 请输入第请输入第 %d%d 个同学的学号和成绩个同学的学号和成绩 :",n++);:",n++); scanf("%ld,%d",&p1->num,&p1->score);scanf("%ld,%d",&p1->num,&p1->score); p2->next=p1;p2->next=p1; p2=p1;p2=p1; }}

p2->next=NULL;p2->next=NULL; p1=head;p1=head; while(p1->next!=NULL) {while(p1->next!=NULL) { printf("%ld,%d\n",p1->num,p1->score);printf("%ld,%d\n",p1->num,p1->score); p1=p1->next;p1=p1->next; }}}}

Page 35: 第九章  结构体与共用体

对链表的删除操作

struct student *del(struct student *head,long num){ struct student *p1,*p2; if (head==NULL) {printf("\n 空链表 !\n"); goto end;} p1=head; while (num!=p1->num&&p1->next!=NULL) { p2=p1;p1=p1->next;} /* 非所找结点且非未结点后移 */ if(num==p1->num) /* 找到了 */ { if (p1==head) head=p1->next; /* 为首结点 */ else p2->next=p1->next; /* 非首结点 */ printf("delete:%ld\n",num); n=n-1; } else printf(“%ld not been found!\n”,num); /* 未找到 */end: return(head);}

Page 36: 第九章  结构体与共用体

对链表的插入操作

struct student *insert(struct student *head,struct student *stud){ struct student *p0,*p1,*p2; p1=head; /*p1 指向第一个结点 */ p0=stud; /*p0 指向要插入的结点 */ if(head==NULL) /* 如为空链表 */ {head=p0;p0->next=NULL;} else {while ((p0->num>p1->num)&&(p1->next!=NULL)) { p2=p1; p1=p1->next;} /* 寻找位置 */ if(p0->num<=p1->num) { if(head==p1) head=p0; /* 如最小插在第一个结点前 */ else p2->next=p0; /* 否则插在 p1 所指结点前 */ p0->next=p1;} else {p1->next=p0;p0->next=NULL;}} /* 未找到插在最后 */ n=n+1; return(head);}

Page 37: 第九章  结构体与共用体

§ 9.8 共用体 构造数据类型 , 也叫联合体 用途:使几个不同类型的变量共占一段内存 ( 相互覆盖 )

共用体类型定义定义形式:

union 共用体名{ 类型标识符 成员名; 类型标识符 成员名; …………….} ;例 union data

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

ch

i 类型定义不分配内存

Page 38: 第九章  结构体与共用体

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

形式二 : union data { int i; char ch; float f; }; union data a,b,c,*p,d[3];

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

共用体变量的定义

f

ch

i

f

ch

i

a b

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

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

Page 39: 第九章  结构体与共用体

共用体变量引用引用方式:

例 a.i=1; a.ch=‘a’; a.f=1.5; printf(“%d”,a.i); ( 编译通过,运行结果不对 )

引用规则不能引用共用体变量,只能引用其成员

共用体指针名 -> 成员名共用体变量名 . 成员名 (* 共用体指针名 ). 成员名

union data { int i; char ch; float f; }; union data a,b,c,*p,d[3];

a.i a.ch a.f

p->i p->ch p->f

(*p).i (*p).ch (*p).f

d[0].i d[0].ch d[0].f

共用体变量中起作用的成员是最后一次存放的成员

例 union { int i; char ch; float f; }a; a=1; ()

不能在定义共用体变量时初始化

例 union { int i; char ch; float f; }a={1,’a’,1.5}; ()

可以用一个共用体变量为另一个变量赋值

例 float x; union { int i; char ch; float f; }a,b; a.i=1; a.ch=‘a’; a.f=1.5; b=a; () x=a.f; ()

Page 40: 第九章  结构体与共用体

例 将一个整数按字节输出

01100001 01000001低字节高字节

01000001

01100001

ch[0]

ch[1]

运行结果:i=60501ch0=101,ch1=141ch0=A,ch1=a

main(){ union int_char { int i; char ch[2]; }x; x.i=24897; 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]);}

Page 41: 第九章  结构体与共用体

结构体与共用体区别 : 存储方式不同

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

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

achk

bch k

变量的各成员同时存在

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

联系 : 两者可相互嵌套

Page 42: 第九章  结构体与共用体

例 结构体中嵌套共用体 name num sex job

classposition

Li

Wang

1011

2086

F

M

S

T

501

prof

循环 n 次读入姓名、号码、性别、职务

job==‘s’真

真 假

读入 class读入

position输出

“ 输入错”

循环 n 次job==‘s’

真 假

输出 :姓名 , 号码 ,性别 ,职业 ,班级

输出 :姓名 , 号码 ,性别 ,职业 ,职务

job==‘t’

struct{ int num; char name[10]; char sex; char job; union { int class; char position[10]; }category;}person[2];

Page 43: 第九章  结构体与共用体

例共用体中嵌套结构体,机器字数据与字节数据的处理

00010010 00110100低字节高字节

00110100

00010010

low

high

0x1234

00010010 11111111低字节高字节

11111111

00010010

low

high

0x12ff

struct w_tag{ char low; char high;};union u_tag{ struct w_tag byte_acc; int word_acc;}u_acc;

word_accbyte_acc.low

byte_acc.high

u_acc

Page 44: 第九章  结构体与共用体

§ 9.10 用 typedef 定义类型功能:用自定义名字为已有数据类型命名类型定义简单形式: typedef type name;

例 typedef int INTEGER;类型定义语句关键字已有数据类型名用户定义的类型名例 typedef float REAL;

类型定义后 , 与已有类型一样使用

例 INTEGER a,b,c; REAL f1,f2;

int a,b,c; float f1,f2;

说明 :1.typedef 没有创造新数据类型2.typedef 是定义类型 , 不能定义变量3.typedef 与 define 不同

define typedef预编译时处理 编译时处理简单字符置换 为已有类型命名

Page 45: 第九章  结构体与共用体

typedef 定义类型步骤按定义变量方法先写出定义体 如 int i; 将变量名换成新类型名 如 int INTEGER; 最前面加 typedef 如 typedef int INTEGER; 用新类型名定义变量 如 INTEGER i,j;

例 定义数组类型 int a[100]; int ARRAY[100]; typedef int ARRAY[100]; ARRAY a,b,c;

int a[100],b[100],c[100];

例 定义指针类型 char *str; char *STRING; typedef char *STRING; STRING p,s[10];

char *p; char *s[10];

例 定义函数指针类型 int (*p)(); int (*POWER)(); typedef int (*POWER)(); POWER p1,p2;

int (*p1)(),(*p2)();

例 定义结构体类型 struct date

{ int month;

int day;

int year;

}d;

例 定义结构体类型 struct date

{ int month;

int day;

int year;

}DATE;

例 定义结构体类型typedef struct date

{ int month;

int day;

int year;

}DATE;

例 定义结构体类型 DATE birthday, *p;

struct date { int month; int day; int year; }birthday, *p;

类型定义可嵌套例 typedef struct club

{ char name[20];

int size;

int year;

}GROUP;

typedef GROUP *PG;

PG pclub; GROUP *pclub; struct club *pclub;

GROUP为结构体类型PG为指向 GROUP的指针类型