使用链接列表在C中使用Hashtable

时间:2011-05-02 19:34:57

标签: c pointers linked-list hashtable

我是C的新手大约两周,遇到链接列表和哈希表的一些问题。编译器会抛出一些错误:

我试图在源代码中标记这些内容。

  

finddupl.c:在函数'main'中:

     
    

finddupl.c:35:5:警告:从不兼容的指针类型分配

         

finddupl.c:37:3:警告:从不兼容的指针类型传递'ml_lookup'的参数1

  
     

mlist.h:19:9:注意:预期'struct MList *'但参数类型为'struct MList *'

     

mlist.c:在函数'ml_lookup'中:

     
    

mlist.c:63:37:警告:从不兼容的指针类型分配

  
     

mlist.c:在函数'ml_add'中:

     
    

mlist.c:78:9:错误:请求成员'哈希表'不是结构或联合

         

mlist.c:90:12:警告:从不兼容的指针类型分配

  

任何人都可以在这里指导我正确的方向,我已经在这里工作了几个小时

到目前为止不爱C:p

我遗漏了mentry.c和带有main函数的c文件,在我尝试编写哈希表之前,我已经测试了这两个。

Mentry.h

#ifndef _MENTRY_INCLUDED_
#define _MENTRY_INCLUDED_

#include <stdio.h>

typedef struct mentry {
char *surname;
int house_number;
char *postcode;
char *full_address;
} MEntry;

/* me_get returns the next file entry, or NULL if end of file*/
MEntry *me_get(FILE *fd);

/* me_hash computes a hash of the MEntry, mod size */
unsigned long me_hash(MEntry *me, unsigned long size);

/* me_print prints the full address on fd */
void me_print(MEntry *me, FILE *fd);

/* me_compare compares two mail entries, returning <0, 0, >0 if
* me1<me2, me1==me2, me1>me2
*/
int me_compare(MEntry *me1, MEntry *me2);

#endif /* _MENTRY_INCLUDED_ */

mlist.h

#ifndef _MLIST_INCLUDED_
#define _MLIST_INCLUDED_

#include "mentry.h"

typedef struct mlist MList;

extern int ml_verbose;      /* if true, prints diagnostics on stderr */

/* ml_create - created a new mailing list */
struct MList *ml_create(void);

/* ml_add - adds a new MEntry to the list;
 * returns 1 if successful, 0 if error (malloc)
 * returns 1 if it is a duplicate */
int ml_add(MList **ml, MEntry *me);

/* ml_lookup - looks for MEntry in the list, returns matching entry or NULL */
MEntry *ml_lookup(struct MList *ml, MEntry *me);

#endif /* _MLIST_INCLUDED_ */

mlist.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mentry.h"
#include "mlist.h"
#define HASHSIZE 101


struct Mlist_node{
 MEntry *me;
MEntry *next;
int size;
};

struct Mlist_head{
struct Mlist_node *head;
struct Mlist_node *tail;
};

struct MList{
int size;
struct Mlist_head hashtable[HASHSIZE];
};



struct MList *ml_create(void){

struct MList *m;
struct Mlist_head *h;
int i;

if ((m = ( struct MList *)malloc(sizeof(struct MList))) != NULL){
    if ((h = (struct Mlist_head *)malloc(sizeof(struct Mlist_head))) != NULL) { 
        for (i = 0; i < HASHSIZE; i++) {
            h = &(m->hashtable[i]);
            h->head = NULL;
            h->tail = NULL;
        }
        printf("worked");
        return m;
}
}




printf("fail");
return NULL;
}




MEntry *ml_lookup(struct MList *ml, MEntry *me){
struct Mlist_node *mn;
struct Mlist_head *mh;
if ((mn = (struct Mlist_node *)malloc(sizeof(struct Mlist_node))) != NULL) {    
if ((mh = (struct Mlist_head *)malloc(sizeof(struct Mlist_head))) != NULL) {    
    unsigned hashval = me_hash(me,HASHSIZE);
    printf("%d",hashval);
mh=&(ml->hashtable[hashval]);
for (mn = mh->head; mn != NULL; mn = mn->next) //LINE 63 ERROR
    if (me_compare(mn->me, me) == 0)
        return me; /* found */
        }
        }
return NULL;

}

int ml_add(MList **ml, MEntry *me){

unsigned hashval;
struct Mlist_head *mh;
struct Mlist_node *mn;
hashval = me_hash(me,HASHSIZE);
mh = ml->hashtable[hashval];   //LINE 78 ERROR

if ((mn = (struct Mlist_node *)malloc(sizeof(struct Mlist_node))) != NULL){
    mn->me=me;
    if(mh->head==NULL){
        mh->head=mn;
        mh->tail=mn;
        mn->next=NULL;
    }
    else{
        mn = mh->tail;
        mn->next=me;
        mh->tail=me;   /LINE 90 ERROR

    }
    return 1;
}
else{
    printf("failed to allocate memory");
    return 0;
}

/* not found */
}

1 个答案:

答案 0 :(得分:0)

看看你是如何在mlist.h中声明MList的。您使用语法

 typedef struct mlist MList;

这对我来说有点不对劲。您正在声明一种名称MList。请注意,使用上面的声明样式,编译器在引用此结构时期望看到“struct mlist”或只是类型名称的MList。 (这question可能对您有所帮助)。但是稍后您可以按如下方式定义结构MList:

struct MList{
int size;
struct Mlist_head hashtable[HASHSIZE];
};

这使得编译器期望使用“struct MList”来查看引用的内容。但是在你的fwd声明中,你只是说没有结构的普通旧“MList”是可以的。编译器可能会或可能无法理解fwd声明与您的定义之间的这种混淆。它变得更糟,因为一个是结构的标记名称,另一个是结构的规范名称。这种事情让我的狡猾感觉刺痛了一些东西可能会被关闭并导致你和编译器之间产生混淆。

我只想改变你的转发方式,使其与Mlist的使用方式保持一致,看看是否有助于你。要执行此操作,请将以上行更改为:

 struct MList;

(然后在mlist.h中注意你在引用MList时如何不一致地使用struct关键字。有时你会这样做,有时你不这样做。这也可能导致问题混乱你的编译器。如果改为上面的话fwd声明,使用struct MList,而不仅仅是MList)

在其他新闻中,为:

mlist.c:63:37: warning: assignment from incompatible pointer type

您正在为一个不同类型的MNode分配一个MEntry,所以我希望您能收到警告。