第九章:构造类型
一、结构体类型
1.构造结构体类型
struct 结构体类型名
{ 成员1的定义;
成员2的定义;
………
成员n的定义;
};
例:
struct student
{
int sn;
int age;
char sex;
int s[3];
};
/*
* 定义成员的方式与定义普通变量的方式一样
* 成员列表必须用一对花括号括起
* 结构体名可以省略
*/
2.定义结构体变量
- 先定义结构体类型名再定义结构体变量
struct student
{
int sn;
int age;
char sex;
int s[3];
}; /*类型定义*/
struct student stu1,stu2,st[25]; /*变量定义*/
- 在定义结构体类型的同时可以定义结构体变量
struct student
{
int sn;
int age;
char sex;
int s[3];
} stu1,stu2,st[25];
- 类型、变量同时定义,类型名student省略
struct
{
int sn;
int age;
char sex;
int s[3];
int *p;
} stu1,stu2,st[25];
结构体变量在内存中占用字节数为各成员占用字节数总和
3.结指向结构体数据类型的指针构变量的初始化及引用
在定义结构体变量的同时可以将各成员的初值按顺序放在一对花括号中,来进行对结构体变量的初始化。若初值个数多于成员个数则出错,若初值个数少于成员个数,则多余成员自动赋0
struct aa
{
int a;
char b[10];
float c;
} a1={30,"china",40.5},a2={60,"kunming"},a3;
结构体变量不能整体引用,只能引用它的成员
引用结构体成员的方式:结构体变量名.成员名
printf("a1=%d,%s,%f",a1.a,a1.b,a1.c);
a1.a=80;
a1.b="xinjiang"; /*错误,数组名代表数组的首地址,而且是一个地址常量,应为strcpy(a1.b,"abc");*/
a1.c=60.5;
4.指向结构体数据类型的指针
1)指向结构体变量的指针
可以用指针变量指向结构变量也可能用指针变量指向结构体变量中的成员。要注意指针变量的类型必须与它所指向变量的类型相同。当指针变量指向结构体变量时,对指针变量加1则跳过整个结构体而不是跳过一个成员
如:
struct student
{
int num;
char name[20];
char sex;
float score;
};
strucstruct student aa={1001,"zhang",'M',80.5};
struct student *p=&aa;
char *q=aa.name;
int *r=&aa.num;
/*当指针变量p指向结构体变量aa时,引用aa中成员的方式有三种:*/
aa.num
(*p).num
p->num -> 指向运算符
aa.score
(*p).score
p->score
t student aa={1001,"zhang",'M',80.5};
struct student *p=&aa;
char *q=aa.name;
int *r=&aa.num;
2)指向结构体数组的指针
struct student
{
int num;
char name[20];
char sex;
float score;
};
struct student stu[3]={{1001,"zhang",'M',60.5},
{1002,"peng",'M',100},
{1003,"wang",'W',90.9}};
struct student *p=stu;
/*****访问*****/
stu[0].num;
p->name;
(*p).name;
/*****/
stu[1].num;
(p+1)->num;
(*(p+1)).num;
可以用结构体变量的成员作为实参,它与普通变量作为实参的用法是一样的。
用结构体变量作为实参时,要求形参必须是同一结构体类型的变量,传递后形参与实参各对应成员值是一样的。
也可以用结构体类型的地址(指针变量或数组)作为实参,要求形参必须是同一结构体类型的指针变量或数组。只要是地址传递,则可以通过形参来改变实参的值。
二、链表
1)链表是一种数据结构,它采用动态分配存储单元方式。它能够有效地节省存储空间(同数组比较)
定义作为结点的格式:
struct 结构体名
{ 定义数据成员;
struct 结构体名 *指针变量名;
};
2)动态存储分配函数
malloc()函数,格式:malloc(size)
作用是在内存的动态存储区中分配一个长度为size个字节的连续空间,函数返回值为一个指向分配域起始地址的指针若分配失败则返回NULL。 例如:开辟一个用于存放struct student数据的内存空间,并让p指向该空间:
struct student *p=(struct student *)malloc(sizeof(struct student ));
free()函数,格式:free§
作用是释放用malloc() 分配的内存
三、共用体类型
共用体中的所有成员共用同一段内存(所有成员的起始地址都是一样的)
格式:
union 共用体名
{
成员列表;
};
成员列表为定义该共用体的成员,成员定义的方式与普通变量的方式一样
成员列表必须用一对花括号括起
共用体名可以省略
-
共用体变量的定义
-
先定义类型,再定义变量
-
定义类型的同时,定义变量
-
直接定义变量
union data { int i; char ch[10]; ch[10]; float s; }a1; /* 由于共用体类型变量的所有成员都共用同一段内存,所以共用 体类型变量所占的字节数等于该共用体类型中占用字节数最多 的成员所占的字节数 sizeof(a1)=>10 */
-
-
共用体变量的引用
-
引用的格式: 共用体变量名.成员名
-
同类型成员共享值
-
在内存中整型数据的二进制数低8位占用前面一个字节,高8位占用后面 个字节
-
在定义共用体时,可以对其进行初始化,但只能有一个初值且必须用花括号将初值括起。相当于给第一个成员赋值
-
不能用共用体类型变量做为函数参数
-
共用体变量之间可以相互赋值,赋值后两个变量应使用同一成员
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); /*056*/ } /*****************/ main() { union { char i[2]; int k; }r; r.i[0]=2;r.i[2]=0; printf("%d\n",r.k); /*2*/ }
-
四、typedef
-
用typedef定义新类型名
格式:t df ype e 已有类型名 新的类型名;
如:typedef int INTEGER;
以后在定义变量时int 和INTERGER是等价的
INTEGER a[10],b;<=> int a[10],b;
typedef int ARR[10]; ARR a,b[2];<=> int a[10],b[2][10]; /*********/ typedef char *POINT; POINT p1,*p2;<=>char *p1,**p2; /******/ typedef int INTEGER; INTEGER a[10],b;<=>int a[10],b; /********/ typedef struct LNode { int data; struct LNode *next; }LNode;