如果我将变量赋予全局变量,它可以正常工作。这段代码有什么问题?
sub Multiply {
$res = $a* $b;
return ( $a, $b, $res);
}
main:
my $a =3;
my $b =4;
my $res;
( $a, $b, $res) = Multiply();
print ("Input1 = $a\nInput2 = $b\nResult = $res");
答案 0 :(得分:5)
最重要的错误是你没有声明变量而没有
use warnings;
use strict;
此外,使用$a
和$b
是危险的,因为它们是sort
的全局字符。
my
变量$a
,$b
,$res
是词汇,但子中的变量是其他全局变量;这是因为sub是在声明词法之前定义的。它们从未被初始化,因此它们的undef
会在返回时覆盖词法。添加use warnings;
Use of uninitialized value $b in multiplication (*) at .. [in sub] Use of uninitialized value $a in multiplication (*) at .. [in sub] Use of uninitialized value $a in concatenation (.) or string at .. [in print] Use of uninitialized value $b in concatenation (.) or string at .. [in print]
sub中的全局$res
被初始化为0
,其返回值将覆盖词法。
如果你要将sub的代码放在最后,它将会工作,"因为lexicals在编译sub之前被声明,所以sub看到它们并且可以使用它们。但话说回来,如果词汇中的词汇是动态的,那就是"范围也不会起作用;见this post。
只需在子程序中声明变量并将变量传递给它。
然后它们只存在于sub中,也从外部范围中屏蔽这些名称。 sub有一个定义良好的接口,返回你根据需要分配的值(标量),一切都很清楚。
请参阅Private Variables via my() in perlsub
<强>更新强>
标题提示use strict;
到位,评论指出。然后问题是关于变量的声明。
strict pragma要求在所有其他事项中声明所有变量或完全限定。
子语句中的$res
未声明,因此编译失败; $a
和$b
作为全局变量存在(但与sort
一起使用 - 为方便起见,请不要使用它们)。声明的变量在包含的范围中可见,但是使用函数时,这并不是很简单,并且您希望在函数内声明所有变量。
使用our声明的类似全局变量是可以的,但它们的使用带来了其他问题。虽然偶尔使用全局变量很少需要它们,但最好避免使用它们,因为它们的使用会破坏干净的范围,这是编程中的一个关键原则。
有用的参考是perldiag,它解释了错误消息。或者,在调试运行中使用diagnostics,或者更好地使用splain或使用perl -Mdiagnostics ...
运行代码