之前只用python写过链表


并不一定要动态分配鸭~

#include &

struct node {
char payload;
struct node *next;
};

int main()
{
struct node node_c = {C, NULL};
struct node node_b = {B, node_c};
struct node node_a = {A, node_b};

struct node *linked_list = node_a;

for (struct node *p = linked_list; p != NULL; p = p-&>next) {
printf("%c -&> ", p-&>payload);
}
puts("[END]");
}

这样也是一个链表,节点都在栈上。不过这样的链表需要编译期已知所有节点,没啥大用。

所以逻辑是这样的:

  • 我要实现链表,并且这个链表要支持动态改变长度
  • 所以节点必须是动态分配出来的
  • 这个链表要给别人用的,而不是我在一个函数里搭起来自娱自乐
  • 所以这个链表节点不能分配在栈上,必须在堆上(比如使用 malloc)

其实就是高中数学「充要条件」,顺过来推是 OK 的,但不能反过来说只要在 C 里实现链表,就必须动态分配,甚至必须用 malloc 来动态分配。


C的一般变数都是在栈上分配的,函数退出就没有了,你应该不希望退出当前函数,这个节点就消失了吧?

malloc动态分配的变数是在堆上的,只要不free就一直存在。

也可以通过全局数组的方式一次性创建多个节点,只要程序不退出就会一直存在,但是这种方式是有上限的。


既然用Python写过链表应该懂得它的底层原理是基于C语言的,你单单会使用什么list

,dict,map但是不知道内存怎么分配的不能称之为写过链表,你这是会使用这些内置函数完成链表的基本操作。


用静态数组一样可以做链表,链表的指针不一定就非要放内存地址,数组下标一样可以当指针。

int node[4] = { 1, 2, 3, 4 };
int next[4] = { 4, 0, 2, 3 };
int head = 0 ;

这也是链表。


因为节点的数量不确定。如果能确定最大数量,那是可以在静态区提前预先划分的,比如早期游戏里的子弹和敌人。


先问是不是,再问为什么。

压根不成立的事情没什么为什么


先要弄清链表的使用场景一般都是什么。不动态分配内存,你说还有使用链表的意义吗?直接数组不就完了


因为一般这个链表节点分配以后要跨越他的生命周期作用域,所以一般都用malloc。


推荐阅读:
相关文章