10

十分钟带你理解C语言中的链表

 4 years ago
source link: http://developer.51cto.com/art/202009/627390.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

IZ7NveZ.jpg!mobile

首先,指针计算机中的所有内容都是数字。在C语言中创建变量时,编译器仅按地址处理它,但是在您的代码中,您可以通过两种方式访问它:按值和按地址。

vUzAf2Q.png!mobile

在该代码中,我使用了三个变量,编译器将通过地址访问所有这些变量。

时间-全局变量-存储在堆中

skip- 参数-存储在堆栈中

i- 局部变量-存储在堆栈中

“ Hello world-%d \ n”-存储在堆中

堆是由编译器与您的代码链接的启动代码分配的内存块。创建方式并不重要,但并非所有编译器都一样。那是我们想要得到的技术。

为简化起见,假设变量Times 结束于内存位置256(0x100)。堆栈上的变量i 的位置为64(0x40)。文字“ Hello ...”的位置为200(0xc8)。最后,跳过会得到68(0x44)。

现在假设您像这样调用function():

JfYfErN.png!mobile

这是for循环开始时的内容:

时间-存储在0x100-值为10

跳过-存储在0x44-值2

i- 存储在0x40-值0

未命名文字存储在0xc8-值“ Hello world-%d \ n

现在寻址非常简单。在C语言世界中,当您使用不是指针的变量名时,编译器会将其视为“存储在地址中的值”。因此,当您使用变量skip时,编译器将使用“存储在0x44处的值”。该代码段中的所有变量均为“按值”,表示仅使用值。指针是变量的地址。假设我们这样做:

eyqABrb.png!mobile

现在,您有了一个名为TimesPtr 的变量。像所有其他变量一样,它具有与之关联的内存地址。但是通过将其定义为指针,您可以指定其值为内存地址。

因此,使用上述所有数字,我们还将添加

TimesPtr -存储在地址260(ox104) -堆栈中的

数-存储在地址263(量0x108) -在堆

我们已将TimePtr 分配为Times 的地址,即0x100。在循环开始时,我们指定i = 0,因此0存储在0x40中。我们还分配Num ,它也是指向整数0的指针。编译器将创建代码,0被放入量0x108,地址数。

当您使用'*'运算符时,您正在告诉编译器使用您指定的变量“存储在地址中的值”。当仅使用变量名时,您将告诉编译器“存储的值”。

顺便说一句,在printf()调用中,将文字的地址传递给函数printf(),因为文字在编译器中仅具有一个地址,而不是名称(并且数组通过地址传递,并且该文字是一个字符数组) )。

创建链表最简单的方法是简单地将一个指针添加为指向该结构本身的结构成员。它是这样完成的:

jumquiF.png!mobile

如果要使用typedef ,则不能使用typedef 名称,因为它尚未定义。假设我们想将_student 结构引用为studentT 。代码如下所示:

eeMRRv.png!mobile

现在,next将是列表中下一个节点的地址,如果没有,则为NULL。

ErAfAf6.png!mobile

这是创建链接列表的最简单方法。只需创建一个节点,将其下一个指针分配给列表地址,然后将列表头分配给该节点的地址。在类中,您最好处理strdup(),并记住在删除节点时将其释放。

现在,您需要在单个链表中插入和删除的操作。我将为您提供一个通用链表,以保存任何数据类型:

quY3Yr.png!mobile

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK