C语言 在参数不灵活的情况下改变链表的值



我有个任务。我得到了一个不能修改的函数声明。

函数声明是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()函数内部执行的任何操作都将作用于原始列表。

这条规则的唯一例外是,如果你试图在插入方法中重新分配L,像这样:
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 =来完成这个任务。

此外,好好看看先决条件-他们应该描述的情况,你不需要麻烦自己(可能,我不知道是谁创建了这个任务,但我会这样理解它)-意思是,如果用户不遵守他们,这是用户自己的错,任何不好的事情都可能发生

相关内容

  • 没有找到相关文章

最新更新