结构体、共用体、用户自定义
- 格式:doc
- 大小:518.00 KB
- 文档页数:39
结构体、共用体、用户自定义类型int、char、float、double等都是系统预定义的标准数据类型。
程序员用这些类型声明符声明需要的变量,系统就会为它们分配相应的存储空间,按特定的存储方式进行存储,并在有关运算符作用于这些数据时进行合法性检查。
除此之外,C语言还允许程序员在一定的框架范围内定制需要的数据类型。
声明了类型之后,程序员就可以使用它们来定义需要的变量,如同使用系统提供的int、char、float、double等一样。
C语言允许程序员定制的数据类型是在下面的5种类型框架内进行。
这5种框架分别是:·结构体(struct):也称集合数据类型,用于将不同类型的数据组织在一个名字下·共用体(union):允许一个存储空间中存储不同类型的变量。
· typedef:用于为已经存在的类型定义新名字。
一、用typedef定义类型Typedef 类型名标识符1、简单的名字替换typedef int INTEGER;•意思是将int型定义为INTEGER,这二者等价,在程序中就可以用INTEGER作为类型名来定义变量了。
INTEGER a,b;/*相当于int a,b;*/•定义a,b为INTEGER类型,也即int类型。
下面是一个解释例:①首先按通常定义变量的方法定出定义的主体char *p;②将变量名换成新类型名:char *CHAR;③在量后面加上关键字typedef;typedef char *CHARP④可以用新类型名定义变量了:CHARP p;二、结构体类型1、定义结构变量的一般格式为:struct 结构名{类型变量名;类型变量名;...} 结构变量;结构名是结构的标识符不是变量名例如:struct date{int y,month,day;}说明:结构体类型名不仅可以是简单数据类型,也可以是构造类型,当然也可以是基种结构体类型。
当结构体说中又包含结构体时,称其为结构体的嵌套。
如下:struct student{char name[12];char sex;struct date birthday;float sc[4];};若没的事先说明这一类型,以上结构类型说明可改定为如下形式:struct student{char name[12];char sex;struct date{int y,month,day;}birthday;float sc[4];};建立通信录定制一种数据类型struct Addr:truct Addr{char name[30]; /* 姓名*/char street[40]; /* 街道*/char city[20]; /* 城市*/char provn[20]; /* 省名*/unsigned int zip; /* 邮编*/}2、结构体类的变量、数组和指针变量和定义可以用以下四种方法定义结构体类型的变量、数组和指针变量。
紧跟在结构体类型说明之后说进行定义。
struct student{char name[12];char sex;struct date birthday;float sc[4];}std,pers[3],*pstd;在说明一个无名结构体类型的同时,直接进行定义;如:struct{char name[12];char sex;struct date birthday;float sc[4];};struct std,pers[3],*pstd;先说明结构体类型,再单独进行变量定义。
struct student{char name[12];char sex;struct date birthday;float sc[4];};struct student std,pers[3],*pstd;使用typedef说明一个结构体类型名,再用新类型来定义变量。
3、定义结构体类型变量及对变量的初始化定制一个结构体类型后,得到一个结构体类型名。
有了这个类型名,就可以像int、char、float和double一样,用来定义一些结构体类型的变量。
定义了变量,系统就会为变量分配存储空间。
• 1. 定义结构体变量可以采用不同的方法定义一个结构体类型的变量。
(1)在定义了一个结构体类型之后,把变量定义为该类型。
如有以下声明:struct Student stdnt1, stdnt2, stdnt3;•定义了stdnt1、stdnt2,和stdnt3三个struct Student类型的结构体变量。
注意不能写成:struct Student ,stdnt1, stdnt2, stdnt3; /* 错误逗号*/也不能写成Student stdnt1, stdnt2, stdnt3; /* 缺少关键字struct•结构体变量的初始化在定义了结构体变量之后,stdnt1, stdnt2, stdnt3等就具有struct Student结构体类型的特征,也有了变量的特征。
但是,这些变量不是简单变量,它们的值也不是一个简单的整数、实数或字符等,而是由许多个基本数据组成的复合的值。
例如,stdnt1、stdnt2和stdnt3的值可以有如图7.1所示的值•那么,如何对结构体变量进行初始化呢?与简单变量的初始化类似,结构体变量的初始化应当在变量定义时进行,并且要把初始值依次写在一对花括号内,用赋值运算符赋值给对应的变量。
如struct Student{unsigned int num;char name[20];char sex;int age;float score;char addr[30];} stdnt1={50201,”ZhangXi”,’M’,18,90.5,”Shanghai”},stdnt2={50202,”WhangLi”,’F’,19,88.3,”Beijing”};•也可以用以下形式Struct Student stdnt3={50203,”LiHong”,’M’,17,79.9,”Shanxi”}; /***** ex070101 ***/struct Student{unsigned int num;char name[20];char sex;unsigned char age;float score;};#include <stdio.h>int main(void){struct Student student1={50201,“WangLi”,’M’,18,89.5};struct Student student2;student2=student1; /* 结构体变量间赋值*/printf (“student1: %u,%s,%c,%u,%5.2f\n”, student1.num,\ ,student1.sex,student1.age,student1.score);printf (“student2: %u,%s,%c,%u,%5.2f\n”, student2.num,\ ,student2.sex,student2.age,student2.score);return 0;}•在执行“student2=student1;”这个赋值语句时,将student1变量中各个成员逐个依次赋给student2中相应各个成员。
显然,这两个结构体变量的类型应当相同才行。
•注意:不允许用赋值语句将一组常量直接赋给一个结构体变量。
如下面语句不合法:student1={50203,“WangLong“,19,’F’,89.5};4、引用结构体变量中的数据①结构体变量名.成员名②指针变量名- >成员名③(*指针变量名).成员名使用指向结构体变量的指针引用结构体变量的成员/***** ex070801 ***/#include <string.h>#include <stdio.h>struct StudType{char name[16];long num;int age;char sex;float score;};int main(void){struct StudType student,*p;/* 使用结构体变量引用成员*/strcpy (,"Wang Li");student.num=50101;student.age=18;student.sex='m';student.score=89.5;/* 使用指向结构体变量的指针引用成员*/p=& student;printf("\nname:%s\nnumber:%1d\nage:%d\nsex:%c\nscore:%6.2f\n",\(*p).name,(*p).num,(*p).age,(*p).sex,(*p).score);return 0;}5、相同类型结构体变量之间的数据传递例:Struct{Char name[10];Int num;}per1,per2={“YANGGM”,46};赋值:per1=per26、函数之间结构体变量的数据传递①向函数传递结构体变量中单个成员的数据②向函数传递整个结构体变量中的数据③传递结构体变量的地址#include <stdio.h>typedef struct{char s[10];int t;}ST;getdata(ST*p){scanf("%s%d",p->s,&p->t);}main(){ST a;getdata(&a);printf("%s,%d\n",a.s,a.t);}④向函数传递结构体名#include <stdio.h>typedef struct{int num;double mark;}REC;void sub1(REC x){x.num=23;x.mark=81.5;}void sub2(REC y[]){y[0].num=12;y[0].mark=77.5;}main(){REC a={16,90.0},b[]={16,90.0};sub1(a);printf("A)%d,%5.1lf\n",a.num,a.mark);sub2(b);printf("B)%d,%5.1lf\n",b[0].num,b[0].mark);}⑤函数的返回值是结构体类型#include <stdio.h>typedef struct{int a;char b;}ST;ST fun(ST x){x.a=99;x.b='S';return x;}void main(){ST y;y.a=0; y.b='A';printf("y.a=%dy.b=%c\n",y.a,y.b);y=fun(y);printf("y.a=%dy.b=%c\n",y.a,y.b);}⑥函数的返回值可以是指向结构体变量的指针类型#include <stdio.h>typedef struct{int a;char b;}ST;ST *fun(ST x){ST *px;x.a=100;x.b='C';px=&x;return px;}void main(){ST y,*p;y.a=999;y.b='X';printf("y.a=%dy.b=%c\n",y.a,y.b);p=fun(y);printf("(*p).a=%d(*p).b=%c\n",(*p).a,p->b); }输入3个学生的信息并将它们输出/*** ex070701 ***/#include <stdlib.h>#include <stdio.h>#define StuNUM 3struct StudType{char name[16];long num;int age;char sex;float score;};int main(void){struct StudType stu[StuNUM];int i;char ch;char numstr[16];/* 输入数据*/for (i=0;i<StuNUM;i++){printf ("\nenter all data of stu[%d]:\n",i); gets (stu[i].name);gets (numstr);stu[i].num=atol (numstr); gets (numstr);stu[i].age=atoi(numstr);stu[i].sex=getchar();ch=getchar();gets (numstr);stu[i].score=atof(numstr);}/* 输出数据*/printf ("\n record name \t \t num\tage\tsex\tscore\n");for (i=0;i<StuNUM;i++)printf ("%d\t%-16s%-8d%d\t%-c\t%6.2f\n",i,stu[i].name,\ stu[i].num,stu[i].age,stu[i].sex,stu[i].score); return 0;}/*** ex070702 ***/#include <stdlib.h>#include <stdio.h>#define StuNUM 3 struct StudType{Char name[16]; long num;int age;char sex;float score;};int main(void){struct StudType stu[StuNUM],*p;int i;char numstr[16];/* 输入数据*/for (i=0,p=stu;p<stu+StuNUM;p++,i++){printf ("\nenter all data of stu[%d]:\n",i);gets (p->name);gets (numstr);p->num=atol (numstr);gets (numstr);p->age=atoi (numstr);p->sex=getchar( );getchar( );gets (numstr);p->score=atof (numstr);}/* 输出数据*/printf ("\n record name \t \t num\tage\tsex\tscore\n");for (i=0,p=stu;p<stu+StuNUM;p++,i++)printf ("%d\t%-16s%-8d%d\t%-c\t%6.2f\n", \i,p->name,p->num,p->age,p->sex,p->score);return 0;}三、利用结构体变量构成的链表1、结构体中含的可以指向本结构体的指针成员当一个结构体中的一个或多个成员的基类型就是本结构体类型时,通常把这种结构体称为可以“引用自身的结构体”。