C言語でvectorさせろ

TopCoderをやってたら思いのほかvectorが使いやすかったんです。流石STLに含まれてるだけはあるな・・・
C言語でできないの?と思ってちまちまやってたんですが、非常に使い勝手が悪い形になってしまった。
でもvectorらしい、最後尾へpushしたり、添え字で取り出すことはできるようにはできたんで、まぁいいかな。と。




100行ぐらいになったので例によってcodepadに乗せた。
http://codepad.org/KyIpXYnI


上でやってることは、

  • Vectorを扱う関数郡を作った
  • 値をpushしたり、setしたりした。
  • 配列を大きくする必要が出ると再確保を行う("realloc"のメッセージがでる)
  • キャストを用いた添え字でのアクセス。
  • デバッグとして現在のvectorが持つ領域のdump


vectorってのは要は、
要求された範囲以上のアクセスがあったら、動的に配列を大きくしてやればいいってだけです。
なので配列を大きくしたくなったらreallocしまくればいいってわけです。
でもそれを一々書くのはめんどくさいので、vectorというクラスで内部処理を隠したわけですね。


C言語で実装するのは難しいです。
というのも、C言語にはテンプレートという概念がないので、型を指定することができない。
例えば、C++でdouble型とint型のvectorを作るとすると、2つに対応するため、
vector<double>, vector<int>を作る必要があります。
これは、値をセットするときは、セットする値の型を知らないといけないのと、
戻り値の値を正常に返すためには、戻り値の型を知らないといけない為です。

しかし、テンプレートなんて高貴なもんC言語にはないので、諦めます。


で、考えたのは、vectorを作るときにあらかじめ型のサイズを引数でもらって、
値を渡すときは値を指し示してるポインタを渡してやって、型のサイズ分をコピーする形です。
値をそのまま渡すことができず、1度変数にいれてからでないと渡せないので利便性は悪くなります。
値を受け取るときも、1度変数に入れてもらわないとならないので、さらに利便性は悪くなります。
なので、型を決めてしまってint型専用のvectorなんてすると、
戻り値の型を一意にできるので、実装がいくらか簡単になり、利便性もよくなります。


一応キャストを用いれば、添え字のアクセスは可能です。が、普通こんなコードを書きたがらないでしょう。
また、添え字でアクセスして値をセットしても、pushの為のデータの末尾を示す値が変動しないので、
下手するとpushしてる最中にその添え字でセットした値を上書きすることになります。
コードを見てのとおり、最後のほうで25番目に直接アクセスを行う操作をしていますが、
デバッグVectorが持つ値を見ると、sizeの値は最後にsetVectorをした20のままです。
なので、アクセサー関数からしっかり設定、取得をしないといけません。


メリットをあげれば、テンプレートと違って、型毎にコードを生成することがないので、
複数の型をvectorで扱った場合で比較すると、コード量は少なくなります(キリッ


エラー処理や後始末処理は省いてます。
createVectorの失敗を考慮してませんし、使い終わってもfreeしてません。
noob...