線形リスト

テキストを見ながら線形リストを作ってみた。Dataは図形の円を意識してるけど、まあ何でも一緒。何だか混乱しそうになったので、あらかじめ図を描いたけど、大事なのは図よりも命名法の統一とか、どういうときに値渡しにするのか参照渡しにするのかの基準をはっきり決めておくこと、という気がする。

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

// Data structure definition

typedef struct {
  int x;
  int y;
  int size;
} Data;

typedef struct __node {
  Data data;
  struct __node *next;
} Node;

typedef struct {
  Node *head;
  Node *cursor;
} List;

// list operations

void InitList(List *list) {
  list->head = NULL;
  list->cursor = NULL;
}

Node *AllocNode(void) {
  return malloc(sizeof(Node));
}

void SetNode(Node *node, Data *data, Node *next) {
  node->data = *data;
  node->next = next;
}

void InsertHead(List *list, Data *data) {
  Node *node = list->head;
  list->head = list->cursor = AllocNode();
  SetNode(list->head, data, node);
}

void AppendTail(List *list, Data *data) {
  if (list->head == NULL)
    InsertHead(list, data);
  else {
    Node *node = list->head;
    while (node->next != NULL)
      node = node->next;
    node->next = list->cursor = AllocNode();
    SetNode(node->next, data, NULL);
  }
}

// Print the list given

void PrintData(Data data) {
  printf("x, y: %d, %d\n", data.x, data.y);
  printf("size: %d\n", data.size);
}

void PrintList(List *list) {
  if (list->head == NULL)
    puts("The list is empty");
  else {
    Node *node = list->head;
    while (node != NULL) {
      PrintData(node->data);
      node = node->next;
    }
  }
}

// ------------------------------

int main(void) {
  List list;
  Data data;
  InitList(&list);

  data.x = 320; data.y = 240; data.size = 100;

  InsertHead(&list, &data);
  data.x += 10; data.y += 10;
  InsertHead(&list, &data);
  data.x += 10; data.y += 10;
  AppendTail(&list, &data);

  PrintList(&list);
}
$ gcc list.c; ./a.out 
x, y: 330, 250
size: 100
x, y: 320, 240
size: 100
x, y: 340, 260
size: 100

やってみると、ほんとに基本的なところでつまるもので、構造体への代入で、

data = {320, 240, 100};

とやって怒られたりした。こういう一括代入ができるのは、宣言時と、変数間での値のコピーのときだけらしい。

あと、PrintDataというメソッド的なものが、Data構造体に含まれていないってことあたりも気になった。いっそ、関数へのポインタをDataに突っ込むとかありなのかしら。