Discuss the structure in depth by using a table lookup program.
When you encounter a macro definition #define in 1 o'clock, what does the macro processor and the compiler do with it? You need to deposit the name in and replace text 1 in a table, when appearing in as "Statet = in";
You must replace in with a.
1 processing the name requires that the name and replacement text be stored in the table. Use function Install (S,T) to implement. After the encounter, use the lookup (s) function to find in the table, if found, return to point to the pointer, if not found, return null.
Algorithm: Hash Lookup method (converts the input name to a small nonnegative integer that is then used as the subscript for an array of pointers.) Each element of each array points to the header of a linked list, and each block in the list is used to describe a list of
The name of the hash value. If no name hashes to this value, the value of the array element is null.
Each block in the list is a structure that contains a pointer to the name, a pointer to the replacement text, and a pointer to the subsequent block of the list, if the subsequent block is empty, that is, the list ends.
Block structure is as follows
struct nlist{/* Table entry: * *
struct Nlist *next; /*next entry in Chain *
Char *name; /*defined Name * *
Char *defn; /* Replacement Text * *
};
The pointer array is defined as follows:
#define HASHSIZE 101
static struct nlist *hashtab[hashsize]; /*pointer table*/
Both the lookup and install functions use a hash, which is computed by a for loop, each loop, the last loop evaluates to the result transformed (multiplied by 31) and the new value is added to the value of the current character of the string (*s + 31 *
Hashval), then performs a modulo operation (that is, the remainder) of the result value with the length of the array, resulting in the return value of the function. This hash function is not optimal, but is short and valid.
/*hash:from hash value for string s*/
unsigned hash (char *s)
{
unsigned hashval;
for (hashval = 0; *s!= '; s++)
Hashval = *s + * HASHVAL;
return hashval% Hashsize;
}
The hash process produces a starting subscript that performs a lookup in an array hastab. If a string can be found, it must be in a block of the linked list that the starting subscript points to. The lookup procedure is implemented by the lookup function, if you find
Returns a pointer to the table entry, otherwise null null.
/*lookup:look for S in hashtab*/
struct Nlist *lookup (char *s)
{
struct Nlist *np;
for (NP = Hashtab[hash (s)]; NP!= NULL; NP = Np->next)
if (strcmp (s, np->name) = = 0)
return NP; * * Find * *
return NULL; * * Not Found * *
}
for (ptr = head;ptr!= NULL; ptr = ptr-> next) is the standard way to traverse a list.
The install function uses the lookup function to determine whether the name to be added exists, ditto, to replace it with a new definition, without creating a new table entry, or null if there is insufficient space.
struct Nlist *lookup (char *);
Char *strdup (char *);
/*install:p ut (name, defn) in Hashtab *.
struct Nlist *install (char *name,char *defn)
{
struct Nlist *np;
unsigned hashval;
if (NP =lookup (name) = = NULL) {/* not found/*
NP = (struct nlist *) malloc (Size (* np));
if (NP = NULL | | (Np->name = strdup (name)) = = NULL)
return NULL;
Hashval = hash (name);
Np->next = Hashtab[hashval];
Hashtab[hashval] = NP;
} else
Free ((void *) np->defn);
if ((Np->defn = StrDup (defn)) = = NULL;
return NULL;
return NP;
}