【问题标题】:Problem with implementing a function to reverse a linked list in C在 C 中实现函数以反转链表的问题
【发布时间】:2021-02-15 13:45:28
【问题描述】:

所以我想编写一个函数来使用指针数组反转链表,但我收到警告:来自不兼容指针类型 [-Wincompatible-pointer-types] 的赋值。我想将指向列表节点的指针存储在指针数组int **s = (int **)calloc(10, sizeof(int)); 中,并认为s[*top] = *l 将分配指向**l 指向*top 数组*s[] 的第一个元素的指针。那么我错误地认为数组*s[] 的元素是指针吗?如果有人可以向我解释,我会很高兴。这是整个代码(除了我创建列表的部分):

typedef struct list {
    int v;
    struct list *next;
} list;

void reverseListS(list **l, int **s, int *top) {
    while ((*l)->next != NULL) {
        s[*top] = *l;
        *top++;
        *l = (*l)->next;
    }
    list *temp = *l;
    while (!(*top == 0)) {
        temp->next = s[*top];
        *top--;
        temp = temp->next;
    }
    temp->next = NULL;
}

int main() {
    int **s = (int **)calloc(10, sizeof(int));
    int *top = 0;

    reverseListS(&l, s, top);
}

【问题讨论】:

  • 提供的代码没有意义。例如代替 int **s = (int **)calloc(10, sizeof(int));你至少应该写 int **s = (int **)calloc(10, sizeof(int *));
  • 很多问题。就在main:应该是sizeof(int *)(或sizeof *s)。虽然,我认为你希望s 是一个整数数组,所以它应该是一个int *。而top 没有指向任何地方——为什么它甚至是一个指针? l 未初始化....
  • 您可能应该从一段更简单的代码开始,比如填充一个列表并打印它。一旦它起作用,增加更多的复杂性。解开这段代码是不可行的,扔掉它重新开始吧。
  • @JohnnyMopp 我说我跳过了初始化list *l,我可以编辑它。我认为sizeof(int *)sizeof(int) 之间没有区别,因为用于存储整数的字节数与指向整数的指针相同(如果我错了,请纠正我)。我将top 设为一个指针,这样在函数内部更改它的值也会在外部影响它。如果s 是一个整数数组,我可以分配一个指向存储在该数组中的值的指针吗?因为我试图这样做,但它没有用,并且用谷歌搜索你不能真正指向一个指向存储在整数变量中的地址的指针。
  • 通常,无论类型如何,指针大小都是相同的,但这并不能保证。 Are all data pointers the same size in one platform for all data types?

标签: arrays c pointers


【解决方案1】:

很多问题。就在main:应该是sizeof(int *)(或sizeof *s)。虽然,我认为您希望sints 的数组,所以它应该是int *。而top 并没有指向任何地方——为什么它甚至是一个指针? l 未初始化。

reverseListS s[*top] = *l; 中,您尝试将struct list * 分配给int *

我已经重新编写了你的​​代码来工作。我并不是说这是反转列表的最佳方式,但它对您的代码的修改最少 - 据我了解。

typedef struct list {
    int v;
    struct list *next;
} list;

void reverseListS(list **l)
{
    // Count number of items
    //   *this step could be skipped by dynamically resizing the array with realloc
    int count = 0;
    list *temp = *l;
    while (temp) {
        count += 1;
        temp = temp->next;
    }
    // Allocate memory - an array of list *
    list **s = malloc(count * (sizeof *s));
    if (!s) return;
    // Copy list item addresses to array
    temp = *l;
    int index = 0;
    while (temp) {
        s[index++] = temp;
        temp = temp->next;
    }
    // Rebuild the list in reverse order
    //   *if you already have an "append_to_list" function, that should be used here
    temp = NULL;
    for (int i = index - 1; i >= 0; i--) {
        if (!temp) {
            // This is the new first item in list.
            // Make the original list point to it
            *l = temp = s[i];
        }
        else {
            // Append to end of new list
            temp->next = s[i];
            temp = s[i];
        }
        s[i]->next = NULL;
    }
    free(s);
}
int main() {
    list *l;
    // TODO: Fill the list with values.
    reverseListS(&l);
}

【讨论】:

  • 不,这不是我想做的,这是微不足道的。我想创建一个指针数组来存储列表节点的地址:首先将列表移动到末尾,同时将每个节点的地址复制到该数组,然后返回列表,同时使用它更改节点之间的链接指针数组。 (我见过在 C++ 中使用堆栈完成的事情,但在 C 中没有找到它,最初尝试这样做)
  • 重点在于将指针保存在数组/动态内存中
  • @Vojtie 好的。我没明白。查看更新的答案。
  • @Vojtie 不,请注意我将定义更改为list **s,因为它应该是list * 的数组,而不是int * 的数组。
  • 哦,好吧,我没注意到。谢谢!现在真的很有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 2020-02-25
  • 2017-12-12
  • 2019-06-14
  • 2013-07-27
  • 2015-08-23
  • 1970-01-01
相关资源
最近更新 更多