我有个任务。我得到了一个不能修改的函数声明。
函数声明是void Insert (Item x, int p, List *L);
,我应该改变链表结构体l的值
现在,在主函数中调用该方法的代码是
struct List *L = malloc(sizeof(List));
Insert(x,p,L);
我该如何改变我的代码,这样我就可以传递结构体列表的地址,而不是制作它的另一个副本?
就像我说的,我根本不能改变函数声明。
/*********************************************************************
* 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
我认为这将工作:
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; }
}
}
}
你可能想回顾一下C语言中地址、指针之间的区别(或相似之处),因为你的问题的答案是你已经传递了struct List的地址。
我试着解释一下。malloc()返回一个内存地址,也就是一个指针,在struct List *L
中用*符号表示。当我在脑海中读到这一行时,我会说"L包含一个指向struct List对象的指针"或"L包含一个struct List对象的内存地址"。
所以在这种情况下,当你写Insert(L, x)
时,你已经传递了一个指针到你的struct List对象。而且没有其他的副本。因此,您在Insert()
函数内部执行的任何操作都将作用于原始列表。
void Insert(struct List* L, int x) {
L = NULL; // or L = malloc(sizeof(struct List));
}
这将不会达到您所期望的效果,但其原因更复杂,您可能暂时不需要知道。
你的函数声明不规范。
你的代码表明你有一个签名如下的函数:
void Insert (struct List *L, int x);
你所链接的头文件使用了一个带有以下签名的函数插入:
extern void Insert (Item X, int position, List *L);
注意附加参数Item X
。
由于您没有向我们展示太多代码,因此没有太多可继续进行的内容,但我建议查看一下您缺少的参数
首先:
我该如何改变我的代码,这样我就可以传递结构体列表的地址,而不是制作它的另一个副本?
你已经这样做了:void Insert (Item x, int p, List *L);
将指针指向List结构,而不是结构本身,所以你没有复制它。
其次:
我试过没有工作的是head->next = L;//将列表中的下一项更改为LL = head;//更改L的地址,使其仍然是列表的头
行不通。在Insert
函数中,L是指向List的指针的值。所以如果你在函数内部改变了这个值,它不会在函数外部改变,因为L的值是通过拷贝传递的。只会看到*L
的变化,因为它们不会改变L
本身的值,而是L
指向的值。
我可以向你保证,在Insert
函数中不需要L =
来完成这个任务。
此外,好好看看先决条件-他们应该描述的情况,你不需要麻烦自己(可能,我不知道是谁创建了这个任务,但我会这样理解它)-意思是,如果用户不遵守他们,这是用户自己的错,任何不好的事情都可能发生