我试图在perl中使用哈希表来实现符号表。在下面的代码中,我创建了一个数组@Table
,其元素是对另一个数组的引用(其元素也是数组引用)。这是代码:
#!/usr/bin/perl
sub getKey {
my $name = $_[0];
my $count = 0;
my $key = 0;
my $len = length ($name);
while ($count < $len) {
my $char = substr ($name, $count, 1);
$key = 7 * $key + ord ($char);
$count = $count + 1;
}
$key = $key % 20;
return $key;
}
sub Define {
(my $name, my $kind, my $type, my $Index, my $scope) = @_;
my $key = getKey($name);
print "key is $key\n";
@$entry = ("$name", "$kind", "$type", "$Index", "$scope");
unshift (@{$Table[$key]}, $entry);
print "$name is stored at key $key it is of kind $kind, type $type, at Index $Index and scope $scope\n";
print "entry is @$entry\n";
my $i = 0;
while ( $i < 20){
print "[$i]--> @{$Table[$i]->[0]}\n"; $i++;}
return;
}
our @Table;
my $i = 0;
while ($i < 20) {
$Table[$i] = [];
$i++;
}
Define ("x","field","int","0","0");
Define ("y","argument","int","0","1");
我希望每当我使用子程序Define
定义新符号时,我会添加有关类型的信息(例如,符号x的类型是字段)和种类(对于x来说是int)等,元素$key
指向的数组,即数组$Table[$key]
的{{1}}。将使用子例程@Table
为符号(x或y)计算密钥。作为上述代码的输出打印出的最终数组是:
getKey
但我希望输出为:
[0]--> y argument int 0 1
[1]--> y argument int 0 1
[2]-->
[3]-->
[4]-->
[5]-->
[6]-->
[7]-->
[8]-->
[9]-->
[10]-->
[11]-->
[12]-->
[13]-->
[14]-->
[15]-->
[16]-->
[17]-->
[18]-->
[19]-->
为什么输出与预期不同?
答案 0 :(得分:1)
问题出在这一行:
@$entry = ("$name", "$kind", "$type", "$Index", "$scope");
由于未定义$entity
变量,因此它具有全局范围。因此Define(...)
次调用之间的值保持不变。这是您应该将use strict; use warnings;
放在脚本开头的原因之一。
以下是发生的事情:
Define(...)
来电时@$entry = ...
将创建匿名数组$entry
@Table
$entity
仍然指向同一个匿名数组(因为它是全局的)@Table
@Table
中有两次相同的引用,第二次运行会覆盖第一个值要解决此问题,您需要像这样声明$entry
的范围:
my $entry = [$name, $kind, $type, $Index, $scope];
我使用了anonymous array syntax [...]
。