关于创建链表(C语言基础)我的一些想法

链表


在学到链表时我停留了很长时间,或许是强迫症,总是想要把一小段代码读懂,磨了好久才想通。
接下来让我来讲讲我对链表的理解吧。

创建链表的代码(我苦思冥想的部分)奉上

struct Student* Create()
{
	struct Student* pHead=NULL;
	//定义结构体头指针并指向为空
	struct Student* pConnect;
	//定义用来连接链表的连接指针(也许你很迷茫,但请先这么想着)
	struct Student* pNew;
	//定义新节点
	
	iCount=0;
	iCount++;
	//全局变量自加
	pConnect=pNew=(struct Student*)malloc(sizeof(struct Student));
	//为这两个指针分配内存(不理解?后面细说)
 	
 	printf("输入数据:\n");
 	scanf_s("%d\n",pNew->Data);
 	//分配好了内存就可以输入并存储数据了
 	
 	//重点来了
 	while(pNew->Data!=0)
 	{
 		if(iCount==1)
 		{
 			pNew->pNext=pHead;
 			//第一个新节点结构体的尾部指向NULL(后面没有新节点就还是NULL,如果有就会被覆盖,沙子填空桶式操作嘛)
 			pConnect=pNew;
 			//连接指针指向第一个新节点
 			pHead=pNew;
 			//头指针指向第一个新节点(即开端)

			//这三段代码可以这样表述:
			//pNew,pConnect,pHead都指向同一个地址,但这只是第一个节点展现出的情况,与第二个节点连接这三个指针的功能就会被区分开:
			//pNew为新节点的创建提供支持,
			//pConnect为节点之间的连接提供支持,
			//pHead为链表的开头(保持初始,它不用动,这就是为什么这个函数的后半段代码没它的戏份的原因。)
 		}
 		else
 		{
 			pNew->pNext=NULL;
 			//第二个(或第n个)新节点结构体的尾部指向NULL
 			pConnect->pNext=pNew;
 			//连接指针结构体的尾部指向第二个(第n个)新节点,这不就连接上了么
 			pConnect=pNew;
 			//连接指针重新指向第二个(第n个)新节点,为的是下次再和第三个(第n+1个)新节点连接上
 			//要是没有这一步第二个(第n个)新节点可就有兄弟了(第二个新节点与第三到第n个节点并列,计算机该选择哪个节点呢?)
 		}
 	
 		pNew=(struct Student*)malloc(sizeof(struct Student));
		//新节点重新分配内存
		scanf_s("%d\n",pNew->Data);
 	}
 	free(pNew);
 	//释放新节点未使用的内存
 	return pHead;
 	//返回头指针
};

这样就结束了,对了,还有一段代码我需要解读一下,既然这样,完整的代码我直接连带打出来好了。

pNew=(struct Stduent*)malloc(sizeof(struct Stuent));

左侧,普普通通的指针没啥说的
右侧,

(struct Student*)

看到括号了么,强制转换为结构体指针类型 sizeof,这个本身是测量类型所占内存大小的一个。。。东东吧。

malloc的用法是:void*malloc(unsigned int size)
动态分配一块内存大小为size的内存空间,malloc会返回一个指向分配内存空间的指针,如果出现错误就返回NULL。这要清楚哦。

接下来就是代码时间(累晕了啊)

完整创建链表的代码

#include<stdio.h>
#include<stdlib.h>
//这个预处理文件是给malloc函数以支持的

struct Student
{
	int Data;
	//数据域
	struct Student* pNext;
	//指向下一个节点的尾指针
};
//Student结构体

int iCount;
//定义全局变量

struct Student* Create()
{
	struct Student* pHead=NULL;
	//定义结构体头指针并指向为空
	struct Student* pConnect;
	//定义用来连接链表的连接指针(也许你很迷茫,但请先这么想着)
	struct Student* pNew;
	//定义新节点
	
	iCount=0;
	iCount++;
	//全局变量自加
	pConnect=pNew=(struct Student*)malloc(sizeof(struct Student));
	//为这两个指针分配内存(不理解?后面细说)
 	
 	printf("输入数据:\n");
 	scanf_s("%d\n",&pNew->Data);
 	//分配好了内存就可以输入并存储数据了
 	
 	//重点来了
 	while(pNew->Data!=0)
 	{
 		if(iCount==1)
 		{
 			pNew->pNext=pHead;
 			//第一个新节点结构体的尾部指向NULL(后面没有新节点就还是NULL,如果有就会被覆盖,沙子填空桶式操作嘛)
 			pConnect=pNew;
 			//连接指针指向第一个新节点
 			pHead=pNew;
 			//头指针指向第一个新节点(即开端)

			//这三段代码可以这样表述:
			//pNew,pConnect,pHead都指向同一个地址,但这只是第一个节点展现出的情况,与第二个节点连接这三个指针的功能就会被区分开:
			//pNew为新节点的创建提供支持,
			//pConnect为节点之间的连接提供支持,
			//pHead为链表的开头(保持初始,它不用动,这就是为什么这个函数的后半段代码没它的戏份的原因。)
 		}
 		else
 		{
 			pNew->pNext=NULL;
 			//第二个(或第n个)新节点结构体的尾部指向NULL
 			pConnect->pNext=pNew;
 			//连接指针结构体的尾部指向第二个(第n个)新节点,这不就连接上了么
 			pConnect=pNew;
 			//连接指针重新指向第二个(第n个)新节点,为的是下次再和第三个(第n+1个)新节点连接上
 			//要是没有这一步第二个(第n个)新节点可就有兄弟了(第二个新节点与第三到第n个节点并列,计算机该选择哪个节点呢?)
 		}
 	
 		pNew=(struct Student*)malloc(sizeof(struct Student));
		//新节点重新分配内存以供下面输入的数据使用
		scanf_s("%d\n",&pNew->Data);
 	}
 	free(pNew);
 	//释放新节点未使用的内存
 	return pHead;
 	//返回头指针
};
//Create创建链表

void Print(struct Student* pHead)
{
	int iIndex=0;//定义循环变量记录链表节点个数
	while(pHead!=NULL)
	{
		iIndex++;
		printf("NO%d.:\n",iIndex);
		printf("%d\n",pHead->Data);
		printf("\n");
		pHead=pHead->pNext;
		//头指针指向第二个(第n个)节点
	}
}
//打印链表

int main()
{
	struct Student* pHead;//可以不是pHead,这个pHead和前面定义的没关系
	pHead=Create();//使刚刚定义的指针指向Create返回的pHead的地址值
	Print(pHead);
	return 0;
}
//主函数

自己写的代码可能多多少少有些问题,我测试过,好像前面输入的数反倒到了后面,不过无伤大雅,嘿嘿,不管怎么说,自己想出来的代码才能被自己真正接受,希望各位能有所启发吧。

上一篇:一道很简单的题目--不同的写法


下一篇:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse问题解析