はじめに
D言語には、静的配列と動的配列があります。
意識せずにコピー処理を行うと、想定外の結果となるため、注意が必要です。
C言語の場合
C言語で配列をコピーする場合の実装例は、以下の通りかと思います。
コピー後、配列t
の値を書き換えています。
結果として、配列s
と配列t
の値は異なっています。
copysample.c
#include <stdio.h>
int main(void){
int s[3] = { 1, 2, 3 };
int t[3];
// t = s とはできない
memcpy(t,s,sizeof(s));
printf("s = %d %d %d\n",s[0],s[1],s[2]);
printf("t = %d %d %d\n",t[0],t[1],t[2]);
t[1] = 4;
printf("s = %d %d %d\n",s[0],s[1],s[2]);
printf("t = %d %d %d\n",t[0],t[1],t[2]);
}
実行結果
s = 1 2 3
t = 1 2 3
s = 1 2 3
t = 1 4 3
D言語の場合
D言語では、t = s
を使ったコピーが可能ですが、静的配列と動的配列で実行結果が異なります。
int[3]は、静的配列です。先ほどのC言語の場合と同じ実行結果になります。
copysample1.d
import std.stdio;
void main(){
int[3] s = [ 1, 2, 3 ];
int[3] t;
t = s;
writefln("s = %s",s);
writefln("t = %s",t);
t[1] = 4;
writefln("s = %s",s);
writefln("t = %s",t);
}
実行結果
s = [1, 2, 3]
t = [1, 2, 3]
s = [1, 2, 3]
t = [1, 4, 3]
int[]
は、動的配列です。
先ほどとは実行結果が異なり、配列s
と配列t
の値が同じになっています。
copysample2.d
import std.stdio;
void main(){
int[] s = [ 1, 2, 3 ];
int[] t;
t = s;
writefln("s = %s",s);
writefln("t = %s",t);
t[1] = 4;
writefln("s = %s",s);
writefln("t = %s",t);
}
実行結果
s = [1, 2, 3]
t = [1, 2, 3]
s = [1, 4, 3]
t = [1, 4, 3]
copysample1.dの静的配列では、ディープコピー、
copysample2.dの動的配列では、シャローコピーが行われています。用語補足
では、動的配列をディープコピーしたい場合はどうすればいいのか。
D言語では、.dup
というプロパティが用意されています。
copysample3.d
import std.stdio;
void main(){
int[] s = [ 1, 2, 3 ];
int[] t;
t = s.dup;
writefln("s = %s",s);
writefln("t = %s",t);
t[1] = 4;
writefln("s = %s",s);
writefln("t = %s",t);
}
実行結果
s = [1, 2, 3]
t = [1, 2, 3]
s = [1, 2, 3]
t = [1, 4, 3]
おまけの注意点
D言語には、もう1つ連想配列というものがあります。
連想配列のコピーは基本的に動的配列と同じですが、連想配列の要素がない空の状態でのコピーはnull
がセットされるだけで、シャローコピーにはならない点に注意です。
D言語のサイト(英語)
参考情報
他のプログラミング言語についてのリンク情報です。