9 结构体与共用体
《C语言参悟之旅》第九章 结构体 共用体
2. 第二种形式
这种形式在声明类型的同时定义变量。其一般形式为:
struct 结构体类型名
{
数据类型名 1 成员名 1;
… 数据类型名 n
成员名 n;
} 变量名列表;
同样是定义两个 hero 类型变量 wusong 和 sunerniang,用此种形式定义如下:
struct hero {
int number; char sex; char star_name[20]; char name[20]; char nickname[20]; char position[20]; char weapon[20]; } wusong,sunerniang;
//绰号 //职业 //使用武器
} wusong={14,'m',"天伤星","武松","行者","步兵头领","2 把戒刀"}; //定义了结构体变量 wusong 并初始化
定义结构体变量 wusong 但没有初始化时,编译器会给每个成员一个默认值,初始化后 就赋予初始化时的赋值,如图 9.4 所示。
在现实生活中可以用结构体表示的事物比比皆是,例如,我国四大名著之一——《水浒
传》,其中包括性格各异的 108 个人物,如果现在要使用一种 C 语言的数据类型表示这些人 物,结构体无疑是最佳选择。下面用一个名为 hero 的结构体来表示:
struct hero {
int number; char sex; char star_name[20]; char name[20]; char nickname[20]; char position[20]; char weapon[20]; };
结构体与共用体
10. 1 结构体数据
• 【注意】 • (1) 不能将一个结构体变量作为一个整体进行赋值和输出; 只能对其各
个成员分别输出。 • ( 2) 对成员变量可以像普通变量一样进行各种运算。例如: • sumage = stu1. age + stu2. age; • (3) 既可以引用成员的地址, 也可以引用结构体变量的地址。例如: • printf("score = %f",stu2. score); • (4) 若成员本身还属于一个结构体类型, 则只能对最低级的成员进行赋
给出结构变量。 • 三种方法中声明的stu1、stu2 变量都具有图10. 1 所示的结构。
上一页 下一页 返回
10. 1 结构体数据
• 这说明变量stu1、stu2 为student 类型后, 即可向这两个变量中的各 个成员赋值。在上述结构体定义中, 所有成员都是基本数据类型或数 组类型。
• 【注意】 • (1) 类型与变量是不同概念, 不要混淆。 • (2) 结构体中的成员, 可以单独使用, 其作用与地位相当于普通变量。 • (3) 成员也可以是一个结构体变量。 • (4) 成员名可以与程序中的变量名相同, 二者不代表同一对象。
• };
• 在这个结构体数据类型定义中, struct 是C 语言关键字, student 是结 构体名, 该结构体由5 个成员组成。第1 个成员为num, 字符串变量; 第2 个成员为name, 字符串变量; 第3个成员为age, 整型变量; 第4 个 成员为sex, 字符变量; 第5 个成员为score, 实型变量。
下一页 返回
10. 1 结构体数据
• 例如, 上述学生信息数据的描述可以定义结构体数据类型为
• struct student
结构体与共用体
4、共用体类型的变量如何赋初值,含义是什么?
不能对共用体变量名赋值,也不能在定义共用体变量时初始化。但可以用一个共用体变量为 另一个变量赋值
例:union
{ int i;
char ch;
double f;
}a={1,’a’,1.5}; ()
a=1;
()
m=a;
()
例:float x; union { int i; char ch; double f; }a,b; a.i=1; a.ch=‘a’; a.f=1.5; b=a; () x=a.f; ()
二. 枚举类型的应用
• 1.枚举类型变量的定义 ◆先定义枚举类型,再定义枚举类型变量
enum week{sun,mon,tue,wed,thu,fri,
sat};
enum week weekday,workday; ◆定义枚举类型的同时定义枚举变量 enum color {red,blue,green,black}a,b,c;
共用体类型的关键字
union 联合类型名 { 数据类型 成员名1 数据类型 成员名2
...........
数据类型 成员名n };
例:
union utype {
char ch; int i; float f; };
2、如何定义共用体类型的变量
(1)先定义类型,再定义变量,例如: union data /*共用体类型定义*/ { int i;
◆直接定义枚举变量 enum {male,female}sex1,sex2;
枚举类型变量的特点
例 enum DAY {
MON=1, TUE, WED, THU, FRI, SAT, SUN };
(1) 枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。
结构体和共用体
num
name
birthday
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;
直接定义结构体变量 一般形式:
{ 类型标识符 成员名; 类型标识符 成员名; ……………. }变量名表列;
struct
{ int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2;
形式二:
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 student { int num; char name[20]; char sex; int age; float score; char addr[30]; };
顺序初始化: 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};
C语言第9章结构体、共用体、枚举
结构体变量.成员
struct date { int year;
int month; int day;
“.”是成员运算符, 优先级最高
printf("%d,%d,%d",birth);
printf("%d,%d,%d",birth.year,
}; struct date birth;
birth.month,birth.day);
scanf("%f",&student2.score[2])7; 8
student2
结构变量的整体赋值 student3 = student2;
02 Zhang Zi Liang 88 78
student3
02 Zhang Zi Liang 88 78
湖南工业大学计算机与通信学院
例9-1学生的基本信息包括学号、姓名、3门成绩、平均分、总分。输入一 个学生的前3项基本信息,计算平均分和总分并输出。
湖南工业大学计算机与通信学院
9.1 问题的提出
又如,在学生信息管理系统中填 加个属性:是否是中共党员,如 果不是属性的值为0(int),如
果是属性的值为入党的时间 (char)。在某一时间,属性只有 一种值,而且数据类型不同,这 种情况用什么数据类型描述呢?
对于这种应用,C语言引入了共用体类型。
共用体是一种同一存储区域由不同类型变量共享的数据 类型,它提供—种方法能在同一存储区中操作不同类型 的数据,也就是说共用体采用的是覆盖存储技术,准许 不同类型数据互相覆盖。
基本数据类型并不能方便地解决所有问题
❖ 复合数据类型是基本数据类型迭代派生而来
典型的代表就是“结构”,数组、指针也可算作此类
第九章 结构体和共用体
• (3)结构体数组的初始化 – 结构体数组定义好之后就可以对结构体数组进行赋 值操作,包括在定义结构体数组时赋值和在定义结 构体数组之后赋值。 • 【例9.4】输入输出学生相关信息,学生信息包括学号 (num)、姓名(name)、语文成绩(chinese)、英语成 绩(english)、数学成绩(maths)。
• ⑥不同结构体类型的成员名可以相同,结构体的成员名也可以与基 本类型的变量名相同。他们分别代表不同的对象,系统将以不同的 形式表示它们。如: 1. struct student 2. { int num; 3. char name[20]; 4. int age; 5. int score; 6. } a,b; 7. struct teacher 8. { int num; 9. char name[20]; 10. int age; 11. float salary; 12. }c,d; • ⑦“struct 结构体类型名”为结构体的类型说明符,可用于定义或说 明变量。结构体类型的定义可置于函数内,这样该类型名的作用域 仅为该函数。如果结构体类型的定义位于函数之外,则其定义为全 局的,可在整个程序中使用。
21
• 为指示相邻结点关系,可在第一个结点的指 针域内存入第二个结点的首地址,在第二个 结点的指针域内又存放第三个结点的首地址, 如此串联下去直到最后一个结点。最后一个 结点因无后续结点连接,其指针域可赋为0。 这样一种连接方式,在数据结构中称为“链 表”。图9-3为一简单链表的示意图。
22
9.3.2处理动态链表所需的函数
• (*结构体指针变量).成员名 • 或者 • 结构体指针变量->成员名
– 【例9.5】用指向结构体变量的指针变量引用结构体变量
14
结构体与共用体
9.5 链表的概念
例如,一个存放学生学号和成绩的结点应为以下结构: struct stu {
9.1.1 结构类型变量的说明
3.直接说明结构变量 这种形式的说明的一般形 式为:
struct {
成员表列 }变量名表列;
例如: struct
{ int num; char name[20]; char sex; float score;
} stud1, stud2;
9.1.1 结构类型变量的说明
9.3.2 指向结构数组的指针
指针变量可以指向一个结构数组,这时结构指针变量的值 是整个结构数组的首地址。结构指针变量也可指向结构数组 的一个元素,这时结构指针变量的值是该结构数组元素的首 地址。
9.3.3 结构指针变量作函数参数
即用指针变量作函数参数进行传送。这时由实参传向形参 的只是地址,从而减少了时间和空间的开销。
9.2 结构数组的定义
数组的元素也可以是结构类型的。因此可以构成结构型数组,结构数 组的每一个元素都是具有相同结构类型的下标结构变量。
构造结构数组的方法和构造结构变量相似,只需说明它为数组类型即 可。
例如: struct stud
{ int num; char *name; char sex; float score;
{ int num; char *name; char sex; float score; } stud1,stud2;
stud1.num=102; ="Zhang ping"; printf("input sex and score\n"); scanf("%c %f",& stud1.sex,& stud1.score); stud2= stud1; printf("Number=%d\nName=%s\n", stud2.num, ); printf("Sex=%c\nScore=%f\n", stud2.sex, stud2.score); }
C语言-第9章 结构体与共用体
第9章结构体与共用体一、单项选择题1. 若有以下说明语句:struct student{ int num;char name[ ];float score;}stu;则下面的叙述不正确的是: ( )A) struct是结构体类型的关键字B) struct student 是用户定义的结构体类型C) num, score都是结构体成员名D) stu是用户定义的结构体类型名2. 若有以下说明语句:struct date{ int year;int month;int day;}brithday;则下面的叙述不正确的是_____.A) struct是声明结构体类型时用的关键字B) struct date 是用户定义的结构体类型名C) brithday是用户定义的结构体类型名D) year,day 都是结构体成员名3. 已知:(设整型2字节,字符型1字节,浮点型4字节)struct{ int i;char c;float a;}test;则sizeof(test)的值是。
A) 4 B) 5 C) 6 D) 74. 以下对结构变量stul中成员age的非法引用是。
struct student{ int age;int num;}stu1,*p;p=&stu1;A) stu1.age B) student.age C) p->age D) (*p).age5. 有如下定义struct person{char name[9]; int age;};struct person class[10]={“Tom”,17,“John”,19,“Susan”,18,“Adam”,16,};根据上述定义,能输出字母A的语句是A) printf(“%c\n”,class[3].name); B) printf(“%c\n”,class[3].name[0]);C) print f(“%c\n”,class[3].name[1]); D) printf(“%c\n”,class[2].name[3]);6. 存放100个学生的数据、包括学号、姓名、成绩。
c语言9结构体与共用体
c语言9结构体与共用体九、结构体与共用体(一) 选择题1、C语言结构体类型变量在程序执行期间_________。
A.所有成员一直驻留在内存中B.只有一个成员驻留在内存中C.部分成员驻留在内存中D.没有成员驻留在内存中2、下面程序的运行结果是_________。
main(){struct cmplx{ int x;int y;}cnum[2]={1,3,2,7};printf("%d\n",cnum[0].y/cnum[0].x*cnum[1].x);}A.0 B.1 C.3 D.63、设有如下定义:struct sk{int n;float x;}data ,*p;若要使p指向data中的n域,正确的赋值语句是_________。
A.p=&data.nB.*p=data.n;C.p=(struct sk *)&data.nD.p=(struct sk *)data.n4、以下对结构体变量stu1中成员age的非法引用是_________。
struct student{int age;int num;}stu1,*p;p=&stu1A.stu1.ageB.student.ageC.p->ageD.(*p).age5、下面对typedef的叙述中不正确的是_________。
A.用typedef可以定义各种类型名,但不能用来定义变量B.用typedef可以增加新类型C.用typedef只是将已存在的类型用一个新的标识符来代表D.使用typedef有利于程序的通用和移植6、以下scanf函数调用语句中对结构体变量成员的不正确引用是_________。
struct pupil{char name[20];int age;int sex;}pup[5],*p;p=pup;A.scanf("%s",pup[0].name);B.scanf("%d",&pup[0].age);C.scanf("%d",&(p->sex));D.scanf("%d",p->age);7、若有以下说明和定义union dt{int a;char b;double c;}data;以下叙述中错误的是_________。
第9讲 结构体和共用体
第九讲结构体和共用体9.1 概述迄今为止,我们已经介绍了基本类型(或称简单类型)的变量(如整型、实型、字符型变量等),也介绍了一种构造类型数据——数组,数组中的各元素是属于同一个类型的。
但是只有这些数据型是不够的。
有时需要将不同类型的数据组合成一个有机的整体,以便于引用。
这些组合在一个整体中的数据是互相联系的。
例如,一个学生的学号、姓名、性别、年龄、成绩、家庭地址等项。
这些项都与某一学生相联系,如图。
应当把它们组织成一个组合项,在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。
C语言提供了这样一种数据结构,它称为结构体(structure)。
它相当于其它高级语言中的“记录”。
定义的类型如下:struct student{int num;char name[20];char sex;int age;float score;char addr[30];};上面定义了一个结构体类型,struct student(struct是关键字,不能省略),表示这是一个“结构体类型”。
它包括num,name,age,score,addr 等不同类型的数据项。
应当注意:struct student是程序设计者自己定义的类型名。
它和系统已定义了的标准类型(如int、char、float、double 等)一样可以用来作为定义变量的类型。
定义一个结构体类型的一般形式为:struct 结构体名{成员表列};花括弧内是该结构体中的各个成员(或称分量),由它们组成一个结构体。
例如,上例中的num,name,sex等都是成员。
对各成员都应进行类型说明,即类型标识符成员名也可以把“成员表列”称为“域表”。
每一个成员称为结构体中的一个域。
成员名命名规则与变量名命名规则相同。
“结构体”这个词是根据英文单词structure译出的。
许多C语言书把structure直译为“结构”。
9.2 结构体的定义、引用和初始化一、定义结构体类型变量的方法1、先定义结构体类型再定义变量名如:struct student{int num;char name[20];char sex;int age;float score;char addr[30];};struct student student1,student2;//表示定义两个struct student 类型的变量student1和student2.2、在定义类型的同时定义变量例如:struct student{ int num;char name[2];char sex;int age;float score;char addr[30];} student1,student2;它的作用与前面定义的相同。
C语言--第九章 结构体与共用体
free(pa);
h
19
3. 链表 链表概念:同一类型的结构体变量连接到一起,构成一个链, 各个结构体变量即为链表中的结点。 (1) 静态链表 所有结点都是在程序中定义的,不是临时开辟的,也不能用完后 释放,这种链表称为”静态链表”. 例如:
struct link
{
char ch;
struct link *p;
/* bk[0] bk[1] 3. 结构体指针初始化
bk[2] */
结构体类型数据的指针与其它类型数据的指针初始化相同
例如:struct stu
std,pers[3],*psd1=&std,*psd2=pers,(*p)[3]=&pers;
h
6
9.1.4 结构体类型数据的引用
1. 结构体成员的引用 若已定义了一个结构体变量和该类型的指针变量,并且该指针
p=&t; f(p); } 程序运行结果为:
C language 85
h
13
4. 结构体类型的函数 例9.5 找出成绩最高的学生记录,学生记录由学号和成绩组 成。
#include “stdio.h”
#define N 5
struct stu
{
char num[5];
float s;
};
struct stu fun(struct stu a[])
f(t); } 程序运行结果为:
C language 85
h
12
3. 传递结构体地址 形参结构体指针变量=实参结构体指针
例9.4 #include “stdio.h” struct ST
{ char str[20];int i;}; void f(struct ST *x) { printf(“%s\n%d\n”,x->str,x->i);} main() { struct ST t={“C language”,85},*p;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(B)p->a
9.2 若有以下说明和语句,则表达式
(C)++p->a
(D)(p++)->a
中的值为 31。
struct wc
{int a;
int *b;
} *p;
int x0[ ]={11,12},x1[ ]={31,32};
stratic struct wc x[2]={100,x0,300,x1};
double c;
};
printf("%d\n", sizeof (struct st));
9.16 若有以下的说明和语句,则其输出结果为
。
union un
{ int i;
double y;
};
struct st
{ char a[10];
union un b;
};
printf("%d\n",sizeof (struct st)); 9.17 若有以下的说明和语句,则其输出结果为
printf("%d,%d,%d,%d\n", qiaut, cubs, pick, dodger);
}
9.19 下面程序的输出结果为
。
union abc
{ char c[2];
int a;
}un;
main()
{ un.a=16961;
printf("%d,%c\n",un.c[0],un.c[0]);
gets(sp[i].num);
}
}
getsort(USER *sp)
{ int i,j,k;
USER temp;
for(i=0;i<N-1;i++)
{ k=i;
for(j=i+1;j<N;j++)
if(strcmp(sp[k].name,sp[j].name)>0) k=j;
temp=sp[k]; sp[k]=sp[i]; sp[i]=temp;
{ USER sp[N],temp;
getdata(sp);
getsort(sp);
outdata(sp);
}
getdata(USER *sp)
{ int i;
printf("Enter %d name & phone number:\n",N);
for(i=0;i<N;i++)
{ gets(sp[i].name);
printf("\n the linklist is:"); p=head; if(head!=NULL) do
{ printf("%d", (1) ); p= (2) ; }while( (3) );
} main() {struct stud *head; ... print(head); ... } 9.10 已知 head 指向单链表的第一个结点,下列函数 del()将从单链表中删除值为 num 的第一个结点,请填空。 #include<stdio.h> struct student {int info; struct student *link; }; struct student *del(struct student *head, int num) { struct student *p1,*p2;
struct st
{ int a;
int b[2];
}a; (A)结构变量 a 和结构成员 a 同名,不合法 (B)程序运行时将为结构 st 分配 6 个字节内存单元 (C)程序运行时不为结构 st 分配内存单元
1
(D)程序运行时将为结构变量 a 分配 6 个字节内存单元 9.6 若有以下的说明:
static struct st a[3]={5,&a[1],7,&a[2],9,'\0',},*p;
p=&a[0];
则表达式
的值是 6。
(A)p++->n
(B)p->n++
(C)(*p).n++
(D)++p->n
9.5 若有以下的说明,已知 int 类型的变量占两个字节,则
的叙述是正
确的(多项选择)。
(B)*++(++p)->b (D)(p++)->b
二、填空题
9.8 下面程序实现对两个数 x,y 的判定,若 0≤x≤y≤100 条件成立,则计算 x2+y2, 并将结果输出,否则打印相应的出错信息并继续读数,直至输入正确。请填空。
enum ErrorData{Right, Lesson, Great100,MinMaxErr}; char *ErrorMessage[]={
2
if(max<min)return MinMaxErr; if(max>100)return Great100; if(min<0)return Lesson;
(3) ; } 9.9 已知 head 指向单链表的第一个结点,以下程序调用函数 print()输出这一单向链表, 请在程序中填空。 #INCLUDE<STDIO.H> #include<stdlib.h> struct stud { int info; struct stud *next; }; void print(struct stud *head) { struct stud *p;
"Enter Data Right", "Data<0 Error", "Data>100 Error", "x>y Error" }; main() { int status,x,y; do{
printf("Please Enter two number:(x,y)"); scanf("%d,%d", &x, &y); status= (1) ; printf("%s\n",ErrorMessage[ (2) ]); }while (status!=Right); printf("Result=%d",x*x+y*y); getch(); } int error(int min, int max) {
。
static struct
{char ch;
int i;
double x;, {'b',2,7.98},{'c',3,1.93}};
9.15 若有以下的说明和语句,已知 int 类型占两个字节,则其输出结果为
。
struct st
{char a[10];
int b;
}
6
} outdata(USER *sp) { int i;
printf("after sorted:\n"); for(i=0;i<N;i++) printf("%s,%s\n",sp[i].name,sp[i].num); }
7
4
do{
(2)
} (1) ;
return(n);
}
9.13 若有以下说明,则变量 w 在内存中所占的字节数是
。
union aa
{float x,y;
char c[6];
};
struct st {union aa v; float w[5]; double ave;}w;
9.14 若有以下的说明,则对初值中整数 2 的引用方式为
(D)p->name
使指针 p->b 的值增 1(多项选择)。
struct wc
{ int a;
int *b;
}*p;
int x0[ ]={11,16},x1[ ]={31,36};
static struct wc x[2]={100,x0,300,x1};
p=x; (A)*++p->b (C)*p->b++
else printf("%d not been found! \n",num); } return(head); } 9.11 下面函数 creat()用来建立一个带头结点的单向链表,新产生的结点总是插在链表 的末尾。单向链表的头指针作为函数值返回,请在程序中填空。 #include<stdio.h> struct list { char data; struct list *next; }; struct list *creat() { struct list *h, *p, *q; char ch; h= (1) malloc(sizeof(struct list)); p=q=h; ch=getchar(); while(ch!='?') { p= (2) malloc(sizeof(struct list)); p->data=ch; q->next=p; q=p; ch=getchar(); } p->next='\0'; (3) ; } 9.12 函数 count(head)统计链表结点的个数,head 为头指针,阅读程序并填空。 #include<stdio.h> struct student {char data; struct student *next; }; count(head) struct student * head; { int n=0; struct student * p=head;