配列のコピー

今日ツイッターのタイムラインで配列のコピーの話で盛り上がってた。
C言語で配列のコピーするなら、memcpy関数を使うのがいいと思う。
memcpyはコンパイラによってはアセンブラで実装されている。
アセンブラっていうのはC言語なんかよりずっと低級言語で、使ったことある人なら分かるだろうけどCPUの中のレジスタ単位で値をいじれる。
だから自作でコピー関数作るより速いことが期待される。
ちなみに、似たような関数のmemsetは使い方ちょっと注意しなければいけない。
memsetとかmemcpyはバイト単位で値をセットしたりコピーをする。

int hoge[10];
memset(hoge, 1, sizeof(int)*10);

これは良くない。
int型が4バイトだとすると、hoge[0]~hoge[9]には0x01010101という数字が入ってしまうことになる。
1バイト単位で0x01というのが入っているということ。
memsetに与える初期値として入れていいのは0か-1しかダメみたいなのどこかで見た気がする。
-1だと0x11111111で初期化される。

ところで、ポインタというのはややこしくて、いくら学習しても学習し過ぎることはないと思う。

int *a;

と定義したら、

a

が表すのはポインタ(アドレス)。

*a

が表すのはaに入っている中身の値。
これだけでややこしい。

int b = 3;

というのがあるとすると、

a = &b;
*a = 5;

でbの値が書き変わってしまう。
困ったものだ。

ちなみに、今日の問題はC++STLというものを使うと見た目は簡単にできる。

std::vector< int > c(5, 1);

これで要素数が5で初期値1の配列のようなものcができて、

std::vector< int > d = c;

これでdというcの中身をコピーしたものが生成される。
見た目簡単だけど、この動作を理解するためにはコンストラクタとかコピーコンストラクタとかっていうものを分かってないといけない。
C++はクラスの利用者にとっては親切だけどクラスの開発者にとっては不親切な言語だというのをどこかのfjなんとかさんが言ってた。