我正在练习链表代码。下面是插入函数:
Node* insert_at_pos(Node *head, int pos){
struct Node *ptr=NULL;
printf("enter data\n");
ptr=(Node*) malloc(sizeof(Node));
scanf("%d",&ptr->data);
ptr->next=NULL;
if (pos==0){
if (head==NULL){
head=ptr;
return head; //return that I want to remove
}
}
printf("done\n");
}
如果我返回 void
而不是返回 Node*
,我认为这段代码应该仍然有效,因为我正在通过引用传递值。所以 head
的值应该自动更新而不是返回它,但是如果我删除 Node*
并将 void
放入它就不起作用insert_at_pos
的返回类型。
而且,我正在像这样调用 insert_at_pos
函数::
Node *head=insert_at_pos(head,0);
可能的解释是什么或这里出了什么问题?
最佳答案
基本上有两种方法可以解决这个问题。要么传递指针的地址(键入 Node**
,传递 &head
),要么创建一个单独的列表类型。
第二个解决方案看起来像这样:
typedef struct List {
Node *head;
} List;
然后可以像这样创建一个新的空列表:
List *list = malloc(sizeof (List));
list->head = NULL;
两种方式都可以。从概念上讲,第二种解决方案更符合实际问题,因为它将列表与数据节点区分开来。您可以在不更改列表句柄的情况下创建列表并添加或删除值。
第一个解决方案尝试通过让列表头成为列表句柄来跳过列表的单独实体。问题在于空列表没有任何节点,因此空列表由 NULL 表示。这意味着当列表从空转换为非空或从非空转换为空时,列表句柄会发生变化,因此当您插入或删除项目时,列表句柄可能会发生变化。
使用第一个解决方案的插入函数可以这样声明:
void insert(Node **head, int value);
调用看起来像这样:
Node *head = null;
insert(&head, 42);
或者可以这样声明(就像你的问题):
Node* insert(Node *head, int value);
然后这样调用:
Node *head = null;
head = insert(head, 42);
关于c - 通过引用传递时原始值不会改变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40153245/