构造类型
一、结构体类型
1、构造结构体类型的定义
struct 结构体类型名
{
成员1的定义
成员2的定义
......
成员n的定义
};
struct student { int sn; int age; char sex; int s[3]; };此处的分号不能省略
2、定义结构体变量
A、先定义(构造)结构体类型名,然后用该类型去定义结构体变量
struct student { int sn; int age; char sex; int s[3]; }; struct student str1, str2, str[10]; 注意: 1)str1,str2是变量,而str[10]是数组 2)struct student是一种类型
B、在定义结构体类型的同时可以定义结构体变量
struct student { int sn; int age; char sex; int s[3]; }str1, str2, str[10];
C、类型、变量同时定义,类型名student省略,之后不能再定义这种类型的变量了,此形式不好
struct { int sn; int age; char sex; int s[3]; }str1, str2, str[10];
3、注意事项
1)结构体变量在内存中占用字节数为各成员占用字节数总和
2)struct 是构造结构体类型的标志,其中的student不是变量名,是构造的体类型名,它和int float一样是某一种类型
3)结构体与数组的最大区别是,结构体的成员可以是不同的类型,也可以是相同的类型,但是数组的成员必须是相同的类型
4、使用结构体变量
a、结构变量的初始化
struct aa { int a; char b[10]; float c; }a1={30,"china",40.5},a2={60,"kunming"},a3;
b、引用结构体成员的方式:
结构体变量名.成员名
c、注意:
1)再定义结构体变量的同时可以将各成员的初值按顺序放在一对花括号中,来进行对结构体变量的初始化,若初值个数多于成员个数则出错
2)若初值个数多于成员个数则出错,若初值个数少于成员个数,则多余成员自动赋0
3)结构体变量不能整体引用,只能引用他的成员
a1.b="xinjiang"是非法的,数组名是常量,常量不能放在赋值号的左边,若要给数组名赋字符串需要借用strcpy函数
5、指向结构体数据类型的指针
a、结构体指针
struct student { int num; char name[20]; char sex; float score; }; struct student aa={1001,"zhang",'M',80.5} struct student *p=&aa; char *q=aa.name; int *r=&aa.num; 注意: aa虽然是结构体类型的变量,但是它还是内容变量
b、注意事项
1)指向结构体变量的指针
可以用指针变量指向结构体变量也可用指针变量指向结构体变量中的成员。
要注意指针变量的类型必须与他所指向变量的类型相同。当指针变量指向结构体变量时,对指针变量加1则跳过整个结构体而不是跳过一个成员
2)指向结构体数组的指针
struct student { int num; char name[20]; char sex; float score; }; struct student stu[3]={{1001,"zhang",'M',80.5},{1002,"zhang",'M',80.5},{1003,"zhang",'M',80.5}} ; struct student *p=stu; 注意: 外看是数组,内看是结构体 结构体不能整体使用赋值除外
二、链表
1、数组与链表的区别
数组是顺序存储的,它是随机访问的
链表是链式存储的,它是顺序访问的
2、链表的3个操作
——访问、插入、删除
链表的访问都是通过指针变量从头结点开始,每一个结点都应包括数据部分和下一个结点的地址两部分内容
1)链表的创建
#include<stdio.h> #include<stdlib.h> struct node { int data; struct node *next; }; struct node *head, *p, *q; p=(struct node*)malloc(sizeof(struct node)); p->data=10; head=p; q=(struct node*)malloc(sizeof(struct node)); q->data=20; p->next=q; q->next=null;
2)链表的访问【计算操作】
——链表访问的前提是此链表已经被创建好了
3)链表的删除
——链表删除的前提是此链表已经被创建好了
a、删除第一个结点
struct node *p,*head; head=p; head=p->next; free(p);
b、删除中间结点
struct node *p,*q,*s,*head; head=p; while(p->next!=null&&p->data==c) { q=p; p=p->next; } s=p; q->next=p->next; free(s);
c、删除最后一个结点
struct node *p,*q,*head, head=p; while(p->next!=null) { q=p; p=p->next; } q->next=null;
4)链表的插入
——链表插入的前提是此链表已经被创建好了
a、插入到第一个结点前面
struct node *p ,*s,*head; head=p; s->next=p; head=s;
b、插入中间结点任意一个结点前面
struct node *p,*q,*s,*head; head=p; while(p->next!=null&&p->data==c) { q=p; p=p->next; } s->next=p; q->next=s;
c、插入最后一个结点后面
struct node *p,*q,*s,*head; head=p; while(p->next!=null) { p=p->next; } s->next=null; p->next=s;
3、动态存储分配函数在<stdlib.h>库文件中
1)malloc()函数
格式:malloc(size)
作用是在内存的动态存储区中分配一个长度为size个字节的连续空间,函数返回值为一个指向分配域起始地址的指针若分配失败则返回null
sizeof 求一个变量所对应类型或者类型在内存中的所占有的字节数
返回的地址是void*类型,如果要使用该地址则必须强制转换成所指向地址的类型
2)free()函数
格式:free(p)
作用是释放用malloc分配的内存
三、共用体类型
1、共用体类型的定义格式
格式:
union 共用体名
{
成员列表;
};
注意:
1)成员列表为定义该共用体的成员,成员定义的方式与普通变量的方式一样
2)共用体中的所有成员共用同一段内存(所有成员的起始地址都是一样的)
3)共用体名可以省略
union data { int i; char ch[19]; float s; };
2、共用体变量的定义
1)先定义类型,再定义变量
2)定义类型的同时,定义变量
3)直接定义变量
union data { int i; char ch[19]; float s; };a1 注意: 由于共用体类型变量的所有成员都共用同一段内存,所以共用体类型变量所占的字节数等于该共用体类型中的成员所占用字节数最多的成员所占的字节数。
3、共用体变量的引用
1)同类型成员共享值
2)共用体变量之间可以相互赋值,赋值后两个变量应使用同一成员
3)共用体变量的地址与各成员的地址都相同的
4)在定义共用体时,可以对其进行初始化,但只能有一个处置且必须用花括号将处置括起。相当于给第一个成员赋值
5)共用体、结构体的成员均可以是共用体或结构体类型
6)不能用共用体类型变量做为函数参数
四、typedef
用typedef定义新类型名,在编程中可以用typedef来定义新的类型名来代替已有的类型名
格式:
typedef 已有类型名 新的类型名;
typedef int INTEGER 注意: 1)以后在定义变量时int和INTEGER是等价的。 2)ypedef可以用于定义各种类型名,但不能定义变量,即只要见到typedef则该语句最后的标识符必定是一个类型名而不是变量名。 3)typedef只能对已经存在的类型新增一个别名,而不是创造新类型,即在typedef后必须是一个已有的类型。