1

所以我从一个例子中提取了我的问题的一部分代码,但它没有按我的预期工作。第一个模块是我第一次尝试使用该函数的地方,第二个是函数的定义,在第三个模块中是标题中的函数(相应的代码在它的位置),第 4 个模块是我对这些函数的一些解释。谁能帮我理解有什么问题?

第一个模块问题:这一行有多个标记

  • 从不兼容的指针类型传递“create”的参数 1 [默认启用]
  • 从不兼容的指针类型传递“create”的参数 3 [默认启用]
  • 从不兼容的指针类型传递“create”的参数 2 [默认启用]

repo->TList = create(cmpTrans, cpyT, delT);

第二模块

Vector* create(CmpFun cmp, CpyFun cpy, DelFun del)
{
    Vector* v = (Vector*)malloc(sizeof(Vector));
    v->len = 0;
    v->capacity = 10;
    v->elems = (TElem)malloc(10*sizeof(TElem));
    v->cmp = cmp;
    v->del = del;
    v->cpy = cpy;
    return v;
}

第三模块

transaction* cpyT(transaction* t);
void delT(transaction* t);
int cmpTrans(transaction* s1, transaction* s2);
    /*
     * Creates a copy of a transaction
     * Input: t - pointer to transaction
     * Output:  t' - a copy of transaction t
     *          t'->day = t->day; s'->type = t->type; t'->desc = t->desc; t'->amount = t->amount;
     *          * Deallocates the memory pointed to by the given instance
     * Deallocates the memory pointed to by the given instance
     * Input: t - pointer to transaction
     * Output: memory pointed to by t is deallocated
     * Input: s1, s2 - pointers to transaction
     * Output:  1 - if all the attributes of the 2 transactions coincide
     *          0 - otherwise
     */

模块四:

 typedef void* TElem;
/*
 * Pointer to a comparison function for two generic elements
 */
typedef int (*CmpFun)(TElem, TElem);

/*
 * Pointer to a function that clones (copies) a generic element
 */
typedef TElem (*CpyFun)(TElem);

/*
 * Pointer to a function that deletes (deallocates) a generic element
 */
typedef void (*DelFun)(TElem);
4

1 回答 1

1

您的函数指针 typedefs 所有接受/返回TElem类型,这意味着void *. 您正在声明接受/返回transaction *类型的函数。这使得您从这些函数中创建的函数指针与您创建的 typedef 不兼容:

      transaction *(*)(transaction *) != TElem (*)(TElem)
int (*)(transaction *, transaction *) != int (*)(TElem, TElem)
              void (*)(transaction *) != void (*)(TElem)

您可能会感到困惑,因为在 C 中,void *与其他指针类型之间的转换是隐式的。但是,函数指针类型之间的转换(其中一种带void *参数,另一种不带参数)不是。

要修复它,您需要重写cpyT, delT, 并cmpTrans使用匹配的签名:

TElem cpyT(TElem t);
void delT(TElem t);
int cmpTrans(TElem s1, TElem s2);

或者,您可以在调用时通过类型转换来强制执行create

repo->TList = create((CmpFun)cmpTrans, (CpyFun)cpyT, (DelFun)delT);
于 2013-04-07T21:30:17.840 回答