【问题标题】:C error: cannot take the address of an rvalue of type 'void'C 错误:无法获取“void”类型的右值的地址
【发布时间】:2016-04-07 21:10:20
【问题描述】:

完整的错误信息

dll.c:89:13: 错误:无法获取类型为“void”的右值的地址 arr2[i] = &(*remove)(list);

我的函数应该有 4 个参数,一个两个数组,一个长度值,一个删除函数和一个插入函数。然后它获取第一个数组的值并将它们放入一个链表中。然后它从链表中删除值并将它们插入到第二个数组中。我遇到问题的部分是将值插入到第二个数组中。我知道问题与我对指针的理解有关。我知道数组是void *,并且我的删除函数返回void *,所以最初我尝试了arr2[i] = (*remove)(list),但我也遇到了编译器错误。所以我添加了& 只是因为这在过去似乎有效(我知道这不是一个好的理由),现在我得到了这个错误。感谢您的帮助。

   void transfer(char *arr1, char *arr2, int length, void (*insert)(List *, void *), void* (*remove)(List *)) {
    List *list = List_create();

    for (int i=0; i < length; i++) {
        (*insert)(list, &arr1[i]);
    }

    for (int i=0; i < length; i++) {
        arr2[i] = &(*remove)(list);
    }
}

头文件

#include <stdlib.h>

typedef struct ListNode {
    struct ListNode *next;
    struct ListNode *prev;
    void *value;
} ListNode;

typedef struct List {
    int count;
    ListNode *first;
    ListNode *last;
} List;

List *List_create(void);

void add_to_back(List *list, void *value);
void *remove_from_back(List *list);

void add_to_front(List *list, void *value);
void *remove_from_front(List *list);

void transfer(void *arr1, void *arr2, int length, void (*insert)(List *, void *), void* (*remove)(List *));

【问题讨论】:

  • 该消息看起来不像来自 C 编译器。如果您使用 C++ 编译器,请更改标签或尝试使用 C 编译器。 C 和 C++ 是不同的语言。
  • void * 是一种占位符类型,当指针可以指向任何类型的对象时使用。由于数组元素的类型未知,因此您无法对其进行索引。像这样的函数需要在调用者中采用来自sizeof (elementType)size 参数。
  • 你的函数指针remove返回void,而不是void *。如果你调用这个函数,传递一个实际返回void *的函数地址作为参数,你应该看到编译器在抱怨。如果您展示了如何调用此函数(以及您传入的地址的函数)会有所帮助
  • 我还没有调用transfer函数
  • 仅仅因为这在过去似乎有效(我知道这不是一个好的理由)不是一个好方法!一定要尝试了解哪里出了问题以及纠正工作的原因!

标签: c arrays pointers


【解决方案1】:

remove 函数的签名是

void remove(List *);

你在这里称呼它:

arr2[i] = &(*remove)(list);

但由于返回值是void,就像

// arr2[i] = &(void);

我认为你的意思是 remove 返回一个指向已删除元素的指针,但签名应该是这样的:

void* remove(List *);

作为函数指针:

void* (*remove)(List *))

【讨论】:

  • 我将签名更新为以下 void transfer(void *arr1, void *arr2, int length, void (*insert)(List *, void *), void* (*remove)(List *)) 但我仍然遇到同样的错误
  • 如何称呼你的transfer 方法? remove 的声明/定义的签名是什么样的?只调整函数参数的签名是不够的。
  • 其实错误信息有点不同error: cannot take the address of an rvalue of type 'void *'。我还没有调用 transfer 但我会发布带有添加和删除功能的头文件
  • 如果我删除 &amp; 我会收到以下错误 error: incomplete type 'void' is not assignable arr2[i] = (*remove)(list);
  • @Daniel Kobe 正如@Barmar 在上面的评论中所说,您也不能通过索引i 访问您的arr1arr2 元素,因为它是一个空指针而不是数组。这也应该发出错误/警告。
猜你喜欢
  • 1970-01-01
  • 2016-05-04
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多