3.3.Perl数据类型-数组
1.定义
一组有序的标量数据。数组中可以存储无限多的元素。
@数组变量 = 列表直接量
1.1.数组定义:
@array = ("zhangsan",3.14,"李四",36,undef,undef,"wangwu");
@arr = (); # 元素个数为0的空列表
@arr2 = undef; # 等同于 @arr2 = (undef);
数组的索引:
从前往后:0,1,2,3,4,。。。。。。
从后往前: 。。。。。 。 -5,-4,-3,-2,-1
最后一个索引的位置:$#array 或 -1;
数组的长度(元素个数):$#array+1
1.2.列表直接量
1.1.2.列表定义
(1,2,3)
()
(1..100) # 使用范围操作符.. 表示从(1,2,3,4.......98,99,100)
(1,undef,"zhangsan",1..5,$name,$age,$n..$m)
($a,$b,$c) = (1,"wangwu",5,6,6,7)
1.2.2.单词列表创建:qw
qw: quoted word 或 quoted by whitespace
这里的引号类似于单引号,不能对"\n \t \r"转义,也不能做变量内插。空白(回车、换行 空格、制表符、换行符)会被抛弃。有些可以转义,如 @ 、\ \ 等
qw ( my name is perl ) # 通("my","name","is","perl")
qw ! my name is perl !; # 定界符可以使用() !! // ## [] {} <> 避免使用不合适的定界符
2.访问数组元素
2.1.使用下标访问
$数组名[下标值]: 下标值可以是表达式(索引表达式),但是表达式的值一定会转换成整数。
a r r a y [ 0 ] , array[0] , array[0],array[1], $array[-2], $array[-1], a r r a y [ array[ array[#array]
访问不存在的下标元素(数组下标越界),不会报错, 返回undef;
给数组不存在的下标赋值,会扩容:
$array[999] = "111"; # 扩容后,未定义的元素值默认为undef;
双引号字符串中的数组内插:
print "the array is: @array"; # 会添加额外的空格
print @array; # 不会添加空格
print "the email address is zhangsan\@yahoo.com"; # 需要转义
print "first element is $array[0] \n";
print "first element is ${array}[0] \n"; # 使用的是变量${array}
2.2.访问数组中的每一个元素
2.2.1.流程控制while
$name = "wangwu";
@array = ("a","b","c",$name);
$idx = 0;
while($idx <= $#array){
print $array[$idx];
$idx++;
}
2.2.2.流程控制foreach
foreach $tmp (@array){
print $tmp; $ 如果修改控制变量$tmp,会修改@array的元素
}
foreach (@array){
print $_; # 如果省去控制变量$tmp,则可以直接使用默认变量$_
}
2.2.3.each函数
访问每个元素的值和下标。类似哈希操作。
@array = qw / my name is perl /;
while(($index, $value) = each (@array)){
print "$index: $value \n";
}
# 类似于:
foreach $index (0..$#array){
print "$index: $array[$index] \n";
}
3.数组的操作函数(改变数组)
可以不使用数组的索引操作数组的元素
3.1.操作数组的末尾元素
-
pop函数
去除数组的最后一个元素。最后一个元素被删除了。函数的返回值就是删除的最后一个元素。移除一个空数组,返回undef。数组本身会改变
$ele = pop (@array); # 括号可以省略
-
push函数
添加一个或多个元素到数组的尾部。返回添加元素后数组的长度。数组本身会改变
@a = (1,2,3); $b = 33; $size = push(@a,$b) push(@a,1..5) push(@a,qw/ hello world /)
3.2.操作数组的头部元素
-
shift函数
在头部移除一个元素。第一个元素被删除了。函数返回值就是删除的第一个元素。移除一个空数组,返回undef;。数组本身会改变。
$ele = shift @array; # 可以添加括号
-
unshift函数
添加一个或多个元素到数组的头部。数组本身会改变
@a = (1,2,3); $b = 33; unshift(@a,$b) unshift(@a,1..5) unshift(@a,qw/ hello world /)
3.3.操作数组的任意位置
-
splice函数
@removed = splice (@array,$from,$length,@add)
从数组@arry的索引 f r o m 开 始 ( 包 括 from开始(包括 from开始(包括from),移除$length个元素,并在移除的位置填充上数组@add。
数组@array会改变。
变化方式:
@removed = splice (@array,$from) @removed = splice (@array,$from,$length) @removed = splice (@array,$from,$length,@add)
4.数组其他操作
基本不改过数组
-
reverse函数
对数组倒序后,并返回倒序后的结果。不改变原数组。
@nums = 1..5; @reverse_nums = reverse @nums;
-
sort函数
按照字符集顺序对数组元素进行排序,默认升序,返回排序后的数组。不改变原数组。
@names = ("zhangsan","lisi","wangwu") @sorted_name = sort @names; @reverse_sorted_names = reverse( sort(@names) ); @sorted_nums = sort 97..101; # 结果(100,101,97,98,99) 以后学习如何按照数值排序
5.上下文
5.1.定义
上下文(context): 所谓的上下文,就是如何使用表达式。具体上下文是什么,起到决定性作用的是操作符(函数也是操作符)。
a * b
a . b
a x b
sort a
$a = 42 + @array
@list = @array
$n = @array
但是仅仅从表达式无法归纳出一个通用的法则。实际上能概况的规则是:那种上下文更有意义,就使用那种上下文。
5.2.建议
学习Perl,就是学习Larry的思维方式。
Perl语言的优点之一是书写灵活,太灵活也是缺点之一。为了减少代码中上下文的歧义,建议使用明确的方式处理代码中需求:
$n = @array # 建议 $n = $#array + 1;
$array[$idx] # $idx一定是个整数
@arr = 4 * 5; # 建议 @arr = (4*5)
@arr = undef # 建议 @array = (undef);
5.3.强制指定上下文
scalar: 强制指定列表上下文为标量上下文。scalar是个伪函数(不是真正的函数),他只是告诉Perl这里要切换到标量上下文了。
@genes = qw[ "a","b","c"];
print @genes;
print scalar @genes;
没有对应的函数将标量上下文强制指定为列表上下文。
5.4.列表上下文的标准输入
-
键盘输入
chomp($one_line = <SDTIN>); # 默认从键盘输入一行数据,回车结束;并去掉$one_line的最后的回车 chomp(@array = <SDTIN>);# 默认从键盘输入多行数据,windows系统按Control+d结束(linux:control+z);并去掉每个元素后面后面的换行符。
-
文件输入
会将整改文件同时读到内存中,如果文件过大,会导致内存不足。