Hashtable в C, используя связанные списки - PullRequest
2 голосов
/ 02 мая 2011

Я новичок в C около двух недель, столкнувшись с несколькими проблемами со связанными списками и хэш-таблицами.Компилятор выдает несколько ошибок:

Я пытался пометить их в исходном коде.

finddupl.c: в функции 'main':

finddupl.c: 35: 5: предупреждение: назначение из несовместимого типа указателя

finddupl.c: 37: 3: предупреждение: передача аргумента 1 'ml_lookup' из несовместимого типа указателя

mlist.h: 19: 9: примечание: ожидается «struct MList *», но аргумент имеет тип «struct MList *»

mlist.c: в функции «ml_lookup»:

mlist.c: 63: 37: предупреждение: назначение из несовместимого типа указателя

mlist.c: в функции 'ml_add':

mlist.c: 78: 9: ошибка: запрос элемента 'hashtable' в чем-то, не являющемся структурой или объединением

mlist.c: 90: 12: предупреждение: назначение из несовместимого типа указателя

Может ли кто-нибудь направить меня в правильном направлении, я был здесь несколько часов

Пока не люблю C: p

Я не учелmentry.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 голосов
/ 03 мая 2011

Посмотрите, как вы можете объявить MList в mlist.h.Вы используете синтаксис

 typedef struct mlist MList;

Это мне немного не по вкусу.Вы объявляете тип имени MList.Обратите внимание, что при описанном выше стиле объявления компилятор ожидает увидеть "struct mlist" или просто MList имени типа при обращении к этой структуре.(Этот вопрос может быть вам полезен).Однако позже вы определили struct MList следующим образом:

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

, что заставляет компилятор ожидать послесловия, чтобы видеть вещи, на которые ссылается "struct MList".Но в вашей декларации fwd вы только что сказали, что старый добрый MList без структуры в порядке.Компилятор может или не может иметь смысл в этой путанице между объявлением fwd и вашим определением.Хуже всего то, что один - это имя тега структуры, а другой - каноническое имя структуры.Подобные вещи заставляют меня чувствовать, что что-то может быть отключено, и это может привести к путанице между вами и компилятором.

Я бы просто изменил то, как вы будете объявлять, чтобы соответствовать тому, как используется Mlist, и посмотреть, поможет ли это.вы.Для этого измените вышеприведенную строку на:

 struct MList;

(затем обратите внимание на mlist.h, как вы непоследовательно используете ключевое слово struct при обращении к MList. Иногда вы делаете, а иногда нет. Это также можетбыть причиной проблем с запутыванием вашего компилятора. Если вы перейдете к описанному выше объявлению fwd, используйте struct MList, а не просто MList)

В других новостях, для:

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

Выназначение MEntry MNode, которые бывают разных типов, поэтому я ожидаю, что вы получите предупреждение, которое вы получаете.

...