第九章 结构体
自定义类型 – 结构体
结构体类型,不占内存,不能保存数据;
内存空间,可以保存数据
1 2 3 4 5 6 7 8 9
| struct stu { int num; char name[10]; char sex; float score; }; struct stu boy1;
|
sizeof对类型和变量均可使用
1 2
| sizeof(boy1); sizeof(struct stu);
|
结构体类型变量的定义方式
先定义类型,再定义变量
1 2 3 4 5 6 7 8
| struct stu { int num; char name[10]; char sex; float score; }; struct stu boy1,boy2;
|
定义类型的同时,定义变量
1 2 3 4 5 6 7 8 9
| struct stu { int num; char name[10]; char sex; float score; }boy1, boy2;
struct stu boy3;
|
定义类型的同时定义变量,但省略类型名
因无类型名,无法再重新定义其他变量
1 2 3 4 5 6 7
| struct { int num; char name[10]; char sex; float score; }boy1, boy2;
|
结构体类型变量的初始化
1 2 3 4 5 6 7 8 9 10 11 12
| struct stu { int num; char name[10]; char sex; float score; };
struct stu boy1,boy2 = {1001, "zhao", 'M', 85.5};
boy1 = boy2;
|
结构体类型的数组
1 2 3 4 5
| struct stu ss[3];
ss[0].num = 1001; strcpy(ss[1].name, "Qian"); ss[2].score=92.0;
|
结构指针变量
结构体变量用 .
结构体指针变量用 ->
(*
结构体指针变量)用.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| struct stu boy1; struct stu *p; p=&boy1;
p -> num=100;
boy1.num=1001;
strcpy(p->name, "Zhang");
strcpy(boy1.name, "Zhang");
(*p).score=92.0;
boy1.score=92.0;
|
结构体类型数据做函数参数
用法与传普通变量类似,
结构体类型变量做函数参数,不会改变原来的实参的值。
结构体指针做函数参数,可以修改原来实参的值。
结构体类型的嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| struct date { int year; int month; int day; }; struct stu { int num; char name[10]; char sex; struct date birthday; float score; };
|
第二种
1 2 3 4 5 6 7 8 9 10 11 12 13
| struct stu { int num; char name[10]; char sex; struct { int year; int month; int day; } birthday; float score; };
|
类型定义语句typedef
为类型起“绰号”,并不产生新的数据类型,只是给已有的类型增加新名
1 2 3 4 5
| typedef double real;
real a,b;
double a,b;
|
C语言常用内存管理库函数(包含stdlib.h
)
函数名 |
介绍 |
备注 |
malloc |
分配1块长度为size字节的连续内存空间(不清零),函数返回该空间的首地址;如分配失败函数返回0 |
(类型说明符*)malloc(size) |
calloc |
分配n块、每块长度为size字节的连续内存空间(共size×n字节),并将该空间中的内容全部清零,函数返回该空间的首地址;如分配失败函数返回0 |
(类型说明符*)calloc(n,size) |
free |
释放ptr所指向的一块内存空间,ptr是由malloc或calloc函数所分配空间的地址,即是这两个函数的返回值(或类型转换后的返回值) |
free(ptr)(ptr为任意基类型的指针) |
链表
以链接方式存储的线性表,链表各元素的逻辑结构与存储结构一般不一致。
链表类型:单向链表,双向链表,循环链表。。。
单向链表
一个单向链表的节点分为两个部分,第一部分保存或者显示节点的相关信息,第二部分存储下一个节点的地址。单向链表只向一个方向遍历。
链表的一种,特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;列表有节点构成,head指针指向第一个称为表头节点,而终止于最后一个指向NULL的指针。
双向链表
比单向链表多一个的是,双向链表每个节点有两个链接,一个指向前一个节点,而另一个指向下一个节点,当为最后一个节点时,指向空值或空列表。
循环链表
在一个循环链表中,首节点和末节点被连接在一起。这种方式,单向和双向都可实现。
链表的创建与输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <stdio.h> #include <stdlib.h> #include <string.h>
struct nodelist { int score; struct nodelist *next; };
typedef struct nodelist SNODE;
SNODE *create_list(int data) { SNODE *head=NULL, *node=NULL, *end=NULL; int i;
head = (SNODE *)malloc(sizeof(SNODE)); end = head;
for(i=0; i<data; i++) { node = (SNODE *)malloc(sizeof(SNODE)); node->score = i; end->next = node; end = node; } end->next = NULL;
return head; }
void out_list(SNODE *h) { SNODE *p; p = h->next; while(p) { printf("%d\n", p->score); p = p->next; } }
int main() { int data = 3; SNODE *head; head = create_list(data); out_list(head); system("pause"); }
|
链表节点的插入和删除
节点的插入
1 2 3 4
| p = new struct node; p->data = 95.5; p->next = q->next; q->next = p;
|
节点的删除
1 2
| q->next = p->next; delete p;
|