TCPL——练习6.5 & 6.6

  这两道习题综合起来是利用散列表写个适用C语言的简单#define处理器,只能处理#define/#undef不带参数的情形,并且#define后面必须带值。不带值其实也就是加多一个处理,分辨#define语句是否已经结束。这里输入代码我用的是TCPL的getch, ungetch,其实本应该直接读入一个C文件,可是这里我偷懒了。读入文件的话处理代码差别也不大。我把代码分为几个模块:

hash.c:散列表相关代码

io.c:输入输出相关代码

main.c:测试

  以下是代码hash.h:保留三个借口给其他模块调用

 
  
#ifndef HASH_H
#define HASH_H

struct nlist;

struct nlist * install( char * name, char * defn);
int undef( char * name);
void print( void );

#endif
散列表实现文件:

hash.c
 
   
#include < stdio.h >
#include
< stdlib.h >
#include
< string .h >

struct nlist {
char * name; /* defined name */
char * defn; /* replaced value */
struct nlist * next; /* next node */
};

#define HASHSIZE 101
static struct nlist * hashtab[HASHSIZE];

void print( void )
{
struct nlist * np;
for ( int i = 0 ; i < HASHSIZE; ++ i) {
if (hashtab[i] != NULL) {
for (np = hashtab[i]; np != NULL; np = np -> next) {
printf(
" name: %-10s defn: %-5s\n " , np -> name, np -> defn);
}
}
}
}

static char * strdup( char * s)
{
char * p;

p
= ( char * )malloc(strlen(s) + 1 );
if (p != NULL) {
strcpy(p, s);
}
return p;
}

static unsigned int hash( char * s)
{
unsigned
int hashval;

for (hashval = 0 ; * s != ' \0 ' ; ++ s) {
hashval
= * s + 31 * hashval;
}
return hashval % HASHSIZE;
}

static 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;
}
}
return NULL;
}

struct nlist * install( char * name, char * defn)
{
struct nlist * np;
unsigned
int hashval;

if ( (np = lookup(name)) == NULL) {
np
= ( struct nlist * )malloc( sizeof ( struct nlist));
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); /* free the prev defn */
}
if ( (np -> defn = strdup(defn)) == NULL) {
return NULL;
}
return np;
}

int undef( char * name)
{
struct nlist * prev, * np;
unsigned
int hashval;

if ( (np = lookup(name)) != NULL) {
hashval
= hash(name);
prev
= hashtab[hashval];
if (prev == np) {
printf(
" only one node\n " );
free(np
-> defn);
free(np
-> name);
free(np);
}
else {
printf(
" more than one node\n " );
for ( ; prev -> next != np; prev = prev -> next)
;
prev
-> next = np -> next;
free(np
-> defn);
free(np
-> name);
free(np);
}
return 0 ;
}

return - 1 ;
}
io.h: 只保留一个借口给main函数调用:

 
  
#ifndef IO_H
#define IO_H

int getword( char * word, int lim);

#endif
io.c : 输入输出实现文件:

io.c
 
   
#include < stdio.h >
#include
< stdlib.h >
#include
< string .h >
#include
< ctype.h >

#define BUFSIZE 100

char buf[BUFSIZE];
int bufp = 0 ;

int getch( void )
{
return bufp > 0 ? buf[ -- bufp] : getchar();
}

void ungetch( int c)
{
if (bufp >= BUFSIZE) {
printf(
" buffer is full.\n " );
}
buf[bufp
++ ] = c;
}

int getword( char * word, int lim)
{
int c;
char * w;

memset(word,
0x00 , lim);
w
= word;

while (isspace(c = getch()) )
;
if (c != EOF) {
* w ++ = c;
}
else {
return c;
}

for ( ; -- lim > 0 ; w ++ ) {
if ( ! isalnum( * w = getch()) ) {
ungetch(
* w);
break ;
}
}
* w = ' \0 ' ;
return word[ 0 ];
}
最后是main.c文件,调试信息我都去掉了。

main.c
 
   
#include < stdio.h >
#include
< stdlib.h >
#include
< string .h >

#include
" io.h "
#include
" hash.h "

typedef
enum _status {
NONE,
GET_NAME,
GET_VALUE,
UNGET_NAME
} Status;

#define MAXSIZE 100
int main( void )
{
struct nlist * np;
Status status
= NONE;
char word[MAXSIZE] = { 0 };
char name[MAXSIZE] = { 0 };
char defn[MAXSIZE] = { 0 };

while (getword(word, MAXSIZE) != EOF) {
if (strcmp(word, " #define " ) == 0 ) {
status
= GET_NAME;
continue ;
}
else if (strcmp(word, " #undef " ) == 0 ) {
status
= UNGET_NAME;
continue ;
}

if (status == GET_NAME) {
memset(name,
0x00 , sizeof (name));
strcpy(name, word);
status
= GET_VALUE;
}
else if (status == GET_VALUE) {
memset(defn,
0x00 , sizeof (defn));
strcpy(defn, word);
status
= NONE;

if ( (np = install(name, defn)) == NULL) {
return - 1 ;
}
}
else if (status == UNGET_NAME) {
undef(word);
}
}
print();

return 0 ;
}
简单测试结果:

代码
 
   
ken@Linux: ~/ TCPL / chap6 / hash$ . / main
#include
< stdio.h >

#define A 100
#define B 200
#define C 300

#undef A
in #undef .
only one node
name: defn:
name: B defn:
200
name: C defn:
300

 

转载于:https://www.cnblogs.com/python_newbie/archive/2010/11/23/1885025.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值