我是C语言的新手,大约两周了,遇到了一些链表和哈希表的问题。编译器抛出一些错误:
我已经尝试在源代码中标记这些。
find double .c: In function 'main':
find double .c:35:5:警告:从不兼容的指针类型赋值
finddouble .c:37:3:警告:从不兼容的指针类型传递参数1
MList .h:19:9:注意:期望'struct MList *',但参数类型是'struct MList *'
mlist.c:在函数'ml_lookup':
mlist.c:63:37:警告:从不兼容的指针类型赋值
mlist.c: In function 'ml_add':
mlist.c:78:9:错误:请求成员'hashtable'在非结构或联合的位置
mlist.c:90:12:警告:从不兼容的指针类型赋值
有谁能给我指路吗,我已经花了几个小时了
至今不爱C:p
我省略了main函数的mentry.c和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 */
}
查看如何在MList .h中向前声明MList。使用语法
typedef struct mlist MList;
这看起来有点不对劲。你声明了一个MList类型。注意,使用上述声明风格,编译器期望在引用该结构时看到"struct mlist",或者只是类型名称的mlist。(这个问题可能对你有帮助)。但是,稍后您将定义一个结构体MList,如下所示:
struct MList{
int size;
struct Mlist_head hashtable[HASHSIZE];
};
这使得编译器期望后记看到与"struct MList"相关的内容。但是在你的fwd声明中,你只是说没有结构体的普通旧的"MList"是可以的。编译器可能无法理解fwd声明和定义之间的这种混淆。更糟糕的是,一个是结构体的标签名,另一个是结构体的规范名。这种事情让我的敏感的感觉有些东西可能会关闭,并导致您和编译器之间的混淆。
我只想改变你的转发声明的方式,使其与Mlist的使用方式保持一致,看看这是否对你有帮助。为此,将上面的行更改为:
struct MList;
(然后注意在MList. h中,当引用MList时,如何不一致地使用struct关键字。有时会,有时不会。这也可能导致问题w/混淆您的编译器。如果更改为上述fwd声明,请使用struct MList,而不仅仅是MList)
在其他新闻中,for:
mlist.c:63:37: warning: assignment from incompatible pointer type
你正在分配一个MEntry给一个MNode,这是不同的类型,所以我希望你得到你得到的警告。