【发布时间】:2018-06-02 16:10:00
【问题描述】:
根据我目前对C如何工作的了解,如果我以这种方式使用函数List_int_add(linklist, 50)而不必分配linklist = List_int_add(linklist, 50),则链接列表的值将更新为List_int_add(linklist, 50)的返回值,因为代替linklist 的是参数Node_int * head,并且函数返回head。由于参数是一个指针,List_int_add(linklist, 50) 不应该足以更新linklist 吗?
使用List_int_add(linklist, 50) 时,List_int_print(linklist) 的输出将从 100 开始,而不是 50。但如果我分配给 linklist=List_int_add(linklist, 50),它会正常工作。
(请忽略返回时的类型转换,这是由于我之前编写代码的方式,而我正在编辑代码中,我知道没有必要)
提前致谢。
在 main.c 中:
#include <stdio.h>
#include <stdlib.h>
#include "LinkedList/linkedlist.h"
int main(int argc, char ** argv){
Node_int * linklist = NULL;
linklist = List_int_add(linklist, 50);
linklist = List_int_add(linklist, 100);
linklist = List_int_add(linklist, 150);
linklist = List_int_add(linklist, 200);
linklist = List_int_add(linklist, 250);
linklist = List_int_add(linklist, 300);
linklist = List_int_add(linklist, 350);
linklist = List_int_remove(linklist,50);
List_int_print(linklist);
List_int_destroy(linklist);
if (linklist == NULL)
List_int_print(linklist);
return EXIT_SUCCESS;
}
在linkedlist.c中:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "linkedlist.h"
/* Node_int_construct: create a Node_int */
static Node_int * Node_int_construct(int val);
/* Node_int_construct: create a Node_int */
static Node_int * Node_int_construct(int val){
Node_int * nd = (Node_int *) malloc(sizeof(Node_int));
nd->next = NULL;
nd->prev = NULL;
nd->value = val;
return nd;
}
Node_int * List_int_add(Node_int * head, int val){
Node_int * nd = Node_int_construct(val);
// insert at the end
Node_int * ptr = (Node_int *) head;
if (ptr == NULL){
head = nd;
head -> next = NULL;
head -> prev = NULL;
return (Node_int *) head;
}
while (ptr->next != NULL){
ptr = ptr->next;
}
nd->prev = ptr;
ptr->next = nd;
return (Node_int *) head;
}
Node_int * List_int_remove(Node_int * head, int val){
Node_int * target = List_int_search((const Node_int * const) head, val);
if (target == NULL){
return target;
}
if (target == head){
head = head->next;
head->prev = NULL;
free(target);
}
else if (target->next == NULL){
Node_int * ptr = target->prev;
ptr->next = NULL;
free(target);
}
else {
Node_int * prev = target->prev;
Node_int * next = target->next;
prev->next = next;
next->prev = prev;
free(target);
}
return head;
}
void List_int_destroy(Node_int * head){
Node_int * ptr = head;
Node_int * temp;
while (ptr != NULL){
temp = ptr;
ptr = ptr->next;
free(temp);
}
}
Node_int * List_int_search(const Node_int * const head, int val){
Node_int * ptr = (Node_int *) head;
while (ptr != NULL){
if (ptr->value == val){
return ptr;
}
ptr = ptr->next;
}
return ptr;
}
void List_int_print(const Node_int * const head){
Node_int * ptr = (Node_int*) head;
while (ptr != NULL){
printf("> %d \n", ptr->value);
ptr = ptr->next;
}
}
在linkedlist.h中:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
typedef struct _node_int {
struct _node_int * next;
struct _node_int * prev;
int value;
} Node_int;
/* List_int_add: add Node_int at the end of list. */
Node_int * List_int_add(Node_int * head, int val);
/* List_int_remove: remove first item that matches val.
Returns head if successful, returns NULL if failure */
Node_int * List_int_remove(Node_int * head, int val);
/* List_int_destroy: Delete entire list. */
void List_int_destroy(Node_int * head);
/* List_int_search: Returns pointer to node of the first matching item in list,
NULL if node is not found. */
Node_int * List_int_search(const Node_int * const head, int val);
/* List_int_print: print int list. */
void List_int_print(const Node_int * const head);
#endif
【问题讨论】:
-
与您的问题无关,但在
List_int_add函数中,变量head的类型为Node_int *,与函数声明返回的类型相同。这意味着您不需要转换head,因为您将它转换为它已经是的类型。尽可能避免强制转换。如果编译器抱怨,那么首先检查代码,看看你是否犯了错误,如果你 100% 确定你没有,那么你就投了。 -
至于你的问题,你通过指针按值。要模拟按引用传递,您需要传递一个指向变量的指针,在您的例子中是指向指针的指针,类型为
Node_int **。并在传递变量时使用地址运算符&。 -
如果你像这样调用
void foo(int bar) {bar = 42;}这个函数int x = 0; foo(x);在调用foo之后x的值是多少? -
@LưuVĩnhPhúc 谢谢!
标签: c pointers linked-list