/* 大規模シミュレータを作る時に、私は、動的メモリのリスト構造体を大量に使う。 Linuxカーネルにも、この仕組みがあるらしく、ユーザプログラムでも使う方法が 解説されていた。 http://qiita.com/chromabox/items/ea9720422d7a974f6ce c言語でリストを使う時に、役に立ちそうだったので、自分のコメントを付けた ものを写させて頂いている。 なお、"list.h"は、kobore.net/list.h.htmlに置いてあり。 */ /* gcc -g list_demo.c -o list_demo */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" typedef struct _tag_datas { int number; char name[64]; list_head _list; }type_line; const char *ndata[]= { "beagle", "cupcake", "donut", "eclair", "froyo", "gingerbread", "honeycomb", "icecleam", "jellybean", "kitkat", NULL, }; // 渡されたリストのエントリが最後かどうか調べる #define list_is_entry_last(pos, head, member) \ &pos->member == (head) int main(int argc,char *argv[]) { LIST_HEAD(mylist); // mylist は リスト変数の宣言と初期化 int nums=1,i; type_line *data = NULL; type_line *dend = NULL; // Listへ要素の追加 for(i=0;ndata[i] != NULL;i++){ data = (type_line *)malloc(sizeof(type_line)); // インスタンスを生成 INIT_LIST_HEAD(&data->_list); // 先頭アドレスを指定(というか「決める」) data->number = nums; // 構造体にデータを投入 strcpy(data->name,ndata[i]); // 同上 nums++; list_add_tail(&data->_list, &mylist); // リスト末尾に追加、リスト先頭に追加する場合はlist_add()を使う } // Listを順にたぐる list_for_each_entry(data,&mylist,_list){ // "_list"は構造体の一つ、mylistは先頭のアドレス printf("%d: %s\n",data->number,data->name); } // Listを順にたぐりつつ、探す (基本的には上記と同じ) list_for_each_entry(data,&mylist,_list){ if(strcmp(data->name,ndata[4]) == 0){ // ndata[4]と同じ文字列なら、引き出す printf("found ! %d: %s\n",data->number,data->name); break; } } // Listが最後まで来たかどうか if(list_is_entry_last(data,&mylist,_list)){ printf("not found\n"); }else{ printf("continue print\n"); // 探せたらそこから順にたどる // list_for_each_entry_continue だと今dataが示しているところの次から // list_for_each_entry_from だと今dataが示しているところになります list_for_each_entry_continue(data,&mylist,_list){ printf("%d: %s\n",data->number,data->name); } } // 後始末 list_for_each_entry_safe(data,dend,&mylist,_list){ list_del(&data->_list); free((void *)data); } return 0; }