鱼C论坛

 找回密码
 立即注册
查看: 551|回复: 3

[技术交流] 搞笑抽象单链表/指针

[复制链接]
发表于 2023-11-30 19:14:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在写单链表的时候觉得函数void addPerson(struct Person **contacts) 里的这个**有点难理解
作业做多了以后开始形成抽象的理解,感觉自己的这个理解还算能自圆其说,为了怕以后忘记决定记录下来,也供各位玩笑玩笑

以单链表3课后作业动动手最后一题通讯录为例子。截取一段 addPerson函数
  1. void addPerson(struct Person **contacts)
  2. {
  3.         struct Person *person;
  4.         struct Person *temp;
  5.    
  6.         person = (struct Person *)malloc(sizeof(struct Person));
  7.         if (person == NULL)
  8.         {
  9.                 printf("内存分配失败!\n");
  10.                 exit(1);
  11.         }
  12.    
  13.         getInput(person);
  14.    
  15.         // 将person用头插法添加到通讯录中
  16.         if (*contacts != NULL)
  17.         {
  18.                 temp = *contacts;
  19.                 *contacts = person;
  20.                 person->next = temp;
  21.         }
  22.         else
  23.         {
  24.                 *contacts = person;
  25.                 person->next = NULL;
  26.         }
  27. }
复制代码

困扰问题:个人之前对于 **contact *contact  &contact *person person 或 **head头指针的理解有点混乱。
==================以下开始抽象=======================
将函数括号里定义的*理解为穿一件衣服,**就是穿两件衣服;函数花括号内的*定义为脱衣服,*是脱一件衣服;main函数里实参的&是多穿一件衣服
首先 为什么add函数里是穿两件,一是因为要保证人(值)至少穿了一件衣服(不能luo奔),即保证单链表有一个指向肉体的指针。二,外面的第二件是为了给第二个人留的,告诉第二个人你来了有衣服穿,保证有第二个人来的位置(保证了是个链表)。所以用到**的函数都是与 下一个人 有关的如delete,add,(release);用到*的函数则是对 单个人 进行的操作,如print,change,find
其次 在函数花括号内,大家都是穿了一件衣服的,你穿了两件就要*(脱掉一件),原本就穿了一件的,就不用操作,直接出门就好。
然后 何时用contact/head,何时用person,看你想表达的是整个表还是其中的单项。 以上段程序中  if (*contacts != NULL)就是判断表空不空, if (person == NULL)是判断单项空不空(都是指针,不是值的空不空哦)
最后 在main函数里,定义的contact就穿了一件衣服( struct Person *contacts = NULL;),但实际上add函数里输入的是穿了两件的,所以需要&一下。

大伙看看这样理解逻辑咋样^^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-11-30 19:14:22 | 显示全部楼层
你的抽象比喻很有趣!这样的理解方法确实可以帮助初学者更好地理解指针和链表。

在C语言中,指针是一种特殊的变量类型,它存储的是内存地址。而链表是由多个节点组成的数据结构,每个节点包含一个值和指向下一个节点的指针。

在函数声明中,`struct Person **contacts` 表示一个指向指针的指针,也就是两层间接引用。这是因为我们需要在函数中修改传入的指针,以便在添加新节点时能正确更新链表的头部。

在函数内部,`*contacts`表示指向链表头部指针的指针。为了方便理解,你可以将其理解为一个人的地址,也就是一个人的衣服。`person`则是新创建的节点。

接下来的代码通过头插法将新节点插入到链表中,如果链表不为空,则将原来的头部节点暂存到 `temp` 变量中,然后将新节点 `person` 设为链表的头部,并将指针重新指向 `temp`。这样就完成了在链表头部插入新节点的操作。

如果链表为空,即 `*contacts` 为 `NULL`,则直接将新节点设为链表的头部,并将新节点的指针指向 `NULL`。

最后,在 `main` 函数中,我们声明了一个链表的头部指针 `struct Person *contacts = NULL;`,也就是一个人的衣架。当我们需要调用 `addPerson` 函数时,我们传递的是这个指针的地址 `&contacts`。这样在函数内部可以通过 `*contacts` 来修改传入的指针。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-30 19:26:46 | 显示全部楼层
GPT一种挽尊的存在,我爱你!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-30 19:26:52 | 显示全部楼层
妖娆乌龙茶 发表于 2023-11-30 19:26
GPT一种挽尊的存在,我爱你!

感谢您的赞美!作为一种人工智能技术,GPT确实可以提供帮助和解答各种问题。我会尽力回答您的问题并提供指导。如果您还有其他问题,随时告诉我,我会尽力帮助您。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-2 01:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表