�ɤ����ʤ顢�⤦�����٤��������褦�˽񤤤Ƥߤ���

�Ϥ��٤ˤä�# - C�����tail�äݤ���Τ��
�ޤ��������زʤ�C����Υƥ��Ȥ����롥C����ʤ����ʤޤä����Ȥ�ʤ��������顤�פ��Ф��ͤС��Ƥ��Ȥǡ�10�Ը�����tail��񤤤Ƥߤ����ʲ��Υ�������

�ޤ��ϡ�main()�������顣��ȯ�������ǤϷݤ�̵���Τǡ��Կ��⥪�ץ����Ȥ��ƻ���Ǥ���褦�ˤ��Ƥߤ���

tail.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CHARS_IN_LINE 1024
#include "queue.h"

char *new_string(const char *str){
    char *new = (char *)malloc(strlen(str)+1);
    if (new == NULL) DIE_OUT_OF_MEMORY;
    strcpy(new, str); /* it's okay not to use strncpy */
    return new;
}

void usage(const char *str){
    fprintf(stderr, "usage: %s [-n] inputfile\n", str);
    exit(2);
}

int print_atom(void *str){
    return printf("%s", (char *)str);
}

int main(int argc, char **argv){
    char buf[MAX_CHARS_IN_LINE];
    int nline = 10;
    queue *q;
    FILE *fp;

    if (argc < 2) usage(argv[0]);
    if (argv[1][0] == '-'){
        nline = atoi(argv[1]+1);
        if (!nline) usage(argv[0]);
    }
    if ((fp = fopen(argv[argc-1],"r")) == NULL){
        fprintf(stderr, "%s : %s\n", argv[argc-1], strerror(2));
        exit(2);
    }
    q = new_queue(nline);
    while (fgets(buf, MAX_CHARS_IN_LINE, fp)) {
        enqueue(q, new_string(buf));
    }
    traverse_queue(q, print_atom);
    del_queue(q);
    exit(0);
}

���Ƥ��̤ꡢ

  • ������ü���ʤ顢����̤˼��ޤ��礭���ˡ�
  • -Wall��Ĥ���compile���Ƥ������warning���Фʤ��褦�����ä���cast��
  • queue�δؤ��ؿ�����ϡ�queue.h�������ɤ��Ф��Ƥ��롣
  • traverse_queue()�����ܡ�C�Ǥ����ؿ����äݤ�����ʤ���ʤ��Ȥ�����Ȥ��ơ���äȤ�C�ˤ�lambda�Ϥʤ��Τ����ɡ�

����ǡ�queue.h�ϰʲ��ΤȤ��ꡣ

queue.h
#define DIE_OUT_OF_MEMORY { fprintf(stderr, "Out of memory!\n"); exit(-1); }

struct list {
    void *car, *cdr;
};
typedef struct list list;

struct queue{
    int size, max;
    list *head, *tail;
};
typedef struct queue queue;

list *new_list(void *atom){
    list *new = (list *)malloc(sizeof(list));
    if (new == NULL) DIE_OUT_OF_MEMORY;
    new->car = atom;
    new->cdr = NULL;
    new->head = new->tail = NULL; /* shiro-san, thanx */
    return new;
}

void del_list(list *l){
    if (l == NULL) return;
    if (l->car) free(l->car);
    free(l);
}

queue *new_queue(int max){
    queue *new = (queue *)malloc(sizeof(queue));
    if (new == NULL) DIE_OUT_OF_MEMORY;
    new->max  = max;
    new->size = 0;
    return new;
}

list *dequeue(queue *q){
    list *head = q->head;
    if (head) {
        q->head = q->head->cdr;
        q->size--;
    }
    return head;
}

int enqueue(queue *q, void *atom){
    list *l = new_list(atom);
    if (q->size == q->max) del_list(dequeue(q));
    if (q->size == 0) {
        q->head = q->tail = l;
        q->head->cdr = q->tail;
    }else{
        q->tail->cdr = l;
        q->tail = l;
    }
    q->size++;
    return q->size;
}

void del_queue(queue *q){
    list *l;
    if (q == NULL) return;
    while((l = dequeue(q)) != NULL){ 
        del_list(l); 
    }
    free(q);
}

void traverse_queue(queue *q, int (*callback)(void *)){
    list *l;
    for (l = q->head; l; l = l->cdr) callback(l->car);
}
  • car,cdr�Ȥ����Τϼ�̣:)
  • void *�ʤΤǡ��٤�������������ʤ�tail�ʳ��ˤ�Ȥ����������
  • ��������car��list��֤鲼���뤳�ȤϹ�θ���Ƥ��ʤ������������Ǥ�queue������Ǥ���Ф褤�ΤǤ������٤Ǥ�����������
  • queue�ˤޤĤ�����ϰ��̤�����Τǡ��Ȥ����Ϲ�¤�òµ¤¤Ë¤ï¿½ï¿½ï¿½É¬ï¿½×¤ï¿½ï¿½ï¿½ï¿½Þ¤ï¿½Ê¤ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Æ¸ï¿½ï¿½ï¿½ï¿½Ð¡ï¿½enqueue�����element��ɬ��malloc()���줿��ΤǤ���Ȥ������Ȥ���
  • traverse_queue()��callback()��void�Ǥ�褫�ä����ʡ�

���ʤߤˡ��֤դĤ���Haskell�ܡפ�tail�ϡ����꡼ϲ�񷿡��������٤��Ȥޤ�Haskell�Τ����פϤ��ޤ�ʤ��ơ�Perl�Ǥ�

perl -e 'print reverse((reverse <>)[0..9])'

�ǽ���Ƥ��ޤ���

Dan the Occasional C Programmer