一个表查找程序
宏处理器或编译器的符号表管理主要代码,采用的结构是一个hash表,hash表的每一项是一个链表。
例如#define IN 1,在程序编译的时候,需要把名字IN和替换文本1存入到某个表中。此后,当名字IN出现在某些语句中时,如int state=IN,就必须要用1来替换IN。
选择哈希表,检索速度快(O(1)+O(n))
代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 101 //宏处理器或编译器的符号表管理主要代码 struct nlist { struct nlist* next; char* name; char* defn; }; static struct nlist* hashtab[HASHSIZE]; //把s复制到堆内存中 char* my_strdup(char* s){ char* p; p=(char*)malloc(strlen(s)+1); if(p!=NULL){ strcpy(p,s); } return p; } //取得hashval(下标),一个字符串s对应一个hash表中的下标 unsigned int hash(char* s){ unsigned hashval; for (hashval=0;*s!='\0'; ++s) { hashval=*s+hashval*31; } return hashval%HASHSIZE; } //根据s,找到hashval,再根据它找到在哈希表中对应一个链表(因为其它字符串也可能和s有一样的hashval),然后遍历链表,看看有没有和s相等的字符串 struct nlist* lookup(char* s){ struct nlist* np; for (np=hashtab[hash(s)];np!=NULL;np=np->next) { if(strcmp(np->name,s)==0) return np;//找到s } return NULL; } //将name和defn添加到哈希表中 struct nlist* install(char* name,char* defn){ struct nlist* np; unsigned hashval; np=lookup(name); if(np==NULL){ np=(struct nlist*)malloc(sizeof(*np)); if(np==NULL||(np->name=my_strdup(name))==NULL) return NULL; hashval=hash(name); np->next=hashtab[hashval]; hashtab[hashval]=np; } else{ free((void*)np->defn); } if((np->defn=my_strdup(defn))==NULL) return NULL; return np; } int main(){ install("IN","1"); install("INsQ","2"); install("IzN","3"); install("IsadN","4"); //打印哈希表的所有项 for (int i = 0; i < HASHSIZE; ++i) { struct nlist* np=hashtab[i]; if(np!=NULL){ for (np;np!=NULL;np=np->next) printf("HASHVAL=%d==>%s:%s",hash(np->name),np->name,np->defn); printf("\n"); } } }