c - 了解推送功能
问题描述
我很难理解 C 中链表的推送功能。例如,我有以下结构
typedef struct node {
int val;
struct node * next;
} node_t;
我已经创建了一个这样的链接列表
// creating list
node_t * head = NULL;
head = (node_t *) malloc(sizeof(node_t));
// checking if list is initialised sucessfully
if (head == NULL) {
return 1;
}
// 1st and 2nd element
head = (node_t *) malloc(sizeof(node_t));
head->val = 1;
head->next = (node_t *) malloc(sizeof(node_t));
head->next->val = 2;
head->next->next = NULL;
推送功能是这样给出的
void push(node_t ** head, int val) {
node_t * new_node;
new_node = (node_t *) malloc(sizeof(node_t));
new_node->val = val;
new_node->next = *head;
*head = new_node;
}
我的问题是为什么new_node->next
分配给取消引用head
?我认为head
应该是一个指针,从而使*head
下一个node_t
本身。new_node.next
是一个指针,因此应该new_node->next = head
改为?
其次,最后一行*head = new_node
是否与head = &new_node
? 更何况,是不是一样**head = &new_node
?最后一个对我来说最有意义,因为我们将指针的指针作为push
.
解决方案
我的问题是为什么
new_node->next
分配给取消引用head
?
因为head
函数的参数push
是指向头指针的指针。您必须取消引用它一次才能获得(假定的)指向链表头节点的指针。这当然必须在调用方匹配——它们必须传递列表头指针的地址。
我认为
head
应该是一个指针,从而使*head
下一个node_t
本身。
head
所呈现的代码通过在不同的范围内使用相同的标识符“”来表示不同级别的间接性,从而稍微混淆了这一点。在函数push
中,参数head
是 a node_t **
。是的,这是一个指针,但不是指向头节点。相反,它指向另一个指针,该指针又指向头节点。 *head
有一个node_t *
,没有一个node_t
。
其次,最后一行
*head = new_node
是否与head = &new_node
? 更何况,是不是一样**head = &new_node
?
不,这些都是不同的,这直接来自于head
,*head
和**head
都指定不同的对象这一事实。在函数push()
中,
head
指定函数参数,它具有类型node_t **
并且是函数的局部参数。赋值head = &new_node
将是类型正确且总体有效的,设置head
为指向函数的局部变量new_node
,但这没什么用,因为它不会向函数的调用者传达任何内容,并且它在函数本身内没有任何特殊用途。*head
当然,指定对象head
指向的对象,由函数调用者选择。它有类型node_t *
。调用者可以访问该指针对象,例如,它可以是调用者的局部变量之一。赋值*head = new_node
修改了调用者可访问的对象,因此调用者可以看到它的效果,这就是参数作为双指针的目的。**head
指定*head
指向的对象 anode_t
. 调用者也可以访问该对象,但修改它不会满足函数的目的。然后调用者将得到相同的一个node_t
对象,只是内容不同。在任何情况下,表达式&new_node
anode_t **
都没有正确的赋值类型**head
。如果一个人真的打算分配给它,那么一个类型正确(但在语义上不合适)的选项将是**head = *new_node
.
最后一个对我来说最有意义,因为我们将指针的指针作为
push
.
将指针传递给指针的原因是函数可以修改指向的指针。结果是之后,调用者的指针指向由 分配的节点push
,而该节点的next
指针指向调用者的指针最初指向的节点。这正是将节点添加到列表中所需要的。调用者的视图如下所示:
在推()之前
X --next--> ... --next--> NULL
|
v
Value1 ...
推送后(Value2)
Y --next--> X --next--> ... --next--> NULL
| |
v v
Value2 Value1 ...
但是,如果push
改为分配给**head
,结果将是
X --next--> (depends)
|
v
Value2
请注意,Value1
现在消失了,取而代之的是Value2
.
推荐阅读
- sql - 多个 GROUP 和 COUNT Oracle SQL
- rdf - Virtuoso OWL 2 DL 推理
- javascript - 在 passProps 中传递函数数组会导致来自 JS 的错误调用:字段大小不同
- python - 改进 Python 列表理解以消除嵌套数组
- javascript - 绑定与箭头函数(在 JavaScript 中,或用于响应 onClick)
- perl - 无法在 Windows 上安装 LWP::Parallel::UserAgent (Strawberry Perl)
- c - 如何初始化一个不定长度的数组
- streaming - 使用文件夹中的 mp3 设置简单的音频直播流
- c++ - C++中的移动构造函数和复制构造函数
- python-3.x - 用 Python 处理 .docm 文件?