2013年12月24日火曜日

開発環境

C実践プログラミング 第3版 (Steve Oualline (著)、 望月 康司 (監訳) (翻訳)、谷口 功 (翻訳)、オライリー・ジャパン)のⅢ部(高度なプログラミング概念)の18章(モジュールプログラミング)、18-14(プログラミング実習)、実習18-3.を解いてみる。

その他参考書籍

18-14(プログラミング実習)、実習18-3.

コード

symbol_table.h

extern struct node *symbol_table;
extern void enter(char *name);
extern int lookup(char *name);
extern void delete(char *name);
extern void print_symbol_table();

コード

symbol_table.c

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

struct node{
    struct node *left;
    struct node *right;
    char *word;
};

struct node *symbol_table = NULL;

static void memory_error(void)
{
    fprintf(stderr, "Error:Out of memory\n");
    exit (8);
}

static char *save_string(char *string)
{
    char *new_string;

    new_string = malloc((unsigned) (strlen(string) + 1));
    if(new_string == NULL){
        memory_error();
    }
    strcpy(new_string, string);
    return (new_string);
}

static void _enter(struct node **node, char *word)
{
    int result;
    char *save_string(char *);
    if((*node) == NULL){
        (*node) = malloc(sizeof(struct node));
        if((*node) == NULL){
            memory_error();
        }
        (*node)->left = NULL;
        (*node)->right = NULL;
        (*node)->word = save_string(word);
        return;
    }
    result = strcmp((*node)->word, word);
    if(result == 0){
        return;
    }
    if(result < 0){
        _enter(&(*node)->right, word);
    } else {
        _enter(&(*node)->left, word);
    }
}

void enter(char *word)
{
    _enter(&symbol_table, word);
}

static int _lookup(struct node **node, char *word)
{
    int result;
    if((*node) == NULL){
        return 0;
    }
    result = strcmp((*node)->word, word);
    if(result == 0){
        return 1;
    }
    if(result < 0){
        return _lookup(&(*node)->right, word);
    }
    return _lookup(&(*node)->left, word);
}

int lookup(char *word)
{
    return _lookup(&symbol_table, word);
}

static struct node *find_min(struct node **node)
{
    if((*node) == NULL){
        fprintf(stderr, "Error: find_min\n");
        exit (8);
    }
    if(((*node)->left) == NULL){
        return (*node);
    }
    return find_min(&(*node)->left);
}

static void _delete(struct node **node, char *word){
    int result;
    struct node *min;
    if((*node) == NULL){
        return;
    }
    result = strcmp((*node)->word, word);
    if(result == 0){
        if((*node)->right == NULL && (*node)->left == NULL){
            (*node) = NULL;
            return;
        }
        if((*node)->right == NULL){
            (*node) = (*node)->left;
            return;
        }
        min = find_min(&(*node)->right);
        _delete(&(*node)->right, min->word);
        min->left = (*node)->left;
        min->right = (*node)->right;
        (*node) = min;
        return;
    }
    if(result < 0){
        _delete(&(*node)->right, word);
    } else {
        _delete(&(*node)->left, word);
    }
}

void delete(char *word)
{
    _delete(&symbol_table, word);
}

static void _print_tree(struct node *top)
{
    if(top == NULL){
        return;
    }
    _print_tree(top->left);
    printf("%s\n", top->word);
    _print_tree(top->right);
}

void print_symbol_table()
{
    _print_tree(symbol_table);
}

コード

sample.c

#include "symbol_table.h"
#include <stdio.h>

int main(int argc, char *argv[])
{
    char *names[] = {"int", "float", "char", "struct", "void"};
    char *search_names[] = {"int", "double"};
    int size = 5;
    int size_search = 2;
    int i;
    
    print_symbol_table();
    for(i = 0; i < size; i++){
        printf("%sをシンボルテーブルに追加\n", names[i]);
        enter(names[i]);
        print_symbol_table();
    }
    for(i = 0; i < size_search; i++){
        printf("「%s」がシンボルテーブルにあるか調べる\n", search_names[i]);
        if(lookup(search_names[i])){
            printf("見つかった\n");
        } else {
            printf("見つからなかった\n");
        }
    }
    
    for(i = 0; i < size; i++){
        printf("%sをシンボルテーブルから削除\n", names[i]);
        delete(names[i]);
        print_symbol_table();
    }
    return (0);
}

Makefile

CC=cc
CFLAGS=-g
OBJS=sample.o symbol_table.o

all: sample

sample: $(OBJS)
 $(CC) $(CFLAGS) -o sample $(OBJS)

sample.o: symbol_table.h sample.c

symbol_table.o: symbol_table.c

clean:
 rm -f sample sample.o symbol_table.o

入出力結果(Terminal)

$ make
cc -g   -c -o sample.o sample.c
cc -g   -c -o symbol_table.o symbol_table.c
cc -g -o sample sample.o symbol_table.o
$ ./sample
intをシンボルテーブルに追加
int
floatをシンボルテーブルに追加
float
int
charをシンボルテーブルに追加
char
float
int
structをシンボルテーブルに追加
char
float
int
struct
voidをシンボルテーブルに追加
char
float
int
struct
void
「int」がシンボルテーブルにあるか調べる
見つかった
「double」がシンボルテーブルにあるか調べる
見つからなかった
intをシンボルテーブルから削除
char
float
struct
void
floatをシンボルテーブルから削除
char
struct
void
charをシンボルテーブルから削除
struct
void
structをシンボルテーブルから削除
void
voidをシンボルテーブルから削除
$

0 コメント:

コメントを投稿