第10章 结构体与共用体自定义类型标识符结构体的定义与引用共用体的定义与引用10.1 自定义类型标识符一般格式:typedef 原类 型名 新类型名例如: typedef int INTEGER; typedef float REAL;所以有:i nt i;float x;INTEGER i ;REAL x; typedef int ARRAY[100];ARRAY a, b, c;又如: int a[100],b[100],c[100];1、先按定义变量的方法写出定义语句; 如: int a[10];2、将变量名用新类型名替换; 如: int ARRAY[10];3、在最前面 加typedef; 如: typedef int ARRAY[10]; 4、然后可以用新类型名定义变量。 如: ARRAY a,b,c;定义一个新类型的步骤1)用typedef可以定 义各种类型名,但不能用来定义变量。 2)用typedef只能为已经存在的数据类型标识符另起一个新名,而不能创造一种新类型。3)要注 意typedef与#define的区别,如: typedef int SUM; #define SUM int 数组可以表示一组类型相同的数据。 在实际中,通常需要通过一组不同类型的数据共同来描述某 个实体。如:学生个人资料(学号、姓名、性别、年龄和学习成绩)。 C 语言提供的结构体就是这样一种数据类型,它由一组称为 成员(域或元素)的数据成分组成,其中每个成员可以具有不同的类型,用来存放类型不同但又相互有关的数据。 结构体类型:是一 种C语言没有定义、用户可以根据实际需要自己定义的构造型数据类型。10.2 结构体的定义与引用struct 结构体类型标识符{ 类型名1 结构成员名表1; 类型名2 结构成员名表2; …… 类型名n 结构成员名表 n;};如:描述学生基本信息 struct student { int num; char nam e[20]; char sex; int age; float score; };结构体数据类型说明的 一般格式int a[3];成员的组织结构10.2.2 结构体类型变量、数组和指针变量的定义方法1: 先定义结构体类型,再定义结构 体变量如: struct student { int num; char nume[20]; c har sex; int age; float score; }; struct student std, pstd, pers[3];方法2:在定义结构体类型的同时定义结构体变量如: struct student { int num; char name[20]; char sex; int age; float score;} std,pstd, pers[3];stdpers10.2.2 结 构体类型变量、数组和指针变量的定义方法4:使用typedef说明一个结构体类型名,然后用新类型名定义变量方法3:直接定义结构体变量 如: struct { int num; char nume[20]; char sex; int age; float score; } std,pstd, pers[3];如: typedef struct student { int num; char name[20]; char se x; int age; float score; } STREC;STREC std,pstd, pers[3];10.2.2 结构体类型变量、数组和指针变量的定义typedef struct student { int num; char name[20]; char sex; int age; float sc ore; } STREC;STREC std,pstd, pers[3];结构体变量的存储情况: 在内 存中,结构体变量std占据一片连续的存储空间,该空间的首地址为&std 结构体数组pers在内存中占一片连续空间,该空间被等分成 3分,每一份用于保存一个结构体数组元素 结构体指针变量pstd在内存中占一个存储单元,它将保存某个STREC类型变量的地址。如ps td=&std;结构体类型和结构体变量结构体类型说明可以嵌套。 struct date { int month, da y, year ;};struct student { int num; char nume[20] ; char sex; int age; struct date birthday; flo at score; };struct student { int num; cha r name[10]; char sex; int age; struct date { int year; int month; int day; } birthday; float sc ore; };10.2.2 结构体类型变量、数组和指针变量的定义10.2.3 给结构体变量、数组和指针变量的初始 化1、结构体变量的初始化例如:struct student std={20001,"Li Li",’M’,19,85};结构 体变量名={初值};初值的个数、顺序、类型应与成员说明一致2、结构体类型数组的初始化struct 结构体类型标识符 结构体数组名= {初值};例如:struct student pers[2]={{20001,"Li Li",’M’,19,85} {20002,"Wu an",’F’,19,78} };3、结构体指针的初始化struct 结构体类型标识符 指针 变量名=&结构体变量名; 例如: struct student std, sp=&std ;10.2.3 给结构体变量 、数组和指针变量的初始化10.2.4结构体类型变量、数组和指针变量的引用1、对结构体成员的引用 结构体变量名.成员名 (指针 变量名).成员名 指针变量名->成员名std.num=10101; 等价于 sp->num=10101;std.sex=’M’ ; 等价于 (sp).sex=’M’;std.score=75+8;等价于 (sp).score=75+8; std.age++; 等价于 sp->age++;如: struct student{ long num; char name[20]; char sex; int age; float score;}std,p ers[5],sp=&std;(1)结构体类型数组和结构体成员数组:数组元素下标的引用原则结构体类型成员的引用原则引用结构体成员 时要注意以下几点:struct student{ long num; char name[20]; char sex ; int age; float score;}std,pers[5],sp=&std;std.name[2]或s p->name[2]或(sp).name[2]。 不能写作std.name,因为name是数组名。 pers[0].age 或(pers+0)->age或((pers+0)).age。 注意:不能写成pers.age。pers(2)对于结构体嵌套的 情况,只能引用最低层的成员。std.birthday.month或sp->birthday.month或(sp).birthda y.month。struct date { int month, day, year ;};struct stud ent { int num; char nume[20]; char sex; int age; struct date birthday; float score; }st d,sp=&std;引用结构体成员时要注意以下几点:取结构体变量的地址为: &结构体变量名 如:&std取结构体成员的地 址为: &结构体变量名.成员名 如:&std.agestruct student{ long num; char n ame[20]; char sex; int age; float score;}std,pers[5],s p=&std;(3)可以用 “&”对结构体类型变量、数组元素及其成员进行取地址运算了。引用结构体成员时要注意以下几点:(4)请分析 并理解以下几种运算struct student{ long num; char name[20]; char sex ; int age; float score;}std,pers[5],sp=&std;例如有赋值语句:sp=pe rs;++sp->num 与 ++(sp->num)等价sp->num++ 与(sp->num)++等价 ( ++sp)->num(sp++)->num(5)采用(sp).num方式引用成员num时,(sp)两侧的括号不能省略。引用结构 体成员时要注意以下几点:(6)根据定义,指针变量sp只能指向一个结构体类型数据,而不能指向结构体类型数据中的某一成员例如,下面是不 对的:sp=&pers[2].num引用结构体成员时要注意以下几点:10.2.4结构体类型变量、数组和指针变量的引用struct student{ long num; char name[20]; char sex; int age; float score;}std,pers[5],sp=&std;【例10.1】 结构体类型变量的引用示例。【例10.3】 指向结构体变量的指针变量的应用。【例10.4】结构体类型数组指针变量的引用示例。2. 对结构体类型变量的整体赋值允许两个具有同一种 类型的结构体变量之间进行整体赋值操作。例如有以下定义:struct student{ 1ong num; char na me[20]: char sex; int age; float score;} std1,std2={11011 ,“Yang Lin”,’M’,18,89};则在程序中,可以用赋值语句:std1=std2;这样实际上是将std2中各个成员的 值分别赋给了std1中对应的同名成员。10.2.5 函数之间结构体变量的数据传递在函数之间传递结构体类型数据有三种方法 用结构体 变量的成员作参数 c语言允许将结构体变量的成员象普通变量一样传递给一个函数. 10.5 统计一个班及格学生的 人数main(){int count(); int j,ok=0; struct student { int num ; char name[20]; int score; }stu[3];for(j=0;j<3;j++) sca nf("%d%s%d",&stu[j].num,stu[j].name,&stu[j].score);for(j=0;j<3;j+ +) ok+=count(stu[j].score);printf("The result is:%d\n",ok);}in t count(int x){ int m=0; if (x>=60) m=1; return(m);}10.6 用指向结构 体的指针变量作函数参数示例 struct student { int num; char name[20]; in t score; }main(){ void print(struct student p); struct student stu; stu.num=12345; strcpy(stu.name,"LI LI"); stu.score=67.5; print(&stu);}void print(struct student p){ printf("NO.=%d,NAME =%s,SCORE=%d", p->num,p->name,p->score); printf("\n");}10.7 用整个结构体变量作为函数参数struct student { int num ; char name[20];int score; }main(){ void print(struct student p); struct student stu; stu.num=12345; strcpy(stu.name,"LI LI" ); stu.score=67.5; print(stu);}void print(struct student s1){ p rintf("NO.=%d,Name=%s,Score=%d", s1.num,s1.n ame,s1.score); printf("\n");}练习1.若有以下说明和定义typedef int INTEGER; INTEGER p,q;以下叙述正确的是( )。A. p是int型变量B. p是基类型为int的指针变量C. q是基类型为i nt的指针变量D. 程序中可用INTEGER代替int类型名?2. 以下选项中,能定义s为合法的结构体变量的是( )。A. t ypedef struct abc B. struct { double a; { double a; char b[10]; char b[ 10]; } s; } s;C. struct A BC D. typedef ABC { double a; { double a; char b[10]; char b[10]; } } ABC s; ABC s; ?3.设有以下定义语句typedef struct{ int n; char ch[8]; }PER;则下面 叙述中正确的是( )。 A. PER 是结构体变量名 B. PER是结构体类型名 C. typed ef struct 是结构体类型 D. struct 是结构体类型名 ?4. 设有以下定义struct ss{ char n ame[10]; int age; char sex; } std[3], p=std;下面各输入语句中错误的是( )。 A. scanf(“%d”,&(p).age); B. scanf("%s",&std.name); C. scanf(“%c”,&std[0].sex); D. scanf("%c",&(p->sex));?上节回顾s truct student { int num; char name[20]; }; struct student std,sp[2]; char name[20]; int i;stdspnamestd.num, i std.name, namescanf(“%d%d”,&std.num,&i);scanf(“%s%s”,std.name, name);1、共用体的概念 共用体是指不同类型的数据可以在不同的时间内使用共同的内存单元。 共用体实际上是c语言提供的一种覆盖技术。10.3 共 用 体 char sexint num float score1 0.3.1 共用体的定义和使用 “共用体”类型变量的定义形式为: union 共用体名 { 类 型名1 共用体成员名表1; 类型名2 共用体成员名表2; …… 类型名n 共用体成员名表n; }; union student { int num; char sex; float score; } stu1 ,stu2;也可以将类型定义与变量定义分开,例如: union student { int num; char sex; float score; }; union student stu1,stu2;3、共用体变量 的引用方式共用体的使用也与结构体相同,用&取共用体的地址,用“.”或“-〉”访问共用体成员。例如: stu1.n um(引用共用体变量中的整型变量num) stu1.sex(引用共用体变量中的字符变量sex) stu1.score(引用共用体变量中的实型变量score) 1、同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时 只能存放其中一种。 2、共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。如有以下赋值 语句: stu1.num=101; stu1.sex= ’F’; stu1.score=89.5;在完成以上三个赋值运算以后,只有stu1.scor e是有效的,stu1.num和stu1.sex已经无意义了。共 用 体 使 用 说 明3、共用体变量的地址和它的各成员的地址都是同 一地址4、共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用 体的成员。struct date{ int day, month, year; union { int sh1 ; float sh2;}sh;} a;a.daya.montha.yeara.sh.sh1a.sh.sh2举 例例 10.13 分析下列程序的运行结果 main(){ union { char c[4]; int k; }r; r.c[0]=''2''; r.c[1]=''0''; r.k=20; printf("%d,%d,%d\n",r.k,r.c[0],r.c[1]);}20,20,0r20 00000000000101000000000000000000【例10.14】分析下列程序的输出结果 union as { int a, b; }s[3],p;main(){ int n=1,k; for(k=0;k<3;k++) { s[k].a=n; s[k].b=s[k].a2; n+=2; } p=s; printf("\n%d\n",p->a);}s123365105pback 以下程序的运行结果是 。union myun{ struct { int x, y, z; } u; int k; } a;main(){ a.u.x=4; a.u.y=5; a.u.z=6; a.k=0; printf("%d\n",a.u.x); }a0 |
|