0

以下insertSNode函数插入itemreturn更新指针。在insertSnode函数中,来自不同struct的每个数据都被相应地取消引用。

问题:我在(LINE 1)、(LINE 2)、(LINE 3)、(LINE 4) 上收到编译器错误,并显示以下错误消息:

“成员引用基类型 'void' 不是结构或联合。”

问题:

如何摆脱编译器错误?如果我不能,或者,我们是否有更好的解决方案来编写与这种情况相同的函数?假设有太多struct类型(即Type_A、Type_B 等),用不同的类型声明创建不同的函数是极其低效的。

*pListTypeA = (Type_A *) insertSnode(*pListTypeA, pPreTypeA, pTypeAItem, TYPEA);
*pListTypeB = (Type_B *) insertSnode(*pListTypeB, pPreTypeB, pTypeBItem, TYPEB);
*pListTypeC = (Type_C *) insertSnode(*pListTypeC, pPreTypeC, pTypeCItem, TYPEC);
// more assignments

insertSnode定义:

void* insertSnode(void* pList, void* pPre, char* item, const int type) {
    void *pNew;

    if (TYPEA == type) {
        pList = (Type_A*) pList;
        pPre =  (Type_A*) pPre;
        pNew =  (Type_A*) pNew;
    } else if (TYPEB == type) {
        pList = (Type_B*) pList;
        pPre =  (Type_B*) pPre;
        pNew =  (Type_B*) pNew;
    } else (TYPEC == type) {
        pList = (Type_C*) pList;
        pPre =  (Type_C*) pPre;
        pNew =  (Type_C*) pNew;
    }
    if (!(pNew = malloc(sizeof(*pList)))) {
        printf(ERR_NOT_ENOUGH_MEMORY);
        exit(EXIT_NOT_ENOUGH_MEMORY);
    }
    pNew->name = item;    // compiler error: (LINE 1)
    if (pPre == NULL) {
        pNew->link = pList;    // compiler error: (LINE 2)
        pList = pNew;
    } else {
        pNew->link = pPre->link;    // compiler error: (LINE 3)
        pPre->link = pNew;    // compiler error: (LINE 4)
    }
    return pList;
}

笔记:

仅供参考:我能够在没有用于类型声明的 if 语句和只有一种类型(例如 Type_A)的情况下运行此代码。所以,我们都知道除了类型声明之外没有外部问题。

4

3 回答 3

1

这里的问题是下面的行

pList = (TYPE_A*) pList;

仍然分配给一个void*指针,所以强制转换是无用的,其余代码的行为就好像它没有发生一样。

我不知道一个干净的方法来整齐地解决这个问题我很抱歉。我打算建议一个中间体struct,但这不起作用,因为您想直接修改实例。

如果是这样C++,泛型将是答案..

为了使您当前的想法发挥作用,您需要为每种类型创建不同的变量并将其转换为这些变量,或者在每次要使用变量时进行转换。

或者尝试按照 Michael Pryor 的建议将类型统一为一种。

否则,您可以尝试使用宏 - 请参阅下面的示例以了解上述代码中的一行。

#define OPERATEONTYPE(Type,TypeEnum)\
if(type == TypeEnum) {\
    ((Type*)pNew)->name = item;\
}


void* insertSnode(void* pList, void* pPre, char* item, const int type) {
         OPERATEONTYPE(Type_A,TYPEA)
    else OPERATEONTYPE(Type_B,TYPEB)
    else ....
}

#undef OPERATEONTYPE //should only be used/usable within that function anyway
于 2013-02-17T03:07:31.853 回答
1

如果每个“结构类型”都有一些共同的值(名称、下一个、上一个等),那么也许您想使用联合?将公共部分存储在通用结构中,然后使用联合来存储非公共部分。

注意@KarthikT 的回答是正确的,这些确实是语法错误,因为 pNew 始终是一个 void 类型,并且没有与之关联的“结构”,所以 pNew->name 是一个无意义的构造。

于 2013-02-17T03:20:40.970 回答
-2

正如 Karthik 所说,您必须在c++.
在 c 中,有一个解决方案。删除. if...else if...else_ 如下使用它。insertSnode()

void* insertSnode(void* pList, void* pPre, char* item, const int type) {
void *pNew;
 if (!(pNew = malloc(sizeof(*pList)))) {
    printf(ERR_NOT_ENOUGH_MEMORY);
    exit(EXIT_NOT_ENOUGH_MEMORY);
}
if (TYPEA == type) {
   if(pPre==NULL){
   (Type_A*)pNew->name=item;
   (Type_A*)pNew->link=plist;
   (Type_A*)pList=pNew;
 }else{
    (Type_A*)pNew->link=(Type_A*)pPre->link;
     (Type_A*)pPre->link;
  }
} else if (TYPEB == type) {
    if(pPre==NULL){
   (Type_B*)pNew->name=item;
   (Type_B*)pNew->link=plist;
   (Type_B*)pList=pNew;
 }else{
    (Type_B*)pNew->link=(Type_B*)pPre->link;
     (Type_B*)pPre->link;
  }
} else if(TYPEC == type) {
   if(pPre==NULL){
   (Type_C*)pNew->name=item;
   (Type_C*)pNew->link=plist;
   (Type_C*)pList=pNew;
 }else{
    (Type_C*)pNew->link=(Type_c*)pPre->link;
     (Type_C*)pPre->link;
  }
}


return pList;
}
于 2013-02-17T03:29:12.343 回答