忍者ブログ

2024
05
03

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

2024/05/03 (Fri.)

2012
06
24

自己参照型双方向リスト(C言語)

現在ゲーム中のユーザ管理するのにリスト構造使おうとちょっと作ったので置いておく。
自己参照型双方向リストです。

ソースコード

/* nex2t_list.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>

#define RET_SUCCESS        0
#define RET_NO_ENTRY       1
#define RET_NO_MATCH_ENTRY 2

#define RET_NO_EXIST       0
#define RET_EXIST          1

#define DEBUG_LINE         "------------------------------------------\n"

typedef struct client_info {
	pid_t pid;
	char ip[NI_MAXHOST];
	char port[NI_MAXSERV];
} cli_info_t;

typedef struct client_info_node {
	struct client_info_node *next;
	struct client_info_node *prev;
	cli_info_t ent;
} cli_info_node_t;

typedef struct client_info_list {
	struct client_info_node *head;
	struct client_info_node *tail;
} cli_info_list_t;

void test(void);
void create_info(cli_info_t *info, pid_t pid, const char ip[],
                 const char port[]);
void list_init(cli_info_list_t *list);
void list_exit(cli_info_list_t *list);
void list_add(cli_info_list_t *list, const cli_info_t *info);
int list_del_head(cli_info_list_t *list);
int list_del_tail(cli_info_list_t *list);
int list_del_match_pid(cli_info_list_t *list, pid_t pid);
int list_del_match_ip(cli_info_list_t *list, const char ip[]);
int list_del_match_port(cli_info_list_t *list, const char port[]);
int list_del_match(cli_info_list_t *list, const cli_info_t *info);
int is_exist_cli_info_pid(const cli_info_list_t *list, pid_t pid);
int is_exist_cli_info_ip(const cli_info_list_t *list, const char ip[]);
int is_exist_cli_info_port(const cli_info_list_t *list, const char port[]);
int is_exist_cli_info(const cli_info_list_t *list, const cli_info_t *info);
void list_show(const cli_info_list_t *list);
void list_show_match_pid(const cli_info_list_t *list, pid_t pid);
void list_show_match_ip(const cli_info_list_t *list, const char ip[]);
void list_show_match_port(const cli_info_list_t *list, const char port[]);
void list_show_match(const cli_info_list_t *list, const cli_info_t *info);

int main(void)
{
	test();
	return 0;
}

void create_info(cli_info_t *info, pid_t pid, const char ip[],
                 const char port[])
{
	info->pid = pid;
	strcpy(info->ip, ip);
	strcpy(info->port, port);
}

void list_init(cli_info_list_t *list)
{
	list->head = NULL;
	list->tail = NULL;
}

void list_add(cli_info_list_t *list, const cli_info_t *info)
{
	cli_info_node_t *node;
	cli_info_node_t *node_tmp;

	node = (cli_info_node_t *)malloc(sizeof(cli_info_node_t));
	node->ent.pid = info->pid;
	strcpy(node->ent.ip, info->ip);
	strcpy(node->ent.port, info->port);

	if (list->head == NULL) {
		/* first add */
		list->head = node;
		list->tail = node;
		node->prev = NULL;
		node->next = NULL;
	} else {
		node_tmp = list->head;
		while (node_tmp->next != NULL) {
			node_tmp = node_tmp->next;
		}
		node_tmp->next = node;
		node->next = NULL;
		node->prev = node_tmp;
		list->tail = node;
	}
}

int list_del_head(cli_info_list_t *list)
{
	cli_info_node_t *node_next_keep;

	if (list->head == NULL) {
		return RET_NO_ENTRY;
	} else if (list->head->next == NULL) {
		free(list->head);
		list->head = NULL;
		list->tail = NULL;
	} else {
		node_next_keep = list->head->next;
		free(node_next_keep->prev);
		list->head = node_next_keep;
		list->head->prev = NULL;
	}
	return RET_SUCCESS;
}

int list_del_tail(cli_info_list_t *list)
{
	cli_info_node_t *node_prev_keep;

	if (list->tail == NULL) {
		return RET_NO_ENTRY;
	} else if (list->tail->prev == NULL) {
		free(list->tail);
		list->head = NULL;
		list->tail = NULL;
	} else {
		node_prev_keep = list->tail->prev;
		free(list->tail);
		list->tail = node_prev_keep;
		list->tail->next = NULL;
	}
	return RET_SUCCESS;
}

int list_del_match_pid(cli_info_list_t *list, pid_t pid)
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		return RET_NO_ENTRY;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (node->ent.pid == pid) {
			if ((node->prev == NULL) && (node->next == NULL)) {
				list->head = NULL;
				list->tail = NULL;
			} else if (node->prev == NULL) {
				list->head = node->next;
				node->next->prev = NULL;
			} else if (node->next == NULL) {
				list->tail = node->prev;
				node->prev->next = NULL;
			} else {
				node->prev->next = node->next;
				node->next->prev = node->prev;
			}
			free(node);
			return RET_SUCCESS;
		}
		i++;
	} while (node->next != NULL);

	return RET_NO_MATCH_ENTRY;
}

int list_del_match_ip(cli_info_list_t *list, const char ip[])
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		return RET_NO_ENTRY;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (!strcmp(node->ent.ip, ip)) {
			if ((node->prev == NULL) && (node->next == NULL)) {
				list->head = NULL;
				list->tail = NULL;
			} else if (node->prev == NULL) {
				list->head = node->next;
				node->next->prev = NULL;
			} else if (node->next == NULL) {
				list->tail = node->prev;
				node->prev->next = NULL;
			} else {
				node->prev->next = node->next;
				node->next->prev = node->prev;
			}
			free(node);
			return RET_SUCCESS;
		}
		i++;
	} while (node->next != NULL);

	return RET_NO_MATCH_ENTRY;
}

int list_del_match_port(cli_info_list_t *list, const char port[])
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		return RET_NO_ENTRY;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (!strcmp(node->ent.port, port)) {
			if ((node->prev == NULL) && (node->next == NULL)) {
				list->head = NULL;
				list->tail = NULL;
			} else if (node->prev == NULL) {
				list->head = node->next;
				node->next->prev = NULL;
			} else if (node->next == NULL) {
				list->tail = node->prev;
				node->prev->next = NULL;
			} else {
				node->prev->next = node->next;
				node->next->prev = node->prev;
			}
			free(node);
			return RET_SUCCESS;
		}
		i++;
	} while (node->next != NULL);

	return RET_NO_MATCH_ENTRY;
}

int list_del_match(cli_info_list_t *list, const cli_info_t *info)
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		return RET_NO_ENTRY;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if ((node->ent.pid == info->pid)
		    && !strcmp(node->ent.ip, info->ip)
		    && (!strcmp(node->ent.port, info->port))) {
			if ((node->prev == NULL) && (node->next == NULL)) {
				list->head = NULL;
				list->tail = NULL;
			} else if (node->prev == NULL) {
				list->head = node->next;
				node->next->prev = NULL;
			} else if (node->next == NULL) {
				list->tail = node->prev;
				node->prev->next = NULL;
			} else {
				node->prev->next = node->next;
				node->next->prev = node->prev;
			}
			free(node);
			return RET_SUCCESS;
		}
		i++;
	} while (node->next != NULL);

	return RET_NO_MATCH_ENTRY;
}

void list_show(const cli_info_list_t *list)
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		printf("NO ENTRY.\n");
		return;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		printf("[%d] pid:%d, ip:%s, port:%s\n", i++, node->ent.pid,
		       node->ent.ip, node->ent.port);
	} while (node->next != NULL);
}

void list_show_match_pid(const cli_info_list_t *list, pid_t pid)
{
	int i = 1, match_flag = 0;
	cli_info_node_t *node;

	if (list->head == NULL) {
		printf("NO_ENTRY.\n");
		return;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (node->ent.pid == pid) {
			printf("[%d] pid:%d, ip:%s, port:%s\n", i,
			       node->ent.pid, node->ent.ip, node->ent.port);
			match_flag = 1;
		}
		i++;
	} while (node->next != NULL);

	if (!match_flag) {
		printf("NO MATCH ENTRY pid:%d\n", pid);
	}
}

void list_show_match_ip(const cli_info_list_t *list, const char ip[])
{
	int i = 1, match_flag = 0;
	cli_info_node_t *node;

	if (list->head == NULL) {
		printf("NO_ENTRY.\n");
		return;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (!strcmp(node->ent.ip, ip)) {
			printf("[%d] pid:%d, ip:%s, port:%s\n", i,
			       node->ent.pid, node->ent.ip, node->ent.port);
			match_flag = 1;
		}
		i++;
	} while (node->next != NULL);

	if (!match_flag) {
		printf("NO MATCH ENTRY ip:%s\n", ip);
	}
}

void list_show_match_port(const cli_info_list_t *list, const char port[])
{
	int i = 1, match_flag = 0;
	cli_info_node_t *node;

	if (list->head == NULL) {
		printf("NO ENTRY.\n");
		return;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (!strcmp(node->ent.port, port)) {
			printf("[%d] pid:%d, ip:%s, port:%s\n", i,
			       node->ent.pid, node->ent.ip, node->ent.port);
			match_flag = 1;
		}
		i++;
	} while (node->next != NULL);

	if (!match_flag) {
		printf("NO MATCH ENTRY port:%s\n", port);
	}
}

void list_show_match(const cli_info_list_t *list, const cli_info_t *info)
{
	int i = 1, match_flag = 0;
	cli_info_node_t *node;

	if (list->head == NULL) {
		printf("NO ENTRY\n");
		return;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if ((node->ent.pid == info->pid)
		    && !strcmp(node->ent.ip, info->ip)
		    && (!strcmp(node->ent.port, info->port))) {
			printf("[%d] pid:%d, ip:%s, port:%s\n", i,
			       node->ent.pid, node->ent.ip, node->ent.port);
			match_flag = 1;
		}
		i++;
	} while (node->next != NULL);

	if (!match_flag) {
		printf("NO MATCH ENTRY pid:%d, ip:%s, port:%s\n",
		       info->pid, info->ip, info->port);
	}
}

int is_exist_cli_info_pid(const cli_info_list_t *list, pid_t pid)
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		return RET_NO_EXIST;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (node->ent.pid == pid) {
			return RET_EXIST;
		}
		i++;
	} while (node->next != NULL);

	return RET_NO_EXIST;
}

int is_exist_cli_info_ip(const cli_info_list_t *list, const char ip[])
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		return RET_NO_EXIST;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (!strcmp(node->ent.ip, ip)) {
			return RET_EXIST;
		}
		i++;
	} while (node->next != NULL);

	return RET_NO_EXIST;
}

int is_exist_cli_info_port(const cli_info_list_t *list, const char port[])
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		return RET_NO_EXIST;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if (!strcmp(node->ent.port, port)) {
			return RET_EXIST;
		}
		i++;
	} while (node->next != NULL);

	return RET_NO_EXIST;
}

int is_exist_cli_info(const cli_info_list_t *list, const cli_info_t *info)
{
	int i = 1;
	cli_info_node_t *node;

	if (list->head == NULL) {
		return RET_NO_EXIST;
	}
	node = list->head;
	do {
		if (i != 1) {
			node = node->next;
		}
		if ((node->ent.pid == info->pid)
		    && !strcmp(node->ent.ip, info->ip)
		    && (!strcmp(node->ent.port, info->port))) {
			return RET_EXIST;
		}
		i++;
	} while (node->next != NULL);

	return RET_NO_EXIST;
}

void list_exit(cli_info_list_t *list)
{
	cli_info_node_t *node_tmp;
	cli_info_node_t *node_keep;

	if (list->head == NULL) {
		return; /* no entry */
	}
	node_tmp = list->head;
	do {
		node_keep = node_tmp->next;
		free(node_tmp);
		node_tmp = node_keep;
	} while (node_tmp != NULL);
}

void test(void)
{
	cli_info_list_t list;
	cli_info_t info;

	list_init(&list);

	printf("first list state.\n");
	create_info(&info, 1003, "192.168.1.3", "10003");
	list_add(&list, &info);
	create_info(&info, 1004, "192.168.1.4", "10004");
	list_add(&list, &info);
	create_info(&info, 1005, "192.168.1.5", "10005");
	list_add(&list, &info);
	create_info(&info, 1006, "192.168.1.6", "10006");
	list_add(&list, &info);

	printf(DEBUG_LINE);
	list_show(&list);
	printf(DEBUG_LINE "\n");

	printf("list_show_match test\n");
	printf(DEBUG_LINE);
	list_show_match_pid(&list, 1005);
	list_show_match_pid(&list, 1007);
	list_show_match_ip(&list, "192.168.1.10");
	list_show_match_ip(&list, "192.168.1.6");
	list_show_match_port(&list, "10009");
	list_show_match_port(&list, "10003");
	create_info(&info, 1003, "192.168.1.5", "10003");
	list_show_match(&list, &info);
	create_info(&info, 1003, "192.168.1.3", "10003");
	list_show_match(&list, &info);
	printf(DEBUG_LINE "\n");

	printf("is_exist_cli_info test (equal param list_show_match test)\n");
	printf(DEBUG_LINE);
	printf("%d\n", is_exist_cli_info_pid(&list, 1005));
	printf("%d\n", is_exist_cli_info_pid(&list, 1007));
	printf("%d\n", is_exist_cli_info_ip(&list, "192.168.1.10"));
	printf("%d\n", is_exist_cli_info_ip(&list, "192.168.1.6"));
	printf("%d\n", is_exist_cli_info_port(&list, "10009"));
	printf("%d\n", is_exist_cli_info_port(&list, "10003"));
	create_info(&info, 1003, "192.168.1.5", "10003");
	printf("%d\n", is_exist_cli_info(&list, &info));
	create_info(&info, 1003, "192.168.1.3", "10003");
	printf("%d\n", is_exist_cli_info(&list, &info));
	printf(DEBUG_LINE "\n");

	printf("list_add test\n");
	printf(DEBUG_LINE);
	create_info(&info, 2003, "192.168.2.3", "20003");
	list_add(&list, &info);
	create_info(&info, 2004, "192.168.2.4", "20004");
	list_add(&list, &info);
	list_show(&list);
	printf(DEBUG_LINE "\n");

	printf("list_del test\n");
	printf(DEBUG_LINE);
	list_del_head(&list);
	list_del_tail(&list);
	list_show(&list);
	printf(DEBUG_LINE);
	list_del_match_pid(&list, 1003);
	list_del_match_pid(&list, 1004); /* del */
	list_show(&list);
	printf(DEBUG_LINE);
	list_del_match_ip(&list, "192.168.1.5"); /* del */
	list_del_match_ip(&list, "192.168.1.7");
	list_show(&list);
	printf(DEBUG_LINE);
	list_del_match_port(&list, "10006"); /* del */
	list_del_match_port(&list, "10005");
	list_show(&list);
	printf(DEBUG_LINE);
	create_info(&info, 1003, "192.168.1.5", "10003");
	list_del_match(&list, &info);
	create_info(&info, 2003, "192.168.2.3", "20003"); /* del */
	list_del_match(&list, &info);
	list_show(&list);
	printf(DEBUG_LINE);

	list_exit(&list);
}

コンパイル例

gcc -W -Wall -o nex2t_list nex2t_list.c

実行結果

./list
first list state.
------------------------------------------
[1] pid:1003, ip:192.168.1.3, port:10003
[2] pid:1004, ip:192.168.1.4, port:10004
[3] pid:1005, ip:192.168.1.5, port:10005
[4] pid:1006, ip:192.168.1.6, port:10006
------------------------------------------

list_show_match test
------------------------------------------
[3] pid:1005, ip:192.168.1.5, port:10005
NO MATCH ENTRY pid:1007
NO MATCH ENTRY ip:192.168.1.10
[4] pid:1006, ip:192.168.1.6, port:10006
NO MATCH ENTRY port:10009
[1] pid:1003, ip:192.168.1.3, port:10003
NO MATCH ENTRY pid:1003, ip:192.168.1.5, port:10003
[1] pid:1003, ip:192.168.1.3, port:10003
------------------------------------------

is_exist_cli_info test (equal param list_show_match test)
------------------------------------------
1
0
0
1
0
1
0
1
------------------------------------------

list_add test
------------------------------------------
[1] pid:1003, ip:192.168.1.3, port:10003
[2] pid:1004, ip:192.168.1.4, port:10004
[3] pid:1005, ip:192.168.1.5, port:10005
[4] pid:1006, ip:192.168.1.6, port:10006
[5] pid:2003, ip:192.168.2.3, port:20003
[6] pid:2004, ip:192.168.2.4, port:20004
------------------------------------------

list_del test
------------------------------------------
[1] pid:1004, ip:192.168.1.4, port:10004
[2] pid:1005, ip:192.168.1.5, port:10005
[3] pid:1006, ip:192.168.1.6, port:10006
[4] pid:2003, ip:192.168.2.3, port:20003
------------------------------------------
[1] pid:1005, ip:192.168.1.5, port:10005
[2] pid:1006, ip:192.168.1.6, port:10006
[3] pid:2003, ip:192.168.2.3, port:20003
------------------------------------------
[1] pid:1006, ip:192.168.1.6, port:10006
[2] pid:2003, ip:192.168.2.3, port:20003
------------------------------------------
[1] pid:2003, ip:192.168.2.3, port:20003
------------------------------------------
NO ENTRY.
------------------------------------------

検索用タグ C言語 双方向リスト 自己参照型

拍手[0回]

PR

2012/06/24 (Sun.) Comment(0) C言語

Comments

名前
メールアドレス
URL
コメント
PASS  Vodafone絵文字 i-mode絵文字 Ezweb絵文字

ブログ内検索

最新記事

カテゴリー

アーカイブ

フリーエリア





プロフィール

HN:
nex2t
年齢:
8
性別:
男性
誕生日:
2016/01/01
職業:
開発エンジニア(ソフト)
趣味:
ラグビー 犬 将棋 ラーメン サーフィン(ネット)
自己紹介:
入社2年目の組込みエンジニア
好きな言語:C言語
エディタ:emacs
シェル:zsh
ディストリ:Scientific Linux, Ubuntu
略歴
お仕事のほう
2011/3 調布にある大学卒業
2011/4~6月 研修
2011/7~12月? 10GのLANドライバをがんばる
2012/1~2012/4月? VDCPデーモンを作る
2012/5~2012/10月? genlockデーモンを作る
~(現在) 装置テストなど

趣味などのほう
~2012年4月 自由気ままに。仕事の勉強など。歯医者に時間を取られる。
2012年4月~2012年6月 機動力が増す(バイクの免許&バイク(125ccの原付をゲットする)
2012年6月~2012年8月 将棋のネットゲームを作る(引きこもる)((こころざし半ば)
2012年7月~2012年8月 通勤途中にバイクでこけて('自損)、1か月チャリ通の刑になる
2012年9月~現在(2013年3月) DDRばかりする(主にDP)

(↑2013/3/10更新)

DDRのほう
------------------------------------------
・199?年 小学校高学年。
よく遊ぶ友達内でDDRが流行る。
3rdが家にあり、家庭用マットもあったが、ゲーセンでプレイすることは皆無。
(コロコロコミックとガブリチュウを買うと小遣いがなくなるぐらいしかお金がない)
Burtyfly、DAM DARIRAMとかの誰でも聞いたことあるような曲、DEAD END、Paranoia Rebirth、AFRONOVAとかちょっと難しい曲、
BUMBLE BEE、End of the Centuryとかいい感じで印象に残っている。
GRADIUSIC CYBERが当時意味不明で難しいなと思っていた。
ハンドクラップの他にもメトロノームとかついてた気がする。
スコアとかを気にしたことはなかった。
------------------------------------------
・199?年 中学。
4thを中古で購入。半年に1回ぐらいプレイしてた?(手でやるだけ)。
ワンダ・古畑・HERO・ピンクダイナソー・オリオン・DROP OUT(当時とても速かった)とかが印象に残っている。
---------------------------------------------
・200?年 高校。
MAXを中古で買って、たまにやっていた。ゲーセンに1クレだけ踏みに行ったりしてた。
SO DEEP、天ヒー、象さん、ウィッチドクター、トワイライトゾーン、MAX300が印象に残っている。
この頃、MAX300 SPのリズム(ダンダン ダダンダ(ry)が体に染みついた模様笑。
なおMAXは友人に貸したままの模様。
------------------------------------------
・200?年 大学。
数か月に1回、ストレス発散がてら踏んでいた。確かXとかX2だった気がする。
踏むのは決まって8分でけっこう踏んだ気になる、AFRONOVA、天ヒー、象さん。
Aランクとか出せたことがなかった。
---------------------------------------------
・2012年9月 社会人 X3
コミケ準備のため引きこもっていた反動で、外出ばかりする。
ゲーセンで久々にプレイするととても楽しい(画面もきれいでパネルの反応も良い)。
今まで適当にやってきたが、少しシステムとかスコアを気にし始める。
自分のお金ということもあり、ゲーセンで千円単位でお金を使うことが自然になり、
真面目にDDRをするようになる。
------------------------------------------
・2012年12月 X3
SPしかやったことがなかったが、当時よく通ったゲーセンがDPする人が多く、
楽しそうだったので、DPをやり始める、足の裏の皮がむける。
---------------------------------------------
・2013年4月? X3終了。 DDR2013へ
X3はSP足鳳凰、DP足龍で終了。DPは足12以下の好きな曲のみフルコンができるような具合だった。
------------------------------------------
・2013年7月 ついったーで記録をつけるようになる。
8月4日 足10以下の激譜面AA埋め達成。鬼鯖初クリア
8月10日 足11以下の激譜面AA埋め達成。
8月24日 DDR2013 1000クレ行く。
9月8日 足12以下の激譜面AA埋め達成。
10月   (私用でドタバタする。)
11月2日 Skill pointが1000行く。
11月3日 岐阜のDDR大会 DPノンバー部門参加(予選通過ならず)
11月16日 DP足鳳凰。(エレクリDDPフルコン)
11月22日 足13以下の激譜面AA埋め達成。
11月24日 DP足紙さま?。(苺プリンDDPフルコン、鬼鯖810k同時だった)
Double AA Line 14になる。
現在~  足14のAA埋め、足15のA取得、足13の鳥取りを頑張り中。
------------------------------------------
(↑2013/11/28追加)

最新CM

[06/01 履歴書の書き方]

カウンター