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
第九章 结构体与共用体§ 9.1 结构体
结构体是一种构造数据类型 用途:把不同类型的数据组合成一个整体 -------自定义数据类型
结构体类型定义
struct [ 结构体名 ]{ 类型标识符 成员名; 类型标识符 成员名; …………….} ;
成员类型可以是基本型或构造型struct 是关键字 ,
不能省略
合法标识符可省 : 无名结构体
例 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 字节
……
..
结构体类型定义描述结构的组织形式 , 不分配内存
例 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;
定义结构体类型的同时定义结构体变量一般形式:
struct 结构体名{ 类型标识符 成员名; 类型标识符 成员名; …………….} 变量名表列;
例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2;
直接定义结构体变量一般形式:
struct{ 类型标识符 成员名; 类型标识符 成员名; …………….} 变量名表列;
例 struct { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2;
用无名结构体直接定义变量只能一次
说明结构体类型与结构体变量概念不同
类型 : 不分配内存; 变量 : 分配内存类型 : 不能赋值、存取、运算 ; 变量 : 可以
结构体可嵌套结构体成员名与程序中变量名可相同,不会混淆
例 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
§ 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)…….. ()
【例】main(){ struct student { int number; char name[6]; char sex; int age; char address[20]; } ; printf("%d\n ",sizeof(struct student)); } 结果: 31
【例】若有以下定义,则正确的赋值语句为 。 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
§ 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”};
形式二: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”};
进行所谓“结构体变量赋值”只能逐个成员进行,不能将结构体变量作为一个整体进行输入和输出。如对结构体变量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” 是错误的。
§ 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
结构体数组初始化
例 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”);
例 统计后选人选票
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
§ 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
指向结构体数组的指针例 指向结构体数组的指针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
用指向结构体的指针作函数参数用结构体变量的成员作参数 ---- 值传递用指向结构体变量或数组的指针作参数 ---- 地址传递用结构体变量作参数 ---- 多值传递,效率低
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)例 用结构体变量作函数参数
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****
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);}
§ 9.7 链表
特点:• 按需分配内存• 不连续存放• 有一个“头指针”( head )变量• 每个结点中应包括一个指针变量,用它存放下一结点的
地址。• 最后一个结点的地址部分存放一个“ NULL” ( 空地址)。
链表结点定义形式
§定义形式: struct student { int number; char name[6]; struct student *next; };
链表操作常用技术语句§p=p->next 在链表结点间顺序移动指针 将 p 原来所指结点中 next 的值赋给 p ,而 p->next 值即下一结点起始地址,故 p=p->next 的作用是使 p 指向下一结点起始地址。 §p2->next=p1 将新结点添加到现在链表中 如果 p2 是链表中的末结点, p1 指新建结点,此句的功能是使 p1 所指新结点变成链表中的新的末结点。 §p2->next=NULL 让 p2 所在结点成为链表中最后结点
示例若已建立下面的链表结构,指针 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
链表指针 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++ 进行结点间的跳转。
静态链表的建立#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);}
注意有关技巧:结点是如何定义的?结点是如何建立的?如何使诸结点形成链表?最后一个结点如何建立?如何从一个结点转到下一结点?如何遍历所有结点?
二、内存分配函数1 、“动态内存分配”的概念 使用户程序能在运行期间动态地申请和释放内存空间,从而更有效地利用内存并提高程序设计的灵活性。 如,为了保证程序的通用性,最大需要建立一个 1000 个元素的字符数组,每个数组元素占 30 个字符,共需 30000 个字节存储空间。但程序某次运行时,可能只使用 30 个数组元素,于是就有 29100 个字节的已分配存储空间被浪费。 此时,可通过动态内存分配技术,将程序设计成运行时才向计算机申请内存,并在用完时立即释放占用的内存空间。 使用动态内存分配技术建立的链表称为“动态链表”。
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 为首地址的内存空间全部
释放
动态内存分配函数使用示例
#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.
#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); }
动态链表的建立和遍历示例(后进先出的数据结构,即所谓“栈”)
#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
动态链表的建立和遍历示例
#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; }}}}
对链表的删除操作
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);}
对链表的插入操作
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);}
§ 9.8 共用体 构造数据类型 , 也叫联合体 用途:使几个不同类型的变量共占一段内存 ( 相互覆盖 )
共用体类型定义定义形式:
union 共用体名{ 类型标识符 成员名; 类型标识符 成员名; …………….} ;例 union data
{ int i; char ch; float f; }; f
ch
i 类型定义不分配内存
形式一 : 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
共用体变量定义分配内存 ,长度 =最长成员所占字节数
共用体变量任何时刻只有一个成员存在
共用体变量引用引用方式:
例 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; ()
例 将一个整数按字节输出
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]);}
结构体与共用体区别 : 存储方式不同
struct node{ char ch[2]; int k;}a;
union node{ char ch[2]; int k;}b;
achk
bch k
变量的各成员同时存在
任一时刻只有一个成员存在
联系 : 两者可相互嵌套
例 结构体中嵌套共用体 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];
例共用体中嵌套结构体,机器字数据与字节数据的处理
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
§ 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预编译时处理 编译时处理简单字符置换 为已有类型命名
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的指针类型