在参数中更改不具有灵活性的链接列表的值

时间:2015-09-29 00:08:04

标签: c struct linked-list

我有一项任务。我收到了一个我无法修改的函数声明。

函数声明是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

4 个答案:

答案 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来完成此任务。

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