本文节选自《LPC语言基础教程:从零学习游戏开发》,版权归@mudren,欢迎转载,但必须注明来源(mud.ren)。
数组也是日常开发中最常用的数据类型之一,前面章节已经讲解了数组数据类型的赋值方式,下面补充数组的更多知识。
对数组元素的增删改查:
int main(object me, string arg)
{
int *arr = ({});
// 增
arr += ({1});
arr += ({1});
// 改
arr[0] = 2;
// 删
arr -= ({2});
// 查:arr[n]或arr[<n]或arr[x..y]
return 1;
}
重要提示:对数组+-隐含copy操作,数组指向了新的地址。
另外,数组还支持&和|运算:
({ 1, 2, 3 }) & ({ 2, 4 }) = ({ 2 })
({ 1, 2, 3 }) | ({ 2, 4 }) = ({ 1, 2, 3, 4 })
both &= and |= now work with arrays
从特性来说,LPC中的数组更类似Python语言中的列表(list),操作灵活
除了以上运算符,还支持数组延展运算符...,示例:
int main(object me, string arg)
{
int *a = ({2, 3, 4});
int *b = ({1, a..., 5}); // b = ({1,2,3,4,5})
mixed *c = ({"mudren", 18, "武当派"});
printf("%O\n", b);
// 输出:name = mudren, age = 18, family = 武当派
printf("name = %s, age = %d, family = %s\n", c...);
return 1;
}
需要注意的是,数组的数据类型只在单独赋值时会做限制,在声明数组元素并赋值时可以赋值任何类型,比如一个字符串数组的元素可以在声明时赋值整型数据,但在单独赋值时元素类型必须和数组类型一致。
数组是一种特殊的数据类型,变量存的是地址而不是值,我们看看以下示例:
// 示例:6.2.1
int main(object me, string arg)
{
int *a, *b = ({1});
a = b;
a[0] = 2;
printf("a = %O\nb = %O\n", a, b);
return 1;
}
运行结果如下:
a = ({ /* sizeof() == 1 */
2
})
b = ({ /* sizeof() == 1 */
2
})
示例中改变了数组 a 的值,但数组 b 的值也变了,因为数组变量名指向数组首地址,数组变量存的是地址而不是数值。
如果需要把数组 b 的值赋值给数组 a ,且改变一个的值时不影响另一个,可以使用 copy() 外部函数,具体语法如下:
名称
copy - 可以递归的复制一个变量值
语法
mixed copy(mixed arg);
说明
返回变量 `arg` 的复制。变量只能是以下类型:array、buffer、class、mapping。
看看以下示例:
// 示例:6.2.2
int main(object me, string arg)
{
int *a, *b = ({1});
a = copy(b);
a[0] = 2;
printf("a = %O\nb = %O\n", a, b);
return 1;
}
运行结果如下:
a = ({ /* sizeof() == 1 */
2
})
b = ({ /* sizeof() == 1 */
1
})
比较特别的是,LPC 语言中数组可以直接使用 + 合并,数组元素也可以直接使用 - 移除,这个也在前面章节有讲解,但是有个细节需要注意,我们看看以下示例:
// 示例:6.2.3
int main(object me, string arg)
{
int *a, *b = ({1});
a = b;
a[0] = 2;
b += a;
printf("a = %O\nb = %O\n", a, b);
return 1;
}
运行结果如下:
a = ({ /* sizeof() == 1 */
2
})
b = ({ /* sizeof() == 2 */
2,
2
})
示例中数组 b 的改变并没有影响数组 a,这是因为使用 + 做数组运算时并不是改变了原始数组的值,而是改变了数组在内存中的地址。
数组相关外部函数如下:
- allocate - 初始化数组
- arrayp(pointerp)- 判断变量是否是数组
- element_of - 返回数组的随机元素
- filter_array - 过滤数组元素并返回过滤后的数组
- implode - 合并数组为字符串
- map_array - 修改数组元素并返回修改后的数组
- member_array - 判断指定值是否是数组中的元素
- shuffle - 随机打乱字符串元素
- sort_array - 数组排序
- unique_array - 分组数组元素并返回
函数具体用法请看:https://wiki.mud.ren/index.php?title=Lpc:Efun
当数组当元素还是数组时,就是二维数组,我们可以使用以下方式定义二维数组:
a = allocate(10);
a[0] = allocate(10);
a[1] = allocate(10);
...
或者
mixed a;
a = ({ ({ 1, 2, 3 }), ({ 1, 2, 3 }) });
使用 mixed 定义可以定义二维数组,也可以定义元素类型为混合类型的数组。如果变量类型只为数组,推荐也加上 *(使用 mixed *a;),虽然这并没有什么用,但是可以统一数组的定义样式,知道这个变量应该是一个数组。
mixed类型数组元素不只是可以是数组,而是可以是任何类型的数据,不像其他多数编程语言数组元素限制同一种数据类型,如:
({1,'a',"b",({1,2,3}),(["a":"b"]), me})是一个合法的数组。
数组在使用时需要注意索引越界问题,可以使用 sizeof() 外部函数获取数组元素个数,具体语法如下:
名称
sizeof() - 返回 array、mapping、buffer 或 string 类型数据的元素个数
语法
int sizeof( mixed var );
描述
返回 array、mapping、buffer 或 string 类型数据 `var` 的元素个数,如果 `var` 不是以上类型,返回 0 。
另外,和字符串类似,数据也有一种定界符样式,和字符串不同的是使用@@:
@@poem
二月春来半,宫中日渐长。
柳垂金屋暖,花发玉楼香。
拂匣先临镜,调笙更炙簧。
还将歌舞态,只拟奉君王。
poem
这就是一个字符串数组,每行分别是一个字符串元素。
最后,数组也可以调用函数,如下格式:
({x,y,z})->func();
数组的每个元素都会调用func()。