链表的建立是一个动态过程,动态建立结点时要为其分配内存,所以在学习建立链表之前要复习一下关于动态分配的函数:
malloc函数:void*malloc(unsigned int)
作用:该函数的作用是在内存中动态的分配一块size大小的内存空间,malloc函数会返回一个指针该指针指向分配的内存空间,如果发生错误,则返回NULL
calloc函数:void*calloc(unsigned n,unsigned size)
作用:该函数的作用是在内存中动态的分配n个长度为size大小的连续内存空间数组,并对其进行初始化,该函数也会返回一个指针,该指针指向动态分配的连续内存空间地址
free函数:void free(void*ptr)
作用: 释放由malloc或calloc动态开辟指向的内存空间
下面我们就学习如何建立链表吧:
(关于链表的建立我已经详细的写在代码注解里了,欢迎小伙伴们阅读,指点)
//定义结点类型
struct student
{
char Name[20];
char iNumber[10];
struct student* pNext;
};
//定义一个全局变量记录链表结点个数
int icount = 0;
//定义一个名为Create的函数,返回值为struct student* 来及链表
struct student*Create()
{
//定义一个头节点并将其重置为空
struct student* pHead = NULL;
//定义尾结点,新结点(即要添加的结点)
struct student* pEnd, * pNew;
//开辟一块动态的内存空间,刚开始时使尾结点和新结点都指向这块空间
pEnd = pNew = (struct student*)malloc(sizeof(struct student));
if (pNew!=NULL&&pEnd!=NULL)
{
//向新开辟的pNew空间中写入第一组数据
scanf_s("%s", &pNew->Name[20], 20);
scanf_s("%s", &pNew->iNumber[10], 10);
}
while (pNew->Name!=0)
{
icount++;
//若为第一次写入数据
if (icount == 1)
{
//第一次写入数据则让头结点指向新结点的指针域
pNew->pNext = pHead;
//此时新结点即为尾结点
pEnd = pNew;
//此时新结点也为头结点
pHead = pNew;
}
else
{
//则此时新结点不是第一个结点,则此时他的指针域指向空
pNew->pNext = NULL;
//使得原先的尾结点指针域指向新结点
pEnd->pNext = pNew;
//令新加入的结点为尾结点
pEnd = pNew;
}
//为pNew在重新开辟一块内存空间用来存储新的数据
pNew = (struct student*)malloc(sizeof(struct student));
if (pNew!=NULL)
{
//重新输入下一组数据
scanf_s("%s", &pNew->Name[20], 20);
scanf_s("%s", &pNew->iNumber[10], 10);
}
}
//释放开辟的空间
free(pNew);
//返回链表的头结点,通过头结点就可以找到整个链表
return pHead;
}
(2020年12月20日,假期坚持打卡第二天,加油!)