Cで簡易Vector

CでVectorが使えないならそっれっぽいのを作ればいいというわけで、
昨晩チョコっとCで擬似的に作ったCVectorをメモメモ
戻り値とかコメントとかエラー処理が無かったり、 いろいろと中途半端だけど一応動きます。

Templateが使えないので、いちいちキャストが必要なことと、
複数vectorを管理したい時に、いちいちパラメータをセットしないといけないのが微妙です。。
たぶん良い解決方法があるんだと思うけど思いつかない!

main.c

#include "cvector.h"
#include <stdio.h>

int main()
{
	/*■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
		サンプルプログラム
	■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ */

	/* ダミーデータ */
	PHONE_LIST ts1;
	PHONE_LIST ts2;

	/* 実体 */
	C_VECTOR ldata;

	memcpy(ts1.data.name, "bbbbb", sizeof("bbbbb"));
	memcpy(ts2.data.name, "aaaaa", sizeof("aaaaa"));

	/* C_VECTORのparameteセットと、開始 */
	CVECTOR_PARAMETER_SET(&ldata);
	CVECTOR_START(&ldata, sizeof(PHONE_LIST));

	int size;
	PHONE_LIST *tmp;

	/* push_back */
	ldata.push_back(&ts1);
	size = ldata.size();
	printf("%d\n", size);

	ldata.push_back(&ts2);
	size = ldata.size();
	printf("%d\n", size);

	/* at */
	tmp = (PHONE_LIST*)ldata.at(0);
	printf("%s\n", tmp->data.name);

	/* swap */
	ldata.swap(0, 1);
	tmp = (PHONE_LIST*)ldata.at(0);
	printf("%s\n", tmp->data.name);

	/* erase */
	ldata.erase(0);
	tmp = (PHONE_LIST*)ldata.at(0);
	printf("%s\n", tmp->data.name);

	/* insert */
	ldata.insert(&ts1, 0);
	tmp = (PHONE_LIST*)ldata.at(0);
	printf("%s\n", tmp->data.name);

	/* clear */
	ldata.clear();
	size = ldata.size();
	printf("%d\n", size);


	/* C_VECTORの開放 */
	CVECTOR_END();

	return 0;
}

cvector.h

#ifndef __CVECTOR_H__
#define __CVECTOR_H__

/* 変数命令規則 */
#ifndef __VARIABLE_RULE__
#define __VARIABLE_RULE__
typedef unsigned int ui;
typedef unsigned char u1;
typedef unsigned short u2;
typedef unsigned long int u4;
typedef unsigned long long int u8;
typedef signed int si;
typedef signed char s1;
typedef signed short s2;
typedef signed long int s4;
typedef signed long long int s8;
#endif

#ifndef __CPRINT__
#define __CPRINT__
#include <stdio.h>
#define _PL(str) printf(str)
#endif

#ifndef __CFOR__
#define __CFOR__
#define FOR(i, j) for(i = 0; ((i) < (j)); ((i)++))
#endif

/* リスト管理構造体 */
typedef struct VECLIST
{
	struct VECLIST* next;				/* 前要素	*/
	struct VECLIST* prev;				/* 次要素	*/
	void* address;						/* アドレス */

}VECLIST;

typedef struct CVECTOR_PARAMETER
{
	VECLIST* pri_head;				/* 先頭要素				*/
	VECLIST* pri_tail;				/* 最終要素				*/
	si pri_Elementcnt;				/* 要素数				*/
	si pri_ElementSize;				/* 要素サイズ			*/
	si pri_EraseFlag;				/* _Erase関数が呼ばれると1	*/

	VECLIST* Search_tmp;
	VECLIST* Search_tmp_next;
	si LastSearchNo;
	si search_firstflag;

}CVECTOR_PARAMETER;


typedef struct _C_VECTOR
{
	/* 個々のリストを管理するためのparameter */
	CVECTOR_PARAMETER parameter;

	void* (*at)(int _Dst);
	int (*insert)(void *_Src, int _Dst);
	int (*push_back)(void *_Src);
	int (*size)();
	int (*swap)(int _target1, int _target2);
	int (*erase)(int _Dst);
	int (*clear)();

}C_VECTOR;

/* プロトタイプ宣言 */
int CVECTOR_START(C_VECTOR *_Ldata, int Size);
int CVECTOR_END();
void CVECTOR_PARAMETER_SET(C_VECTOR* _Src);


#endif
&#91;/c&#93;

cvector.c
&#91;c&#93;
#include "cvector.h"
#include <stdlib.h>
#include <string.h>


/* 静的プロトタイプ宣言 */
static VECLIST* Search(si _Dst);
static void* _At(si _Dst);
static si _Insert(void *_Src, si _Dst);
static si _Push_back(void *_Src);
static si _Size();
static si _Swap(si _target1, si _target2);
static si _Erase(si _Dst);


/* 静的グローバル変数 */
static CVECTOR_PARAMETER* g_parameter;

/*******************************************************************************
	概要		:	要素番号を検索します
	説明		:	内部関数なので、外部から呼び出されることはありません
	Include	:	
	引数		:	要素番号(int型)
	戻り値	:	VECLIST *
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
static VECLIST* Search(si _Dst)
{


	/* 最初の一回だけ処理 */
	if(g_parameter->search_firstflag)
	{
		g_parameter->search_firstflag = 0;
		g_parameter->Search_tmp = g_parameter->pri_head;
	}

	/* 前回に_Erase関数が呼ばれていた */
	if(g_parameter->pri_EraseFlag)
	{
		g_parameter->Search_tmp = g_parameter->Search_tmp_next;
		g_parameter->pri_EraseFlag = 0;
	}

	/* 前回検索した番号と今回検索する番号が同じだったなら */
	if(g_parameter->LastSearchNo == _Dst)
		return g_parameter->Search_tmp;
	
	if((_Dst - g_parameter->LastSearchNo) > 0)
	{
		/* 前方向探査 */
		si cnt;
		FOR(cnt, (_Dst - g_parameter->LastSearchNo))
		{
			/* 末端まで検索したら強制終了 */
			if(!g_parameter->Search_tmp->next)
				break;

			g_parameter->Search_tmp = g_parameter->Search_tmp->next;
		}
	}
	else
	{
		/* 後方向探査 */
		si cnt;
		FOR(cnt, (g_parameter->LastSearchNo - _Dst))
		{
			/* 末端まで検索したら強制終了 */
			if(!g_parameter->Search_tmp->prev)
				break;

			g_parameter->Search_tmp = g_parameter->Search_tmp->prev;
		}
	}

	/* 最後に検索したリストの番号を記憶 */
	g_parameter->LastSearchNo = _Dst;
	
	/* _Erase対策 */
	g_parameter->Search_tmp_next =g_parameter-> Search_tmp->next;
	return g_parameter->Search_tmp;
}

/*******************************************************************************
	概要		:	指定した要素を取り出します
	説明		:	void型のポインタが戻り値なので、明示的にキャストする必要があります。
	Include	:	
	引数		:	要素番号(int型)
	戻り値	:	void *
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
static void* _At(si _Dst)
{
	VECLIST* Search_tmp = Search(++_Dst);

	/* headかtailだった場合error */
	if(!Search_tmp->address)
		return NULL;

	return (void*)Search_tmp->address;
}

/*******************************************************************************
	概要		:	リストへ要素を格納します
	説明		:	登録したい要素を、指定した場所へ挿入します
	Include	:	
	引数		:	要素のポインタ, 挿入したい場所(int型)
	戻り値	:	成功なら0不成功なら1を返します
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
static si _Insert(void *_Src, si _Dst)
{
	void* data_tmp;
	VECLIST* list_tmp;
	VECLIST* Search_tmp = g_parameter->pri_head;

	data_tmp = malloc(g_parameter->pri_ElementSize);
	memmove(data_tmp, _Src, g_parameter->pri_ElementSize);

	list_tmp = (VECLIST*)calloc(1, sizeof(VECLIST));
	list_tmp->address = data_tmp;

	Search_tmp = Search(_Dst);

	/* リストへ挿入 */
	/*■  Search_tmp <-> list_tmp <-> Search_tmp->next  ■*/
	list_tmp->next = Search_tmp->next;
	list_tmp->prev = Search_tmp;
	Search_tmp->next->prev = list_tmp;
	Search_tmp->next = list_tmp;
	
	/* 要素数カウントアップ */
	g_parameter->pri_Elementcnt++;
	return 0;
}

/*******************************************************************************
	概要		:	リストへ要素を格納します
	説明		:	登録したい要素を一番最後のリストへ挿入
	Include	:	
	引数		:	要素のポインタ
	戻り値	:	成功なら0不成功なら1を返します
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
static si _Push_back(void *_Src)
{
	/* 一番最後のリストへ挿入 */
	_Insert(_Src, g_parameter->pri_Elementcnt);
	return 0;
}

/*******************************************************************************
	概要		:	現在の要素の数を返します
	説明		:	現在の要素の数をint型で返します。
	Include	:	
	引数		:	無し
	戻り値	:	要素数(int型)
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
static si _Size()
{
	return g_parameter->pri_Elementcnt;
}

/*******************************************************************************
	概要		:	指定された要素の場所を入れ替えます
	説明		:	現在のparameterのセットされているリストを入れ替えますします
	Include	:	
	引数		:	要素番号1(int型の数値), 要素番号2(int型の数値)
	戻り値	:	成功なら0不成功なら1を返します
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
static si _Swap(si _target1, si _target2)
{
	VECLIST* Search_tmp1, * Search_tmp2;
	void* tmp;
	Search_tmp1 = Search(++_target1);
	Search_tmp2 = Search(++_target2);

	/* headかtailだった場合error */
	if(!Search_tmp1->address || !Search_tmp2->address)
		return 1;

	/* 要素の入れ替え ※リストは変更しない */
	tmp = Search_tmp1->address;
	Search_tmp1->address = Search_tmp2->address;
	Search_tmp2->address = tmp;

	return 0;
}

/*******************************************************************************
	概要		:	指定された要素をクリアします
	説明		:	現在のparameterのセットされているリストをクリアします
	Include	:	
	引数		:	要素番号(int型の数値)
	戻り値	:	成功なら0不成功なら1を返します
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
static si _Erase(si _Dst)
{

	VECLIST* Search_tmp;
	Search_tmp = Search(++_Dst);

	/* リストのつなぎ替え */
	Search_tmp->prev->next = Search_tmp->next;
	Search_tmp->next->prev = Search_tmp->prev;

	/* リストと要素を開放 */
	free(Search_tmp->address);
	free(Search_tmp);

	/* _Erase実行済みフラグON */
	g_parameter->pri_EraseFlag = 1;

	g_parameter->pri_Elementcnt--;
	return 0;
}

/*******************************************************************************
	概要		:	リスト構造の要素をすべてクリアします
	説明		:	現在のparameterのセットされているリストをクリアします
	Include	:	
	戻り値	:	成功なら0不成功なら1を返します
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
static si _Clear()
{
	si cnt;
	si Frequency = g_parameter->pri_Elementcnt;
	FOR(cnt, Frequency)
	{
		_Erase(0);
	}
	return 0;
}


/* 外部関数 ----------------------------------------------*/


/*******************************************************************************
	使い方	:	必ず最初に呼び出します。
	概要		:	CVECTORが利用するparameterをセットします
	説明		:	複数のリストを管理するために、parameterを分離させます
	Include	:	cvector.h stdlib.h
	引数		:	C_VECTOR *_Ldata	;オブジェクト
				int Size			;リストの要素サイズを指定します
	戻り値	:	成功なら0不成功なら1を返します
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
void CVECTOR_PARAMETER_SET(C_VECTOR* _Src)
{
	g_parameter = &_Src->parameter;
}

/*******************************************************************************
	使い方	:	必ず最初に呼び出します。
	概要		:	CVECTORの全体の処理を開始します
	説明		:	構造体の初期化と、メソッドをセットします
	Include	:	cvector.h stdlib.h
	引数		:	C_VECTOR *_Ldata	;オブジェクト
				int Size			;リストの要素サイズを指定します
	戻り値	:	成功なら0不成功なら1を返します
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
si CVECTOR_START(C_VECTOR *_Ldata, int Size)
{
	
	/* リストの先頭と後尾の空要素作成 */
	VECLIST* head = (VECLIST*)calloc(1, sizeof(VECLIST));
	VECLIST* tail = (VECLIST*)calloc(1, sizeof(VECLIST));

	/* parameterの初期化 */
	memset(&_Ldata->parameter, 0, sizeof(_Ldata->parameter));

	g_parameter->pri_head = head;
	g_parameter->pri_tail = tail;

	/* リスト構造の構築 */
	g_parameter->pri_head->next = tail;
	g_parameter->pri_head->prev = NULL;
	g_parameter->pri_tail->prev = head;
	g_parameter->pri_tail->next = NULL;


	/* メソッドを構造体へ格納 */
	_Ldata->at			= _At;
	_Ldata->insert		= _Insert;
	_Ldata->erase		= _Erase;
	_Ldata->push_back	= _Push_back;
	_Ldata->size		= _Size;
	_Ldata->swap		= _Swap;
	_Ldata->clear		= _Clear;

	/* 要素サイズ格納 */
	g_parameter->pri_ElementSize = Size;

	/* _Serch関数フラグ */
	g_parameter->search_firstflag = 1;
	
	return 0;
}

/*******************************************************************************
	使い方	:	プラグラムの一番最後に必ず呼び出します
	概要		:	C_VECTORを終了します
	説明		:	全ての要素をFreeしたあと、ダミーデータをFreeします
	Include	:	cvector.h stdlib.h
	戻り値	:	成功なら0不成功なら1を返します
	Global	:	CVECTOR_PARAMETER g_parameter;
*******************************************************************************/
si CVECTOR_END()
{
	_Clear();
	free(g_parameter->pri_head);
	free(g_parameter->pri_tail);

	return 0;
}

投稿者:

「Cで簡易Vector」への49件のフィードバック

  1. Hello! I could have sworn I’ve visited this site before but after going through many
    of the posts I realized it’s new to me. Anyways,
    I’m definitely happy I found it and I’ll be bookmarking it and
    checking back often!

  2. Hiya, I am really glad I have found this information. Nowadays bloggers publish just about gossips and web and this is really annoying. A good blog with interesting content, that is what I need. Thanks for keeping this website, I’ll be visiting it. Do you do newsletters? Can not find it. bdedefadfbfe

  3. About time! Someone with some information on this. You’d think considering how popular Comic Book Adaptations are nowadays, some information would actually be pretty easy to find. Apparently not. Anyway, thanks for this! I appreciate it!

  4. I am extremely impressed with your writing skills and also with the layout on your blog. Is this a paid theme or did you customize it yourself? Either way keep up the nice quality writing, it’s rare to see a great blog like this one nowadays..

  5. Good post. I study something more challenging on different blogs everyday. It should all the time be stimulating to learn content from different writers and follow somewhat something from their store. I’d choose to use some with the content material on my weblog whether or not you don’t mind. Natually I’ll offer you a link on your web blog. Thanks for sharing.

  6. I am often to blogging and i actually admire your content. The article has really peaks my interest. I’m going to bookmark your web site and hold checking for brand new information.

  7. I’d prefer to use some of the content on my blog whether you don’t mind. Natually I’ll give you a link on your web blog. Thanks for sharing.

  8. I’m impressed, I must say. Really rarely do I encounter a blog that’s each educative and entertaining, and let me inform you, you’ve hit the nail on the head. Your thought is outstanding; the difficulty is something that not sufficient people are talking intelligently about. I am very pleased that I stumbled across this in my seek for something relating to this.

  9. That is the proper weblog for anyone who needs to find out about this topic. You realize so much its virtually onerous to argue with you (not that I truly would need…HaHa). You undoubtedly put a brand new spin on a topic thats been written about for years. Nice stuff, simply nice!

  10. I’d should test with you here. Which isn’t something I normally do! I take pleasure in studying a post that can make people think. Also, thanks for permitting me to remark!

  11. Spot on with this write-up, I truly suppose this website wants far more consideration. I’ll most likely be again to read far more, thanks for that info.

  12. Can I simply say what a relief to seek out someone who truly knows what theyre speaking about on the internet. You positively know how you can convey a problem to light and make it important. More folks have to learn this and perceive this aspect of the story. I cant consider youre no more well-liked because you undoubtedly have the gift.

  13. I’m impressed, I need to say. Actually rarely do I encounter a blog that’s each educative and entertaining, and let me let you know, you might have hit the nail on the head. Your concept is outstanding; the issue is one thing that not sufficient persons are speaking intelligently about. I’m very completely satisfied that I stumbled across this in my search for one thing regarding this.

  14. An interesting dialogue is price comment. I believe that it’s best to write extra on this topic, it might not be a taboo subject however generally individuals are not enough to speak on such topics. To the next. Cheers

  15. This is the proper blog for anyone who needs to find out about this topic. You notice so much its almost laborious to argue with you (not that I actually would want…HaHa). You positively put a brand new spin on a topic thats been written about for years. Great stuff, just nice!

  16. A powerful share, I simply given this onto a colleague who was doing just a little evaluation on this. And he in actual fact bought me breakfast as a result of I found it for him.. smile. So let me reword that: Thnx for the treat! But yeah Thnkx for spending the time to debate this, I feel strongly about it and love reading more on this topic. If potential, as you change into experience, would you thoughts updating your blog with more particulars? It’s extremely useful for me. Large thumb up for this blog put up!

  17. Once I originally commented I clicked the -Notify me when new comments are added- checkbox and now each time a comment is added I get 4 emails with the identical comment. Is there any method you’ll be able to remove me from that service? Thanks!

  18. There are some fascinating closing dates in this article however I don’t know if I see all of them center to heart. There is some validity but I’ll take maintain opinion till I look into it further. Good article , thanks and we wish more! Added to FeedBurner as effectively

  19. An fascinating dialogue is worth comment. I believe that you should write more on this topic, it may not be a taboo subject but typically individuals are not enough to talk on such topics. To the next. Cheers

  20. What I dont understand is how youre not even more popular than you are now. Youre just so intelligent. You know so much about this subject, made me think about it from so many different angles. Its like people arent interested unless it has something to do with Lady Gaga! Your stuffs great. Keep it up!

  21. I discovered your weblog site on google and verify a couple of of your early posts. Proceed to maintain up the very good operate. I simply additional up your RSS feed to my MSN Information Reader. Looking for forward to reading extra from you later on!…

  22. This web site is really a walk-via for all the data you wished about this and didn’t know who to ask. Glimpse right here, and you’ll positively uncover it.

  23. What I dont understand is how youre not even more popular than you are now. Youre just so intelligent. You know so much about this subject, made me think about it from so many different angles. Its like people arent interested unless it has something to do with Lady Gaga! Your stuffs great. Keep it up!

  24. I discovered your blog web site on google and verify just a few of your early posts. Continue to keep up the very good operate. I simply additional up your RSS feed to my MSN Information Reader. Searching for forward to studying more from you afterward!…

  25. hello there and thank you for your information – I have definitely picked up something new from right here. I did however expertise some technical points using this website, as I experienced to reload the web site lots of times previous to I could get it to load properly. I had been wondering if your web host is OK? Not that I am complaining, but sluggish loading instances times will sometimes affect your placement in google and could damage your high quality score if advertising and marketing with Adwords. Anyway I’m adding this RSS to my e-mail and can look out for much more of your respective interesting content. Make sure you update this again soon..

  26. When I originally commented I clicked the -Notify me when new comments are added- checkbox and now each time a comment is added I get 4 emails with the identical comment. Is there any approach you’ll be able to take away me from that service? Thanks!

  27. I have been exploring on the internet looking to get ideas on how to get our web site coded, your overall style together with theme are excellent. Did you code it yourself or did you get a coder to get it done for you?

  28. Very nice article and straight to the point. I don’t know if this is in fact the best place to ask but do you people have any ideea where to employ some professional writers? Thanks 🙂

  29. Hello Everett Bergmark!!
    I am not so good at English.
    However, it received it as a very good meaning. Thank you!!

  30. I love the part about “[The candidate is] inquisitive enough to take advice from many conflicting perspectives, wise enough come to their own conclusion, and have the character to convince others that what they propose is the right thing to do.”

コメントを残す

メールアドレスが公開されることはありません。