首页 > 解决方案 > C 语言使用链表创建实例和数据类型

问题描述

我正在用一本名为 Sams Teach Yourself 的书学习 C 语言。我了解链表的概念,但无法理解该技术。我将写下我是如何理解这一点的,并在此过程中提出一些问题。如果我错了,或者您知道问题的答案,请告诉我。开始了。

第 1 节

首先,我需要定义数据结构并声明头指针以启动如下所示的链表。

struct person{
  char name[20];
  struct person *next;
};
struct person *new;
struct person *head;
head = NULL;

在这里,定义了一个简单的结构。它的类型或标签名称是person. 它有 1 个元素、一个名为 name 的数组和 1 个名为 next 的自引用指针。在结构定义之后,声明了2个指针。其中一个被初始化为NULL,因为当没有什么要指出的时候这是一个很好的做法。

第 1 节问题

第 2 节

这本书解释了将新元素添加到列表开头的过程是 3 步。

  1. 创建结构的实例,使用 malloc() 分配内存空间。
  2. 将新元素的下一个指针设置为头指针的当前值。如果列表为空,则为 NULL,否则为当前第一个元素的地址。
  3. 使头指针指向新元素。
    new = (person*)malloc(sizeof(struct person));
    new->next = head;
    head = new

new分配给malloc,我对此有疑问。的值NULLhead分配给自引用指针,因为它是最后一个指针。然后将 的值new赋给指向head的顶部指针。

第 2 节 问题

标签: cpointerstypeslinked-list

解决方案


在这里,定义了一个简单的结构。它的类型或标签名称是person. 它有 1 个元素、一个名为 name 的数组和 1 个名为 next 的自引用指针。在结构定义之后,声明了2个指针。其中一个被初始化为NULL,因为当没有什么要指出的时候这是一个很好的做法。

一切正确,但要 100% 准确,没有“自引用指针”,它只是一个指向同一类型结构的指针字段,它可以指向该类型的任何其他结构。

这段代码在哪里创建实例?创建实例的格式不是struct标签实例吗?new 是实例吗?它不是第 1 节中声明的指针吗?

“创建实例”是不好的措辞。C 中没有“实例化”之类的东西。在 C 中,内存可以通过两种主要方式分配:自动(通过变量声明)或动态(通过显式调用malloc()或类似函数)。

变量的自动分配发生在堆栈上,并且(正如这个词所暗示的那样)是自动的:您无需担心为变量显式保留空间,编译器会为您完成,并且当变量获取时它也会释放该空间超出范围。动态分配是由用户手动free()执行的,因此一旦不再需要分配的空间,也需要手动清理以释放分配的空间。

在这种情况下,由于您声明了一个指针 struct person *new,您已经自动为指针本身struct分配了空间,但是如果您希望该指针指向有效的东西,您仍然需要为该分配空间。

如何sizeof(struct person)工作?

每种类型都有一个已知的固定大小(几乎,也有例外)。由多个基本类型组成的结构的大小至少是其字段大小的总和。你struct person是你定义的一个新类型,它本身有一个大小,它不仅仅是一个“标签名称”。每次创建类型变量时struct person,程序都需要为其分配sizeof(struct person)字节。尤其是:

sizeof(struct person) >= 20 * sizeof(char) + sizeof(struct person *);
//                            ^^^ always 1   ^^^ usually 4 (on a 32bit system) or 8 (on a 64bit system)

这本书解释了这malloc()是类型转换,因此它的返回值是正确的类型 - 指向 person 数据结构的指针。

错了。您不需要转换malloc(). 在 C 中,有一个特殊的类型void::它的意思是“无类型”。关联的指针类型,void *表示“指向任何类型的指针”,并且是malloc()返回的内容。

void *保证类型的指针始终可以转换为任何其他指针类型,并且从/到void *到/从任何其他指针类型的转换自动发生,无需显式转换。另请参阅此处以很好地解释为什么强制转换的返回值malloc()是一个坏主意。

我以为 C 中的数据类型只有int, char, float & variation of them. 指针是数据类型吗?

哦不,不只是这些。您刚刚自己定义了一个新的数据类型 ( struct person)。我很惊讶您的书在深入研究链接列表和动态内存分配等更高级别的东西之前没有定义数据类型是什么。指针确实是 C 中的另一种基本数据类型,因为您可以获取任何类型的任何变量的地址,所以存在与非指针数据类型一样多的指针数据类型:、、、、int *ecc 。其实是指针数据类型,标识一个指向变量类型的指针。char *float *struct person *struct person


推荐阅读