无意识的无尽循环 - 为什么?

时间:2016-04-04 14:48:25

标签: perl

我有一组数值已经排序。我还有一个最小值和最大值,并希望从数组中删除小于最小值或大于最大值的任何值。当我的最小值小于第一个数组元素的值时,我得到一个无限循环。以下是相关代码的最小示例:

#!/usr/bin/perl

use strict;
use warnings;

my @array = ( 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 );
my $min_wert = 1;
my $max_wert = 13;

while ( $array[0] < $min_wert ) {
    shift @array;
}
while ( $array[-1] > $max_wert ) {
    pop @array;
}

print join( ' ', @array );
print "\n";

问题是,这个版本完美无瑕,输出

5 6 7 8 9 10 11 12 13

在这种情况下不输入第一个。

将相同的测试用例放入我的生产代码中,我在使用shift语句的行上收到以下错误消息:

  

在数字lt(&lt;)中使用未初始化的值   第1130行。

然后我介绍了一个计数器,试图找出为什么甚至输入了while循环,这完全消除了问题,而不是给我进一步诊断的机会。

    @werte_liste = sort {$a <=> $b} @werte_liste; 
    print join( ' ', @werte_liste );
    print "\n";
    print "Start: $start_index - Stop: $stop_index\n"

    while ( $werte_liste[0] < $start_index ) {
        print "In while-loop- why?\n";
        shift @werte_liste;
    }
    while ( $werte_liste[-1] > $stop_index ) {
        pop @werte_liste;
    }

为什么我在这种情况下输入第一个while循环?第二,对于我的具体问题是否有更好的解决方案(我在这里没有谈论很多值,因此代码的可读性比效率更重要)。

2 个答案:

答案 0 :(得分:3)

我不知道为什么它适用于您的测试用例但不在您的生产代码中,但我的猜测是这样的:

您的数组变空。如果$array[0] < $min_wert$array[0](如果数组为空,则会发生),undef,则$min_wert > 0为真。

在数值比较中,

undef基本上被视为0(它会发出警告)。

您可以检查数组是否仍包含以下元素:

while ( @array and $array[0] < $min_wert ) {

另一个while循环可能存在同样的问题。

答案 1 :(得分:1)

@werte_liste为空时会发生什么?

对于其中一个,$werte_liste[0]将是未定义的,而表达式$werte_liste[0] < $start_index将生成Use of uninitialized value in numerlic lt ...警告。

对于另一个,$werte_liste[0]将为<比较评估为0。如果$start_index为正数,则$werte_liste[0] < $start_index为真。

最后,shift @werte_liste@werte_liste无效,@werte_liste将保持为空,您的while ...表达式将无限期重复。<​​/ p>