2014-09-19 10 views
0

Я пытаюсь использовать оператор диапазона в выражении if, чтобы печатать что-либо, когда значение $ b находится между 1 и 3, но приведенный ниже код переходит в бесконечный цикл. Я не уверен, как работает оператор диапазона в if.оператор диапазона в if в бесконечном цикле

#!/usr/bin/perl 
use warnings; 
for ($b = 0; $b < 10; $b++) { 
    if ($b = 1 .. 3) { 
     print "test\n"; 
    } 
} 

Заранее спасибо

+3

не говоря уже о том, что предупреждения сгенерированные. – ysth

+0

Спасибо всем за ваши ответы. еще одна вещь, если у меня есть два условия на левой стороне «..», тогда как это будет работать, например, #!/usr/bin/perl ## использовать предупреждения; while (<>) { if (($ c = 1 и $ b = 3) .. not $ b--) { print "значения c и b - $ c и $ b \ n"; } } какой будет диапазон «if()»? – user2896215

+0

, если любой из операндов .. является константой, он обрабатывается так, как если бы вы сказали '$. ==' эту константу, поэтому проверяете номер строки. если операндом является любое другое выражение, это выражение оценивается как логическое. поэтому ваш пример не будет зависеть от номеров строк. обратите внимание, что ($ c = 1 и $ b = 3) всегда истинно; Вы имели в виду == not =? – ysth

ответ

0

Я думаю, что проблема заключается в вашем if состоянии

Вы используете

if($b = 1..3){ 

Как происходит внутри if состояние его присваивая значение 1 $b поэтому каждый раз, когда его значение останется 1, оно движется в бесконечном цикле.

для создания этого цикла, чтобы работать в диапазоне 1..3 вы можете использовать

if($b == 1 || $b == 2 ||$b == 3) или if($b >= 1 && $b <= 3)

+0

'$ b == 1..3' не делает ничего смутно полезного. –

0

Я думаю, что вы хотите напечатать «тест», если $ Ь равно 1 или 2 или 3. Ваш код будет давать «Использование неинициализированного значения в диапазоне (или флопе) в строке test.pl 6." и вместо трех раз он будет печатать 10 раз.

Предложенное код будет:

#!/usr/bin/perl 
use strict; 
use warnings; 

for (my $b = 0; $b<10; $b++){ 
    if($b =~ /[1-3]/){ 
    print "test\n"; 
    } 
} 
+1

вам нужны привязки на этом: '/^[1-3] \ z /'; в противном случае любое число, которое имеет 1, 2 или 3 в любом месте, будет совпадать. – ysth

+0

Да, правда. У него было от 1 до 10 жестко закодированных и <10, поэтому я не упоминал. Но ваш общий характер: D – Jassi

+0

о, хорошая точка. – ysth

6

Range operator .. не работает так, как вы пытаетесь использовать его. Ваш if эквивалентно следующему:

if ($b = ($. == 1) .. ($. == 3)) { 

Потому что вы не делаете никаких операций с файлами, $. будет неопределенным. Поэтому диапазон всегда будет вызывать предупреждение и сбой и назначать undef для $b. Тогда, поскольку $b присваивается значение, цикл for никогда не будет выходить.

Вы должны использовать simple comparators:

#!/usr/bin/perl 
use warnings; 

for ($b = 0; $b < 10; $b++) { 
    if ($b >= 1 && $b <= 3) { 
     print "test\n"; 
    } 
} 

Выходы:

test 
test 
test 
+0

Ты прав, конечно ... Я немного смутился. Исправлена. – Miller

5

.. в скалярном контексте не оператор диапазона, то оператор Триггер. Вы могли бы использовать его соответствующим образом:

while (my $line = readline $filehandle) { 
    # print only first three lines 
    if (1..3) { 
     print "line $.: $line\n"; 
    } 
} 

Триггер возвращает ложь, пока первое условие возвращает истину (константы не обращаются неявно как нуждающаяся в сравнении с $, номер текущей строки.). Затем он продолжает возвращаться, пока второе условие не будет истинным. Таким образом, в приведенном выше примере блок if вводится только для строк с 1 по 3 ввода.

Бесконечный цикл - это то, что вы каждый раз назначаете '' $ b каждый цикл; возможно вы предназначенный == (сравнение), не = (задание). Но даже это не будет работать с диапазоном, как вы пытаетесь.

Если вы хотите проверить, находится ли число в заданном диапазоне, не используйте ни оператор диапазона, ни оператор flipflop; просто сравните:

if ($b >= 1 && $b <= 3) { 
0

@ Ответ на Miller замечательный, и он подходит для ваших нужд. Если вы ищете метод поиска, если значение содержится в массиве (числовые или не числовые, не последовательные значения и т. Д.), Посмотрите на модуль CPAN List::Util.

Этот пример выглядит для значения 5 в массив:

use strict; 
use warnings; 
use List::Util qw/any/; 

my @range = (1 .. 100); 
my $search_for = 5; 
my $found_in_range = any { $_ == $search_for } @range; 
print $found_in_range, "\n"; #<-- prints: 1 
Смежные вопросы