2013年12月19日木曜日

開発環境

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

その他参考書籍

17-12(プログラミング実習)、実習17-3.

コード

sample.c

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

struct double_list {
    int data;
    struct double_list *next_ptr;
    struct double_list *previous_ptr;
};

struct double_list *head_ptr = NULL;

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

struct double_list *five_ptr;
void double_enter(int item)
{
    struct double_list *insert_ptr;
    struct double_list *new_ptr;
    if(head_ptr == NULL){
        head_ptr = malloc(sizeof(struct double_list));
        if(head_ptr == NULL){
            memory_error();
        }
        head_ptr->data = item;
        if(item == 5){
            five_ptr = head_ptr;
        }
        head_ptr->next_ptr = NULL;
        head_ptr->previous_ptr = NULL;
        return;
    }
    insert_ptr = head_ptr;
    new_ptr = malloc(sizeof(struct double_list));
    if(new_ptr == NULL){
        memory_error();
    }
    new_ptr->data = item;
    if(item == 5){
        five_ptr = new_ptr;
    }
    while (1){
        /* リストの終わりか終わりの手前に挿入される場合 */
        if(insert_ptr->next_ptr == NULL){
            /* リストの終わりに挿入される場合 */
            if(item > insert_ptr->data){
                new_ptr->next_ptr = NULL;
                new_ptr->previous_ptr = insert_ptr;
                insert_ptr->next_ptr = new_ptr;
                /* リストの終わりの手前がリストの先頭の場合 */
                if(insert_ptr->previous_ptr == NULL){
                    head_ptr = insert_ptr;
                }
                return;
            }
            /* リストの終わりの手前に挿入される場合 */
            new_ptr->next_ptr = insert_ptr;
            new_ptr->previous_ptr = insert_ptr->previous_ptr;
            /* リストの終わりの手前がリストの先頭場合 */
            if(new_ptr->previous_ptr == NULL){
                head_ptr = new_ptr;
                insert_ptr->previous_ptr = new_ptr;
                return;
            }
            insert_ptr->previous_ptr->next_ptr = new_ptr;
            insert_ptr->previous_ptr = new_ptr;
            return;
        }
        if(item <= insert_ptr->data){
            break;
        }
        insert_ptr = insert_ptr->next_ptr;
    }
    new_ptr->next_ptr = insert_ptr;
    new_ptr->previous_ptr = insert_ptr->previous_ptr;
    /* リストの先頭に挿入されるかどうか */
    if (new_ptr->previous_ptr == NULL){
        head_ptr = new_ptr;
    } else {
        insert_ptr->previous_ptr->next_ptr = new_ptr;
    }
    insert_ptr->previous_ptr = new_ptr;
}

void double_remove(int item)
{
    struct double_list *current_ptr;
    current_ptr = head_ptr;
    if(item == 5){
        five_ptr = NULL;
    }
    while(1){
        if(current_ptr == NULL){
            break;
        }
        if(item == current_ptr->data){
            if(current_ptr->previous_ptr != NULL){
                current_ptr->previous_ptr->next_ptr = current_ptr->next_ptr;
            } else {
                head_ptr = current_ptr->next_ptr;
            }
            if(current_ptr->next_ptr != NULL){
                current_ptr->next_ptr->previous_ptr =
                    current_ptr->previous_ptr;
            }
            free(current_ptr);
            break;
        }
        current_ptr = current_ptr->next_ptr;
    }
}

void print_double(struct double_list *current_ptr)
{
    if (current_ptr == NULL){
        printf("\n");
        return;
    }
    printf("%d ", current_ptr->data);
    print_double(current_ptr->next_ptr);
}

int main(int argc, char *argv[])
{
    int nums[] = {9, 0, 8, 1, 7, 2, 6, 3, 5, 4};
    int i;
    for(i = 0; i < 10; i++){
        double_enter(nums[i]);
    }
    printf("最初\n");
    printf("5の次: %d\n", five_ptr->next_ptr->data);
    printf("5の前: %d\n", five_ptr->previous_ptr->data);
    print_double(head_ptr);
    double_remove(0);
    printf("0を削除\n");
    print_double(head_ptr);
    double_remove(9);
    printf("9を削除\n");
    print_double(head_ptr);
    double_remove(5);
    printf("5を削除\n");
    print_double(head_ptr);
    double_remove(10);
    printf("10を削除\n");
    print_double(head_ptr);
    double_remove(1);    
    double_remove(2);    
    double_remove(3);    
    double_remove(4);    
    double_remove(6);    
    double_remove(7);    
    double_remove(8); 
    printf("全て削除\n");
    print_double(head_ptr);
    double_remove(5);
    printf("5を削除\n");
    print_double(head_ptr);
    return (0);
}

makefile

CC=cc
CFLAGS=-g

sample: sample.c
 $(CC) $(CFLAGS) -o sample sample.c

clean:
 rm -f sample

入出力結果(Terminal)

$ ./sample
最初
5の次: 6
5の前: 4
0 1 2 3 4 5 6 7 8 9 
0を削除
1 2 3 4 5 6 7 8 9 
9を削除
1 2 3 4 5 6 7 8 
5を削除
1 2 3 4 6 7 8 
10を削除
1 2 3 4 6 7 8 
全て削除

5を削除

$

0 コメント:

コメントを投稿