第11章 结构体与共用体
C语言程序设计第十一章 结构体与共用体

11 结构体与共用体 (1)11.1 定义一个结构的一般形式 (1)11.2 结构类型变量的说明 (2)11.3 结构变量成员的表示方法 (4)11.4 结构变量的赋值 (4)11.5 结构变量的初始化 (5)11.6 结构数组的定义 (5)11.7 结构指针变量的说明和使用 (7)11.7.1 指向结构变量的指针 (7)11.7.2 指向结构数组的指针 (9)11.7.3 结构指针变量作函数参数 (10)11.8 动态存储分配 (11)11.9 链表的概念 (12)11.10 枚举类型 (14)11.10.1 枚举类型的定义和枚举变量的说明 (14)11.10.2 枚举类型变量的赋值和使用 (15)11.11 类型定义符typedef (16)11 结构体与共用体11.1 定义一个结构的一般形式在实际问题中,一组数据往往具有不同的数据类型。
例如,在学生登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。
显然不能用一个数组来存放这一组数据。
因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。
为了解决这个问题,C语言中给出了另一种构造数据类型——“结构(structure)”或叫“结构体”。
它相当于其它高级语言中的记录。
“结构”是一种构造类型,它是由若干“成员”组成的。
每一个成员可以是一个基本数据类型或者又是一个构造类型。
结构既是一种“构造”而成的数据类型,那么在说明和使用之前必须先定义它,也就是构造它。
如同在说明和调用函数之前要先定义函数一样。
定义一个结构的一般形式为:struct 结构名{成员表列};成员表列由若干个成员组成,每个成员都是该结构的一个组成部分。
对每个成员也必须作类型说明,其形式为:类型说明符成员名;成员名的命名应符合标识符的书写规定。
例如:struct stu{int num;char name[20];char sex;float score;};在这个结构定义中,结构名为stu,该结构由4个成员组成。
c程序设计 第十一章 结构体与共用体

11.2 定义结构体类型变量的方法
• 4、对结构体中的成员,可以单独使用,他的作用与地位 • 相当于普通变量。
11.3 结构体变量的引用
• • • • • • • • • • • 引用形式: 结构体变量名.成员名 规则: 1、不能将结构体变量作为一个整体进行赋值、输入和输 出,只能对结构体中的各个成员分别进行;但允许将一个 结构体变量直接赋值给另一个具有相同结构的结构体变 量。 如: student1.num=10010; student1=student2; 2、如果成员本身又属一个结构体类型,则要用若干个成 员运算符,一级一级地找到最低的一级的成员。只能对最 低级的成员进行赋值或存取以及运算。 如:student1.num student1.birthday.month
11.6 指向结构体类型数据的指针
• • • • • • • • • • • • • • 试分析以下几种运算: p -> n p -> n++ ++ p -> n 例11.3 指向结构体变量的指针的应用 #include<stdio.h> #include<string.h> void main( ) { struct student { long num; char name[20]; char sex; float score; };
11.5 结构体数组
• • • • • • • • • 例10.2 候选人得票的统计程序。设三个候选人,每次输 入一个得票的候选人的名字,要求最后输出候选人的得票 结果。 #include<stdio.h> #include<string.h> struct person { char name[20]; int count; } leader[3]={“Li”, 0, “Zhang”, 0, “wang”, 0};
第11章结构体和共同体

6
2011-7-18
11.1 结构体
11.1.2 结构体变量的定义与初始化 1. 结构体类型变量的定义 在定义结构体类型的同时定义变量 struct 结构体名
{ 成员定义表; 成员定义表; }变量名表; 变量名表; 例如: 例如:
7
struct student { char num[8],name[20],sex; num[8],name[20],sex; int age; age; float score; score; }st[30]; st[30]
按照结构体类型的组成, 按照结构体类型的组成,系统为定义的结构体 变量分配内存单元。 变量分配内存单元。结构体变量的各个成员在内存 中占用连续存储区域,结构体变量所占内存大小为 所占内存大小 中占用连续存储区域,结构体变量所占内存大小为 结构体中每个成员所占用内存的长度之和 每个成员所占用内存的长度之和。 结构体中每个成员所占用内存的长度之和。
C 语言程序设计
第11章 结构体与共用体 11章
浙江林学院 信息工程学院
11.1 结构体
11.1.1 结构体与结构体类型的定义 信息管理
2
一个学生的信息有学号、姓名、性别、年龄、住 一个学生的信息有学号、姓名、性别、年龄、 学号 成绩等 址、成绩等。 分类编号、 一本图书的信息有分类编号 书名、作者、 一本图书的信息有分类编号、书名、作者、出版 出版日期、价格、库存量等 社、出版日期、价格、库存量等。 如何描述这些类型不同的相关数据? 如何描述这些类型不同的相关数据? 结构体——一种构造类型数据 结构体 一种构造类型数据 结构体由若干不同类型的数据项组成, 结构体由若干不同类型的数据项组成, 由若干不同类型的数据项组成 构成结构体的各个数据项称为结构体成员 结构体成员。 构成结构体的各个数据项称为结构体成员。
第十一章结构体和共用体

一、先定义结构体类型再定义结构体变量
•
struct 结构体类型名
{ 类型标识符 成员名;
:
类型标识符 成员名;
};
struct 结构体类型名 变量名1,变量名2...;
例如:struct student { char number[10]; char name[20]; char sex; int age; float score[20]; char addr[30]; }; struct student x1,x2;
程序如下: struet person { char name[20]; int count; } leader[3]={"Li", o,"Zhang" , o, " Fang ", o};
main ( ) {int i, j;
chr leader_name[20]; for (i=1; i<=10; i++)
• printf("%ld %-15s %3c %6d %6.2f\n",student[i].num,student[i].name,
•
student[i].sex,student[i].age,student[i].score);
•}
第四节 结构体变量的初始化
与其它变量的初始化完全一样,结构体变量在定 义时可初始化:
3、用“&”运算符可以取结构体变量的首地址 和某个成员的首地址。例如:
printf(“%d\n”,&stud); scanf(“%c\n”,&stud.sex);
scanf(“%d\n”,&stud.birthday.month);
C语言编程:第十一章结构体与共用体

10010 Li Fun M 18 87.5 Bejing
Zhang Sumin (South China Agriculture University Computer Department ,Guangzhou 510640) zsmhome@
Zhang Sumin (South China Agriculture University Computer Department ,Guangzhou 510640) zsmhome@
11.3 结构体变量的引用
结构体变量的引用应该遵循以下原则 • 1)不能将一个结构体变量作为一个整体进行输入和
2)结构体名同标识 符命名规则;
3)分号不能省略
4)成员列表又称“域表”,每个成员也称为域。
5)指定一个结构体类型相当于指定了一个模型,它无 数据,系统对其不分配实际内存单元。
Zhang Sumin (South China Agriculture University Computer Department ,Guangzhou 510640) zsmhome@
struct { int num;
char name[10]; char sex;
int age; float score; char addr[30]; } student1,student2;
(3)
Zhang Sumin (South China Agriculture University Computer Department ,Guangzhou 510640) zsmhome@
第11章 结构体和共同体-PPT精选文档

C语言 程序设计
第11章 结构体和共同体
二、结构体变量的定义
(1) 先定义结构体类型,再定义结构体变量 struct student { long num; 结构体变量占用内存大 小为各成员占用内存大 char name[20]; 小之和,可用sizeof(结构 int score[4]; 体类型名)或sizeof(结构 }; 体变量名)求出 struct student b;
Page 10
C语言 程序设计
第11章 结构体和共同体
void main ( ) { struct student { long num; 定义结构体类型和变量 char name[20]; int score[4]; } b; int i; 输入结构体 printf("请输入学生的学号和姓名\n"); 变量的值 scanf("%ld%s",&b.num,); printf("请输入学生的四门课考试成绩\n"); for(i=0;i<4;i++) scanf("%d",&b.score[i]); printf("%10ld %-20s",b.num,); for(i=0;i<4;i++) printf(" %5d",b.score[i]); 输出结构体 printf("\n"); } Page 11 变量的值
Page 4
C语言 程序设计
第11章 结构体和共同体
11.2 结构体类型和结构体变量 的定义和使用
结构体类型需要自定义,先定义结构体类型
后,再定义结构体变量。
第11章结构体及共用体

3)用结构体变量和指向结构体的指针作函数参数
把结构传递给函数有三种方式: 单个成员 整个结构 指向结构的指针
1、成员传递:用结构变量成员作为实参(值传递)
例如:对于上面定义的结构变量stu_1有四个成员。 其中任何一个都可以做实参。
void main()
{……
{ prin(stu_1.num);
低一级的成员,对它进行赋值或存取以及运算. student1.birthday.month student1.birthday
3)成员可以像普通变量一样进行各种运算.
student2.score= student1.score;
2020/10/1s3tudent1.age++;
6
11.4 结构体变量的初始化
:
}}
2020/10/13
15
2、结构传递(全体传递,多值传递): 用结构变量作实参
将结构变量所占的内存单元内容全部顺序传递给形参(值 传递),由于采用值传递内存开销大、在被调函数中改变 的形参值不能返回主调用函数,因此在使用上很不方便。 eg11.5.c
3、传引用调用(地址传递): 定义结构指针变量并以此指针作为实参
例 paaa––r...upiicf}nn=不可==h;ti&11=fo能以f(;.‘nla“5ao用在例;%;d’a;一定atdt例f”例a个义;u{,}aan共共a.,iib=fuu{o){}ai用 用cfl,;n}n{nnolc=haoai1it,a体 体;ao1o*a,icftibri’nn;npt;l变 变hnao;ctx,fat’da;h量 量i;,rit;[1;;3cf时 为.(5]h;;c};另初编h(;a一始(d译)r*[个化cp(0通h)]变..;)ii过量fl(,o赋d*a[p值运t0)]f..c;行chh结(*果pd)[.不0f].对f ) a.i=1; a.ch=‘a’; a.f=1.5;
第11章结构体、共用体和枚举数据类型(教案).docx

第十一章结构体、共用体和枚举数据类型【目的要求】一、了解:结构变量和结构指针作函数实参的区别;枚举型变量概念、特点与应用;typedef的用途二、理解:结构体、共用体的概念和特点;类型说明和变量定义的区别;单向链表的概念和作用三、学握:结构体、共用体的类型说切、变量定义及使用;结构体数组的定义和初始化(重点);链表的建立、删除和插入(难点)第一节结构体一、结构体的定义格式询而学过的变量都只能定义单一的数据类型,如字符型、整型、实型等等,但是对于复朵的数据,即包含有一个或者多个数据项,各数据项可以具有相同或者不同的类型,并且何个数据项的含义不同,以前的知识就不足了。
例如对于学生实体的描述,学牛有姓名,学号,成绩,性别等等。
我们要描述一个学生需要多个基本变量的组合(集成)。
这种数据类型在Pascal语言中称为记录,在C语言中称为结构体。
它们是数据库的雏形。
num Name S(2X age score address10010 Li Fun M18 87. 5 Beijing10011 Zhang San M21 67 Fuzhou10012 Li si F22 88 Jinan10013 Wang Hai M20 72 Haikou在上述的信息中,每一行代表一个人的信息,有学号、姓名、性别、年龄、成绩、地址等信息,以前学过的任何-•种数据类型均不能表示,而分别表示乂违背了信息的集成原则, 用起来也不方便。
数组的特征是每个元素都是同质(identical)的,不能表示不同的数据类型。
因此,为了把这么多种基本数据类型集合在一起,发明了结构体。
在Pascal语言中叫记录。
定义方式如下:struct student{ int num;char name[20];char sex;int age;float score;char addr[30];};上述并非定义一个变量,或者一个存储空间,而是定义了一个新的结构体类型structstudent (它的地位等同于i nt char等数据类型描述)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第十一章 结构体与共用体 结构体变量引用规则: (1) 不能将一个结构体变量作为一个整体进行输入和输出;只能对结构体变量中的各个成员分别进行输入和输出。“.”是成员(分量)运算符,它在所有的运算符中优先级最高。 (2) 若成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。 (3) 对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。 (4) 可以引用结构体变量成员的地址,也可以引用结构体变量的地址。
—>是指向运算符,优先级为第一级。 结构体变量所占的内存长度是各成员所占内存长度之和。每个成员分别占有其自己的内存单元。 共用体变量所占的内存长度等于最长的成员的长度。
只先有定义了共用体变量才能引用它,而且不能引用共用体变量,而只能引用共用体变量中的成员。
将一个变量定义为结构体类型:不仅要求指定变量为结构体类型,而且要求指定为某一特定结构体类型。
类型与变量的区别: 定义时先定义结构体类型,然后定义变量。类型不分配空间,变量分配空间。
可以采取以下3种方法定义结构体类型变量: (1)先声明结构体类型再定义变量名 例如:struct student student1, student2; | | | 结构体类型名 结构体变量名 (2)在声明类型的同时定义变量 ;这种形式的定义的一般形式为: struct 结构体名 { 成员表列 }变量名表列; (3) 直接定义结构体类型变量 其一般形式为: struct { 成员表列 }变量名表列; 即不出现结构体名。
引用结构体变量中成员的方式为 结构体变量名.成员名 注意: (1) 将一个变量定义为标准类型(基本数据类型)与定义为结构体类型不同之处在于后者不仅要求指定变量为结构体类型,而且要求指定为某一特定的结构体类型,因为可以定义出许许多多种具体的结构体类型。 (2)对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。 (3)成员也可以是一个结构体变量。 (4) 成员名可以与程序中的变量名相同,二者不代表同一对象。
在定义了结构体变量以后,当然可以引用这个变量。但应遵守以下规则: (1)不能将一个结构体变量作为一个整体进行输入和输出。 例如: 已定义student1和student2为结构体变量并且它们已有值。 (2) 如果成员本身又属一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。 (3) 对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。 (4) 可以引用结构体变量成员的地址,也可以引用结构体变量的地址。
结构体变量的地址主要用作函数参数,传递结构体变量的地址。 一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。指针变量也可以用来指向结构体数组中的元素.
以下3种形式等价: (1) 结构体变量.成员名 (2)(*p).成员名 (3)p->成员名 其中->称为指向运算符。 p->n得到p指向的结构体变量中的成员n的值。
将一个结构体变量的值传递给另一个函数,有3个方法: (1)用结构体变量的成员作参数。 (2) 用结构体变量作实参。 (3) 用指向结构体变量(或数组)的指针作实参,将结构体变量(或数组)的地址传给形参.
库函数提供动态地开辟和释放存储单元的有关函数: (1)malloc函数 其函数原型为void *malloc(unsigned int size); 其作用是在内存的动态存储区中分配一个长度为size的连续空间。此函数的值(即“返回值”)是一个指向分配域起始地址的指针(类型为void)。如果此函数未能成功地执行(例如内存空间不足),则返回空指针(NULL)。 (2) calloc函数 其函数原型为void *calloc(unsigned n,unsigned size);其作用是在内存的动态存储区中分配n个长度为size的连续空间。函数返回一个指向分配域起始地址的指针;如果分配不成功,返回NULL。 用calloc函数可以为一维数组开辟动态存储空间,n为数组元素个数,每个元素长度为size 。 (3) free函数 其函数原型为void free(void *p);其作用是释放由p指向的内存区,使这部分内存区能被其他变量使用。p是最近一次调用calloc或malloc函数时返回的值。free函数无返回值。 stu定义为指针变量,在需要插入时先用malloc函数开辟一个内存区,将其起始地址经强制类型转换后赋给stu,然后输入此结构体变量中各成员的值。对不同的插入对象,stu的值是不同的,每次指向一个新的struct student变量。在调用insert函数时,实参为head和stu,将已建立的链表起始地址传给insert函数的形参,将stu(即新开辟的单元的地址)传给形参stud,返回的函数值是经过插入之后的链表的头指针(地址)
定义共用体类型变量的一般形式为: union 共用体名 { 成员表列 }变量表列;
共用体和结构体的比较: 结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。 共用体变量所占的内存长度等于最长的成员的长度。
只有先定义了共用体变量才能引用它,而且不能引用共用体变量,而只能引用共用体变量中的成员。
共用体类型数据的特点 (1)同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种。 (2) 共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。 (3) 共用体变量的地址和它的各成员的地址都是同一地址。 (4) 不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,又不能在定义共用体变量时对它初始化(注意:结构体变量可以)。 (5) 不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可以使用指向共用体变量的指针 (6) 共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。
说明: (1)在C编译中,对枚举元素按常量处理,故称枚举常量。它们不是变量,不能对它们赋值。 (2) 枚举元素作为常量,它们是有值的,C语言编译按定义时的顺序使它们的值为0,1,2… (3) 枚举值可以用来作判断比较。 (4) 一个整数不能直接赋给一个枚举变量。
说明: (1)用typedef可以声明各种类型名,但不能用来定义变量。 (2) 用typedef只是对已经存在的类型增加一个类型名,而没有创造新的类型。 (3) 当不同源文件中用到同一类型数据时,常用typedef声明一些数据类型,把它们单独放在一个文件中,然后在需要用到它们的文件中用#include命令把它们包含进来。 (4) 使用typedef有利于程序的通用与移植。 (5) typedef与#define有相似之处,例如:typedef int COUNT;#define COUNT int的作用都是用COUNT代表int。但事实上,它们二者是不同的。#define是在预编译时处理的,它只能作简单的字符串替换,而typedef是在编译时处理的。实际上它并不是作简单的字符串替换,而是采用如同定义变量的方法那样来声明一个类型 用typedef定义类型的方法(举例) ① 先按定义数组变量形式书写:int n[100]; ② 将变量名n换成自己指定的类型名: int NUM[100]; ③ 在前面加上typedef,得到 typedef int NUM[100]; ④ 用来定义变量:NUM n;
用typedef声明新的类型名来代替已有的类型名 声明INTEGER为整型 typedef int INTEGER 声明结构类型 Typedef struct{ int month; int day; int year;}DATE; 声明NUM为整型数组类型 typedef int NUM[100]; 声明STRING为字符指针类型 typedef char *STRING; 声明POINTER为指向函数的指针类型,该函数返回 整型值 typedef int (*POINTER)( )
结构体是数目固定、类型不同的若干有序变量的集合。 说明: (1)结构体类型中的数据项,既可以是基本数据类型,也允许是另一个已经定义的结构类型。 (2)结构体类型的长度等于各个成员的长度总和。
注意:只有在定义的同时才可以对结构体变量进行整体赋初值。 结构体数组的每一个元素,都是结构体类型数据,均包含结构体类型的所有成员。 链表结构 (1)头指针变量head──指向链表的首结点。 (2)每个结点由2部分组成: 数据──存储结点本身的信息。 指针──指向下一个结点的指针。 (3)尾结点的指针域置为“NULL(空)”,作为链表结束的标志。
(1)枚举元素是常量,不能对其作赋值运算。 (2)枚举元素用一个数值来表示其定义时的先后顺序,默认从0开始。 (3)枚举元素的值也可以人为指定。 (4)枚举元素可以根据顺序号的大小进行比较。 可以用“%d”输出枚举元素的顺序号。 但不能直接用顺序号给枚举变量赋值。
结构体数组在内存中连续存放。