我有一项任务。我收到了一个我无法修改的函数声明。
函数声明是void Insert (Item x, int p, List *L);
我应该更改链表结构L的值。
现在,在我的main函数中调用该方法的代码是
struct List *L = malloc(sizeof(List));
Insert(x,p,L);
我如何更改代码以便我可以传递struct List的地址而不是另外复制它?
就像我说的,我根本无法改变功能声明。
/*********************************************************************
* FUNCTION NAME: Insert
* PURPOSE: Inserts an Item in a List.
* ARGUMENTS: . The Item to be inserted (Item)
* . The position in the List
* where the Item should be inserted in (int)
* . The address of the List (List *L)
* REQUIRES (preconditions):
* . The position should be a nonnegative integer
* not greater than the size of the List.
* . The List should not be full.
* ENSURES: . Empty will return false (0).
* . Size will return the first integer greater
* than the size of the List before the call.
* . Peek in the same position will find
* the Item that was inserted.
*********************************************************************/
extern void Insert (Item X, int position, List *L);
我尝试过的不起作用的是
head->next = L; //changing the next item in list to L
L = head; //changing the address of L so it remains the head of the list
答案 0 :(得分:0)
您可能想要查看地址之间的差异(或相似性),C中的指针,因为您的问题的答案是您已经传递了结构列表的地址。
我会尝试解释一下。 malloc()返回一个内存地址,AKA是一个指针,由struct List *L
中的*符号表示。当我在脑海中读到这一行时,我会说" L包含指向结构列表对象的指针"或" L包含struct List对象的内存地址"。
因此,在这种情况下,当你编写Insert(L, x)
时,你已经传递了一个指向struct List对象的指针。并没有其他副本。因此,您在Insert()
函数内执行的任何操作都将在原始列表中执行。
此规则的唯一例外是,如果您尝试在插入方法中重新分配L,如下所示:
void Insert(struct List* L, int x) {
L = NULL; // or L = malloc(sizeof(struct List));
}
这不符合您的预期,但其原因更为复杂,您可能暂时不需要知道。
答案 1 :(得分:0)
您的函数声明存在异常。
您的代码建议您使用具有以下签名的函数:
void Insert (struct List *L, int x);
您链接的头文件使用带有此签名的函数插入:
extern void Insert (Item X, int position, List *L);
请注意附加参数Item X
。
由于您还没有向我们展示您的大部分代码,因此还有很多工作要做,但我建议您查看您丢失的参数。
答案 2 :(得分:0)
I think this will work:
void Insert (Item x, int p, List *L) {
struct List newnode, last = *L;
newnode = (struct List)malloc(sizeof(struct List));
newnode->item = x;
newnode->next = NULL;
if (last == NULL){
if (p == 0) { *L = newnode; }//first node
else { printf("List is empty and index %d does not exist", p); }
} else if (p == 0) {
newnode->next = *L;
*L = newnode;
}
else{
int counter = 0;
while (1) {
if (counter == p) {
newnode->next = last->next;
last->next = newnode;
break;
}
last = last->next;
counter++;
if (last->next == NULL && counter != p){ break; }
}
}
}
答案 3 :(得分:0)
首先:
我如何更改代码以便我可以传递struct List的地址而不是另外复制它?
您已经在执行此操作:void Insert (Item x, int p, List *L);
将指针带到列表结构,而不是结构本身,因此您不会复制它。
其次:
我尝试过的不起作用的是head-> next = L; //将列表中的下一项更改为L. L = head; //更改L的地址,使其保持列表的头部
它无效。内部Insert
函数L是指向List的指针的值。因此,如果您在函数内更改此值,则不会在外部更改,因为L的值通过副本传递。只会看到*L
的更改,因为它们不会更改L
本身的值,而是L
指向的值。
我可以向您保证,L =
函数中不需要Insert
来完成此任务。
此外,要好好看看先决条件 - 他们应该描述一些你不需要麻烦的情况(可能,我不知道创造了这个任务的人,但我会这样理解) - 意思是,如果用户不遵守它们,它是用户自己的错,任何坏事都可能发生。