D语言数组
News
2007-04-24
Category: 更新(update)
Posted by: 刘策(yayv)
新设栏目 D语言高级教程 , 并转贴一篇 深入分析D语言接口与COM接口的关系 精华文章
[更多]
2007-04-24
Category: 更新(update)
Posted by: 刘策(yayv)
新增2篇文章,均是对D语言数组进行探索的。一篇主要探索D语言数组长度修改时产生的影响, 另一篇主要探索D语言数组在多维的情况下如何初始化。
[更多]
| 2006-10-07 |
关键字:
先看一段代码:
它输出结果如下:
B7D19FB0, B7D19FB4, B7D19FB8,
B7D19FB0, B7D19FB4,
B7D19FB0, B7D19FB4, B7D19FB8,
B7D1CFA0, B7D1CFA4, B7D1CFA8, B7D1CFAC,
可以看到前3行地址相同,后面一行地址不同。为什ô?
D 语言的数组分配是内存紧凑的,当减小数组长度减小时,只需要修改切片大小而不需要重新分配。当长度变大时,也会检查原来的缓冲区是否够大,以确定是否需要 重新分配空间。注意第2次操作时把长度恢复为原来大小时,并非真的恢复了原来的状态,后面长出来的元素会被初始化为默认值。
再来看一个:
输出结果:
910FE0, 910FE4, 910FE8,
910FE0, 910FE4, 910FE8,
910FE0, 910FE4, 910FE8,
910FE0, 910FE4,
910FE0, 910FE4, 910FE8,
913FE0, 913FE4, 913FE8, 913FEC,
在 执行int[] d = c;以后,d的确是和c共享了存储区。不过在改变d的长度以后,它就和c分道扬镳了。所以int[] d = c不能理解为d是一个指向c的引用,它实际上创建了一个新的数组对象,但并不拷贝数组元素,它和int[] d = c[0 .. length]是等价的,都是数组切片操作。
这个问题让我困惑不已。比如你用char[]表示一个单词,用char[][]表示一行,char[][][]表示多行。如何引用这个单词?你当然可以ÿ次使用lines[i][j],但如果处理步骤很多,这会不会看起来很头大?
看上去应该这样使用:
可惜根据前面的结论,这将无法影响到lines。如果找不到一个引用类型指向数组,有时候使用起来还真是很麻烦。看起来把Line/Word包装成类是个勉强凑合的主意。。。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
void main()
writefln("");
c.length = 2;
foreach(inout int i; c)
writefln("");
c.length = 3;
foreach(inout int i; c)
writefln("");
c.length = 4;
foreach(inout int i; c)
writefln("");
}
void main()
writefln("");
c.length = 2;
foreach(inout int i; c)
writefln("");
c.length = 3;
foreach(inout int i; c)
writefln("");
c.length = 4;
foreach(inout int i; c)
writefln("");
}
它输出结果如下:
B7D19FB0, B7D19FB4, B7D19FB8,
B7D19FB0, B7D19FB4,
B7D19FB0, B7D19FB4, B7D19FB8,
B7D1CFA0, B7D1CFA4, B7D1CFA8, B7D1CFAC,
可以看到前3行地址相同,后面一行地址不同。为什ô?
D 语言的数组分配是内存紧凑的,当减小数组长度减小时,只需要修改切片大小而不需要重新分配。当长度变大时,也会检查原来的缓冲区是否够大,以确定是否需要 重新分配空间。注意第2次操作时把长度恢复为原来大小时,并非真的恢复了原来的状态,后面长出来的元素会被初始化为默认值。
再来看一个:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
void main()
writefln("");
foreach(inout int i; d)
writefln("");
d.length = 2;
foreach(inout int i; c)
writefln("");
foreach(inout int i; d)
writefln("");
d.length = 4;
foreach(inout int i; c)
writefln("");
foreach(inout int i; d)
writefln("");
}
void main()
writefln("");
foreach(inout int i; d)
writefln("");
d.length = 2;
foreach(inout int i; c)
writefln("");
foreach(inout int i; d)
writefln("");
d.length = 4;
foreach(inout int i; c)
writefln("");
foreach(inout int i; d)
writefln("");
}
输出结果:
910FE0, 910FE4, 910FE8,
910FE0, 910FE4, 910FE8,
910FE0, 910FE4, 910FE8,
910FE0, 910FE4,
910FE0, 910FE4, 910FE8,
913FE0, 913FE4, 913FE8, 913FEC,
在 执行int[] d = c;以后,d的确是和c共享了存储区。不过在改变d的长度以后,它就和c分道扬镳了。所以int[] d = c不能理解为d是一个指向c的引用,它实际上创建了一个新的数组对象,但并不拷贝数组元素,它和int[] d = c[0 .. length]是等价的,都是数组切片操作。
这个问题让我困惑不已。比如你用char[]表示一个单词,用char[][]表示一行,char[][][]表示多行。如何引用这个单词?你当然可以ÿ次使用lines[i][j],但如果处理步骤很多,这会不会看起来很头大?
看上去应该这样使用:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->char[][][] lines;
char[][] line = lines[0];
line.length = line.length + 1;
line[length - 1] = ",";
char[][] line = lines[0];
line.length = line.length + 1;
line[length - 1] = ",";
可惜根据前面的结论,这将无法影响到lines。如果找不到一个引用类型指向数组,有时候使用起来还真是很麻烦。看起来把Line/Word包装成类是个勉强凑合的主意。。。
