(C语言)数据结构学习笔记:深入学习链表(调试和指针的应用)

预备知识

1.初识指针

   对于刚刚入门的小伙伴来说,指针似乎是一种很神奇的东西,老师在课堂上的解释往往不够形象,这给理解指针带来了很大的不便。下面我用一张图片来解释什么是指针。

(图一)

   如上图所示,图中未加粗的方框表示四块内存单元。在我所使用的Visual Studio 2022集成开发环境和64位操作系统的计算机中,内存采用0x+16位十六进制数字表示。图中的每一串18个字符长度的编码表示一块地址,也就是指针。每一个18个字符长度的编码都表示一块内存单元。图一左上角的编码0x0000012907850890表示左上角的内存单元,左上角加粗的方框中的编码0x0000012907850520表示右下角的内存单元。

  在C语言编写的链表结构中,每一块加粗的方框表示一个结构体,这个结构中包含两个数据类型,一个int类型数据和一个结构体指针类型数据。使用操作符 - >可以访问每一个结构体中的数据。

  2.认识调试

  在小伙伴们学习编程的过程中,我可以很负责地表示,调试一定很重要。可能你们学校的老师压根就没有使用过Visual Studio中的“本地Windows调试器”,但是在编程中,尤其是使用高版本的编译器的过程中,调试对找bug意义重大。比如,在Visual Studio 2022中,我就遇到过编译器不报错,但是程序执行时不会输出任何结果。当代码量很大的时候,找bug就会显得非常困难。但是使用调试可以看清程序执行的步骤,可以看到每一个变量的值的变化情况,这对于初学者排错来说非常重要。

  调试过程如下图:

  (图二)

(图三)

创建链表

  1.创建头节点

  如下图所示,我们用一个结构体表示一个节点的值和下一个节点的地址

struct SingleList
{
	int data;
	struct SingleList* next;
};

(图四)

  图四所示的代码可形象地表示为

(图五)

2.为头节点分配内存

struct SingleList* Header = (struct SingleList*)malloc(sizeof(struct SingleList));

(图六)

  此时链表的头节点内存表示为

(图七)

3.初始化头节点

void Init(struct SingleList* Header)
{
	Header->data = 1;
	Header->next = NULL;
}

(图八)

  此时链表的头节点内存表示为

(图九)

4.头插法创建链表

void AppendNode_HeadInsert(struct SingleList* Header)
{
	for (int i = 0; i < 5; i++)
	{
		struct SingleList* Node = (struct SingleList*)malloc(sizeof(struct SingleList));
		Node->data = i+2;
		Node->next = Header->next;
		Header->next = Node;
	}
}

(图十)

  利用调试得出各个节点的地址,其内存表示为

(图十一)

5.尾插法创建链表

void AppendNode_TailInsert(struct SingleList* Header)
{
	int i = 0;
	while (Header != NULL && i != 5)
	{
		struct SingleList* Node = (struct SingleList*)malloc(sizeof(struct SingleList));
		Node->data = i+2;
		Node->next = Header->next;
		Header->next = Node;
		Header = Header->next;
		i++;
	}
}

(图十二)

利用调试得出各个节点的地址,其内存表示为

(图十三)

6.综合代码

#include<stdio.h>
#include<stdlib.h>
struct SingleList
{
	int data;
	struct SingleList* next;
};
void Init(struct SingleList* Header)
{
	Header->data = 1;
	Header->next = NULL;
}
void AppendNode_HeadInsert(struct SingleList* Header)
{
	for (int i = 0; i < 5; i++)
	{
		struct SingleList* Node = (struct SingleList*)malloc(sizeof(struct SingleList));
		Node->data = i+2;
		Node->next = Header->next;
		Header->next = Node;
	}
}
void AppendNode_TailInsert(struct SingleList* Header)
{
	int i = 0;
	while (Header != NULL && i != 5)
	{
		struct SingleList* Node = (struct SingleList*)malloc(sizeof(struct SingleList));
		Node->data = i+2;
		Node->next = Header->next;
		Header->next = Node;
		Header = Header->next;
		i++;
	}
}
int main()
{
	struct SingleList* Header = (struct SingleList*)malloc(sizeof(struct SingleList));
	Init(Header);
	//AppendNode_HeadInsert(Header);
	AppendNode_TailInsert(Header);
	while (Header!= NULL)
	{
		printf("%d ", Header->data);
		Header = Header->next;
	}
	return 0;
}

注意事项

  1.将代码直接复制粘贴后运行,则执行尾插法。

  2.由于分配内存单元具有随机性,故每次调试的地址值会不相同

  3.本文使用C语言进行编码,故在创建源文件时应将后缀名更改为.c

  4.代码中NULL表示的内存单元为0x0000000000000000

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的程序员小蒋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值