链表
数据两种模式
(1)数组-----连续
(2)链表-----非连续
定义链表:链表是一种数据结构,采用动态分配存储单元的方式。它能够有效的节省存储空间
①节点定义:两部分构成:内容数据部分和下一个节点地址
//节点的定义方式
struct student{
int num;
float score;
struct student *next;//指向自己的指针,节点类型
};
struct student a, *p;②动态机制:malloc函数
动态存储分配函数#include<stdlib.h>
malloc()函数
格式:malloc(size)
作用:在内存的动态存储分区中分配一个长度为size个字节的连续空间,函数的返回值为一个分配域起始地址
的指针,若干分配失败则返回NULL
#include<stdlib.h>
//开辟一个用于存放struct student数据的内存空间,并让p指向该空间
//malloc用之前一定要进行强制类型转换,因为malloc返回的是连续占用空间的首地址一个void *型
struct student *p = (struct student *)malloc(sizeof(struct student));/*
节点的定义
*/
struct node{
int data;
struct node *next;
};
//指针p指向的是整个节点而不是节点里面其中的数据域
struct node *p = (struct node *)malloc(sizeof(struct node));free()函数
格式:free(p);
作用:释放用malloc()分配的内存
③生成链表
#include<iostream>
#include<cstdio>
#include<stdlib.h>
using namespace std;
//链表的建立
struct node{
int data;
struct node *next;
};
int main(){
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;
q->next = NULL;
p->next = q;
return 0;
}
④链表的三个操作:查、增、删
链表的访问
#include<iostream>
#include<cstdio>
#include<stdlib.h>
using namespace std;
//链表的建立
struct node{
int data;
struct node *next;
};
int main(){
struct node *head, *p, *q,*r;
int sum = 0;
float aver;
p = (struct node *)malloc(sizeof(struct node));
p->data = 10;
head = p;
q = (struct node *)malloc(sizeof(struct node));
q->data = 20;
r = (struct node *)malloc(sizeof(struct node));
r->data = 30;
p->next = q;
q->next = r;
r->next = NULL;
//链表的访问
while(p != NULL){
sum += p->data;
p = p->next;
}
aver = sum / 3;
printf("%f",aver);
return 0;
}
//预期结果
20.000000
2、链表的删除
/*
删中间
*/
//删除p节点
//1、找到p节点的前一个节点q
q->next = p-next;
free(p)
//若没有p节点,删除q节点的后面一个节点
q->next = q->next->next;
free(p->next)
/*
删头节点
*/
head = head->next;
/*
删尾,假设告诉尾节点的前一个节点是q
*/
p = q->next;
q->next = NULL;
free(p)
3、增加节点
/*
中间插:要在q节点的后面插一个元素s,不可以交换顺序
*/
//先连后断
s->next = q->next;
q->next = s;
/*
第一个位置插:插一个元素s
*/
s->next = head;
head = s;
/*
最后位置(q)插:插一个元素s,下面两步可以交换
*/
q->next = s;
s->next = NULL;三、共用体类型:
共用体中所有成员共用同一段内存(所有成员的起始地址都是一样的)
union 共用体名
{
成员列表;
};
//定义了一个名为data的共用体类型,该类型有三个成员i, ch, s
/*
先定义类型,在定义变量;union data a1
定义类型的同时定义变量
直接定义变量
*/
union data{
int i;
char ch[10];
float s;
}a1; //a1是变量
/*由于共用体类型变量的所有成员都共用同一段内存,
所以共用体类型变量所用的变量所占的字节数等于
该共用体的类型中占字节数最多的成员所占的字节数
*/
sizeof(a1) = 10Note:
(1)成员列表为该共用体的成员,成员定义的方式与普通变量的方式一样
(2)成员列表必须用一对花括号
(3)共用体名可以省略
union的经典例题:
#include<iostream>
#include<cstdio>
using namespace std;
union myun{
struct {
int x;
int y;
int z;
}u;
int k;
}a;
int main(){
a.u.x = 4;
a.u.y = 5;
a.u.z = 6;
a.k = 0;
printf("%d\n",a.u.x);
return 0;
}
//预期结果:
0#include<iostream>
#include<cstdio>
using namespace std;
int main(){
union{
char i[2];
int k;
}r;
r.i[0] = 2;
r.i[1] = 0;
printf("%d\n",r.k);
return 0;
}
/*
刚开始博主做的时候一看就是20,但是运行结果是错的,经过仔细思考
发现这道题太考的太好了,我们都知道数组中,下标小的低地址,下标大
大地址,问题来了,整数占两个字节,高位占大地址也就是说r.i[1]放的是2
r.i[1] = 0,难道答案是02,胡扯,0在C语言中是8进制标志
*/
//预期结果
2 四、typedef
用typedef定义新的类型名
在编程中可以用typedef来定义新的类型名来代替已有的类型名
格式:
//typedef 已有类型名 新的类型名
//如:
typedef int INTEGER;
INTEGER a[10], b;
int a[10], b; typedef 已有类型名 新的类型名
(1)typedef可用于定义各种类型名,但不能定义变量,即只要见到typedef则该语句最后的标识符
一定是个类型名而不是变量名
(2)typedef只能对已近存在的类型新增一个别名,而不是创造新类型,即在typedef后必须是一个已有的类型。
typedef int ARR[10]
ARR a, b[2];//int a[10], b[2][10];
typedef char *POINT
POINT p1, *p2;//char *p1, **p2版权声明:本文为weixin_42133768原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。