570 likes | 729 Views
11 结构、联合和枚举. 本章目标. 1. 理解结构体,联合体和枚举的数据类型. 2. 学会定义结构体、联合体的数据类型的变量. 3. 学会定义和使用枚举常量. 4. 能够正确使用结构体、联合体的成员. 5. 用结构指针作为函数的参数. 1 引言. 已了解的数据类型:. 整型. 简单数据类型. 浮点型. 字符型. 用户定义的数据类型. 数组. 特点:所有的元素都是同一种类型. 存在的问题: 难以处理较复杂的数据. 如: 建立一份学生档案,对每一个学生至少需要以下一些信息。. 学号 (unsigned no)
E N D
11 结构、联合和枚举 本章目标 1.理解结构体,联合体和枚举的数据类型 2.学会定义结构体、联合体的数据类型的变量 3.学会定义和使用枚举常量 4.能够正确使用结构体、联合体的成员 5.用结构指针作为函数的参数
1 引言 已了解的数据类型: 整型 简单数据类型 浮点型 字符型 用户定义的数据类型 数组 特点:所有的元素都是同一种类型 存在的问题:难以处理较复杂的数据
如:建立一份学生档案,对每一个学生至少需要以下一些信息。如:建立一份学生档案,对每一个学生至少需要以下一些信息。 学号(unsigned no) 姓名(char name[20]) 性别(char sex) 年龄(int age) 成绩(float score) 地址(char addr[30])
C 程序可将上述数据的集合定义为一种结构体类型: struct student { unsigned num; char name[20]; char sex; int age; float score; char addr[30]; };
2 结构的定义 一、结构体定义的一般形式: struct 结构体名 { 成员表列 } ; 成员表列的写法:类型标识符 成员名
注意: 1.这只是定义一种类型的方法,尚未定义变量。 2.struct –––关键词(保留字),表示定义一种结构体类型。
如:struct exp 结构体名 { int times; char flag; 成员表列 float meter ; };
二、结构变量的定义 有三种方法可用来定义结构体变量: 1. 先定义结构体类型再定义结构体变量 例:struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; };
结构体变量定义: struct student x1, x2; 类型标识符 则 x1, x2为student 结构型变量,x1, x2可存放student类型数据。
2. 在定义结构体类型的同时定义变量: 定义形式 struct 结构体名 { 成员表列} 变量名表列; 例:struct student { int num; char name[20]; char sex; int age; char addr[30]; } x1, x2;
3. 直接定义结构类型变量 定义形式 struct {成员表列} 变量名表列; 不出现结构体类型名 如:struct { int num char name[20]; char sex; int age; char addr[30]; } x1, x2;
几点说明: 1. 类型名与变量名是不同的概念 2. 允许成员名又为另一个已定义的结构型变量 3. 每一个成员的作用如同该类型的变量 4. 成员名与程序中的变量名可相同但意义不同
例:结构体的嵌套定义 struct date { int month; int day; int year; }; struct student {int num; char name[20]; char sex; int age; struct date birthday; char addr[30]; } x1, x2;
x1 或x2 birthday num name sex age addr month year day
3 结构的初始化 结构的初始化就是指结构变量的初始化。
一、先定义结构,在定义结构变量时对每个成员赋初值一、先定义结构,在定义结构变量时对每个成员赋初值 如:struct student { unsigned No; char name[20]; char sex; float score; }; struct student x1={8906, "Li Ming ", 'M', 85.5};
2000 8906 No L 2002 i M i name[20] n g \0 2021 M sex 2022 2023 85.5 score 2026 若 x1 的起始地址为2000,则 x1 在内存中占有的存储单元为: 共用27个字节的连续单元
三、结构定义与变量定义及初始化合二为一: struct exp { int a; float b; char yn[8]; } x={1234, 56. 7, "test"}; 但不能这样写: struct exp { int a=1234; float b=56.7; char yn[8]="test"; } x;
4 访问结构成员 访问结构变量实质上是引用其成员 有两种运算符可访问结构成员 一、圆点运算符 如:x1为struct student型变量,则 x1.No: 表示x1的学号 x1.name: 表示x1的名字
注意: 1. 只能用变量的成员,不可用结构变量名直接运算。 2. 每一个成员的作用与其同类型的简单变量的引用相同。
二、箭头运算符: 例:struct student { char name [10]; char sex; int age; float score; char addr[20]; }x1; struct student p;
x1 p name sex age score addr 则p为结构指针变量,它可用来存放student型变量的地址 令 p=&x1; 则 p为x1的首地址. 访问结构成员: pname 等价于 (*p).name pname 表示x1的姓名; page 等价于 (*p).age page 表示x1的年令;
小结: 引用结构变量中的成员有三种方法: (1) 结构体变量名.成员名 x1.num (2) 用指针变量 (p).成员名 (p).num (3) 用指向运算符成员名 p num 注意:指针变量p必须是结构指针型, 且有p=&x1;
三、关于结构变量的几点说明: 1. 结构变量不是一个简单变量,它的值是由许多个基本数据组成。 2. 可以把一个结构变量赋给另一个同类型的结构变量。
如:struct temp { int a; ch ch; } x1, x2; main ( ) { x1.a=10; x1.ch='a'; x2=x1; 把结构变量x1的值赋给结构变量x2. printf("%d, %c", x2. a, x2.ch); }
3.占有的存储单元大小取决于成员的数据类型 如:struct exp { int a; float b; char yn[8]; }; struct exp x={1234,56.7, "text"} 结构变量占用的内存单元为14个字节。
struct temp { int a; char ch; } x1, x2; main( ) {x1.a=10; x2.ch='a'; if(x1= =x2) } 4. 不可以将两个结构变量进行关系比较 非法语句
5.可通过sizeof ( )运算符获得结构变量占用的内存大小 如:struct exp { int num; char ch; char name[20]; float sal; } x1; main( ) { int size; size=sizeof(x1); printf("size=%d\n", size); }
6. 结构变量的输入/输出 只能对结构变量的成员进行输入/输出 若有struct student h; 则:scanf("%s", &h); 错误 printf("%s", h); 原因:结构体变量中包含有多个不同类型的数据项。 正确方法:对结构体变量各成员的值进行输入/输出。 如:scanf("%d%s", &h.num, h.name); printf("%d%s", h.num, h.name);
四、程序实例 例1:请指出下列程序的错误所在: struct person { char name[20]; int count; } x1={"ZhongHua", 10}; main( ) { int *p; 错误的原因:p不是结构指针变量 p=&x1; printf ("%s\n%d\n", (*p).name, (*p).count) } 可改为:struct person *p;
例2:编写一个统计得票数的程序,假定有三个侯选人,每一侯选人的数据包括其姓名和得票数。例2:编写一个统计得票数的程序,假定有三个侯选人,每一侯选人的数据包括其姓名和得票数。 可定义结构类型person和结构数组leader struct person { char name[20]; int count; } leader[3]={"Li", 0,"Zhang" , 0, " Hang ", 0};
程序如下: struct person { char name[20]; int count; } leader[3]={"Li", 0,"Zhang" , 0, " Hang ", 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++; } printf ("\n"); for (i=0; i<3; i++) printf("%5s : %d\n", leader[i].name, leader[i].count); }
输入: Li Li Hang Zhang Zhang Hang Li Hang Zhang Li 显示: Li : 4 Zhang : 3 Hang : 3 name count Li 0 Zhang 0 0 Hang 运行情况如下:
5 结构和函数 把结构变量的数据传给函数的参数有三种方式: ·传递单个成员的值; 传值调用 ·传递整个结构; ·传递指向结构的指针; 传引用调用
例1.把整个结构传递给参数 #include <stdio.h> struct tree { int x; char *s; } t; void fun(struct tree t ) { t.x=t.x+10; t.s="computer"; return; }
main( ) { t.x=6; t.s="minicomputer"; func(t); printf("%d, %s\n", t.x, t.s); } 程序运行结果:6, minicomputer
例2. 把指向结构的指针作为函数的参数 #include <stdio.h> #include <string.h> struct stu { int num; char name[20]; float score; };
void fun(struct stu *p) { strcpy(p->name, "I am a student"); 不能写成:p->name="I am a student"; 因为name成员是一个字符数组 p->score=p->score+20; p->num=p->mum+10; printf("print in fum:\n"); printf("%d\n%s\n%4.1f\n\n", (*p).num, (*p).name, (*p).score); return; }
main( ) { struct stu student={12, "Zhang hua", 68}; struct stu *sp; sp=&student; printf("1--print in main:\n"); printf("%d\n%s\n%4.1f\n\n",(*sp).num,(*sp).name, (*sp).score); fun(sp); printf("2--print in main:\n"); printf("%d\n%s\n%4.1f\n\n", (*sp).num, (*sp).name, (*sp).score); }
程序运行结果: 1--print in main: 12 Zhang hua 68.0 print in fun: 22 I am a student 88.0 2--print in main: 22 I am a student 88.0
6 类型定义:typedef typedef 的用途:为结构类型建立别名 typedef 的作用:简化结构变量的定义
一、建立别名 typedef <结构类型> <别名> 如:struct person { char name[20]; int age; char tel[15]; }; typedef struct person Person
二、结构变量定义 直接用别名作为类型标识 如:Person student;
.8 联合体 一种自定义的数据类型 一、共用体数据类型的特点 与结构体类似之处:由不同的数据项组成一个整体。 与结构体不同之处:占用的内存单元不同。
二、共用体类型定义 定义方式与结构体类型完全相同。 把结构体类型中的关键字struct换成union即可。
1001 v 1005 n c 1007 2001 c n 2002 v 2003 2004 例:struct memb { float v; stag占内存7个字节的空间 int n; char c; } stag; union memb { float v; utag占的内存空间为 int n; char c; } ustag; 共用体类型变量每次只能存放一个成员的值。
三、共用体类型变量的引用 引用方法同结构体变量: (共用体类型变量名).<成员名> 共用体类型变量的输入输出同结构体类型变量相同。
运行结果:36.7 13107 例:#include<stdio.h> union memb { float v; int n; char c; }; main( ) { union memb utag; utag.c='T '; utag.n=18; utag.v=36.7; printf("%5.1f\n%d\n%c\n", utag.v, utag.n, utag.c); }
? 想一想: 若改变成员的赋值顺序: utag.v=36.7 utag.n=18 utag.c='T ' 则运行结果为:36.5 84 T