Perl程序中未初始化的变量问题

Chr*_*asa 1 perl scope

#!/usr/bin/perl

use warnings;

use Scalar::Util qw(looks_like_number);

sub term_value();
sub factor_value();

sub expression_value()
{   
    $num = @_;
    @expression = $_[0];
    print "expression[0]: " . $expression[0] . "\n";

    $index = $_[$num-1];
    print "index: $index\n";

    $result = &term_value(@expression, $index);
    $more = 1;

    while($more)
    {
        $op = $expression[$index];
        print "$op\n";
        if ($op eq "+" || $op eq "-")
        {
            $index++;
            $value = &term_value(@expression, $index);
            if ($op eq '+')
            {
                $result = $result + $value;
            } else {
                $result = $result - $value;
            }
        }
        else
        {
            $more = 0;
        }
    }
    return $result;
}

sub term_value()
{
    $num = @_;
    @expression = $_[0];
    print "expression[0]: " . $expression[0] . "\n";

    $index = $_[$num-1];
    print "index: $index\n";
    $result = &factor_value(@expression, $index);
    $more = 1;

    while($more)
    {
        $op = $expression[$index];
        if ($op eq "*" || $op eq "/")
        {
            $index++;
            $value = &factor_value(@expression, $index);
            if ($op eq '*')
            {
                $result = $result * $value;
            } else {
                $result = $result / $value;
            }
        } else {
            $more = 0;
        }
    }
    return $result;
}

sub factor_value()
{
    $num = @_;
    @expression = $_[0];
    print "expression[0]: " . $expression[0] . "\n";

    $index = $_[$num-1];
    print "index: $index\n";
    $result = 0;
    $c = $expression[$index];
    if ($c eq '(')
    {
        $index++;
        $result = &expression_value(@expression, $index);
        $index++;
    } else {
        while (looks_like_number($c))
        {
            $result = 10 * $result + $c - '0';
            $index++;
            $c = $expression[$index];
        }
    }
    return $result;
}

#Collect argument and separate by character
@one_char = split(//, $ARGV[0]);

$index = 0;
$result = &expression_value(@one_char, $index);

print $result . "\n";
Run Code Online (Sandbox Code Playgroud)

我的控制台返回以下警告:

Use of uninitialized value $op in string eq at eval.pl line 58.
Use of uninitialized value $op in string eq at eval.pl line 58.
Use of uninitialized value $op in string eq at eval.pl line 25.
Use of uninitialized value $op in string eq at eval.pl line 25.
Run Code Online (Sandbox Code Playgroud)

关于未初始化的$ op变量.我认为这可能是一个范围问题...但我无法弄明白.我已经尝试了我能想到的一切(在循环之外初始化变量等),但是在运行程序时似乎没有任何区别.任何建议将不胜感激!

ike*_*ami 5

你只使用包(〜全局)变量,这是一个很大的问题,因为你使用的是递归函数!首先添加

use strict;
Run Code Online (Sandbox Code Playgroud)

首先,这将识别您尚未声明的变量.用于my在适当的范围内声明它们.


你正试图将数组传递给潜艇,但你失败了.唯一可以传递给sub的是标量列表.如果要将数组传递给sub,则需要将引用(〜指针)传递给数组.

sub foo {
   my ($expressions, $index) = @_;
   print($expressions->[$index], "\n");
}

foo(\@expressions, $index);
Run Code Online (Sandbox Code Playgroud)

这就是你收到警告的原因.您正在为数组(@expression = $_[0])分配一个元素,然后尝试索引第二个或更晚的元素.


通过使用原型(),你告诉Perl sub不带参数.然后你用它&来告诉Perl忽略原型,这样你就可以将参数传递给你的潜艇了.摆脱()子名称之后和&子调用之前.


my $more = 1;
while ($more) {
   ...
   if (cond) {
      ...
   } else {
      $more = 0;
   }
}
Run Code Online (Sandbox Code Playgroud)

可以减少到

while (1) {
   ...
   last if !cond;
   ...
}
Run Code Online (Sandbox Code Playgroud)