2010-10-23 4 views
5

Ich habe dieses Programm, das nicht wie erwartet funktioniert. Hilf mir.Warum wird meine Perl-Schleife am Ende um eins unterbrochen?

Ich möchte eine Zeilenüberschrift drucken. Wenn der Eingang 4 ist, möchte ich 1|2|3|4 ausgeben.

Es funktioniert nicht als alle, wenn ich $count Wert festcode es funktioniert teilweise, aber die letzte Nummer fehlt.

sub printC { 
     my $count = @_; 
     # count = 4 # works partially only prints 1|2|3 
     for(my $i=1;$i<$count;$i++) { 
       print "$i|"; 
     } 
     print $i; 
} 
$count = 2; 
&printC($count); 
print "\n"; 

Antwort

11

Das Problem ist hier:

my $count = @_; 

Die Zuordnung in einem Skalar Kontext geschieht, die die Anzahl der Elemente in einem Array @_-$count, die Ihrem Fall ist 1, wie Sie ordnet sind Übergabe von 1 Argument an die Funktion.

Um dies zu beheben, können Sie tun:

my ($count) = @_; 

oder

my $count = $_[0]; 

hier ein weiteres Problem:

for(my $i=1..... 
    ^^ 

von my verwenden Sie $ilokalen gemacht haben der Körper von for und es wird nicht verfügbar sein außerhalb es. Also dein endgültiges print außerhalb der for druckt nichts. Um dies zu beheben bewegt die Deklaration von $i außerhalb der Schleife:

sub printC { 
     my ($count) = @_; 
     my $i; 
     .... 

immer es einen Punkt, um

use strict; 

an der Spitze des Programms zu schreiben, die Sie solche Fehler fangen kann.

Die Perl Weg zu tun, was Ihre Funktion tut, ist:

print join('|',1..$count); 
+0

schätze, wir würden ein gutes synchronisiertes Coding-Team machen –

+0

Ich mag den Perl-Weg. – Tom

+0

Danke für die Mini-Lektion. – user485167

1

$i nicht vorhanden ist, wenn Sie die for Schleife verlassen haben, weil in dem es deklariert ist.

könnten Sie tun

sub printC { 
    my ($count) = @_; 
    my $i; 
    for ($i = 1; $i < $count; $i++) { 
     print "$i|"; 
    } 
    print $i; 
} 

Noch einfacher:

sub printC { 
    my ($count) = @_; 
    print join("|", 1 .. $count) . "\n"; 
} 
5

Ein echter Perl Hacker so etwas schreiben könnte:

sub printC { 
    my $count = shift; 
    print join "|", (1 .. $count); 
} 

Wenn Sie verstehen, wie dies funktioniert, Sie‘ Sie werden mehr über Perl erfahren.:-)

0

Ein anderes Bit von "mehr Perlish sein" ist, die C-style for Schleife nicht zu verwenden. Es gibt fast nie müssen ein C-style for in Perl verwenden.

Statt

for(my $i=1;$i<$count;$i++) { ... } 

Verwendung

for my $i (1 .. $count) { ... } 

Sie sind fast gleichwertig, mit Ausnahme der letztgenannten Version ist sowohl leicht lesbar und resistenter gegenüber Off-by-one Fehler. (Der Grund, Ihr Code nur druckt 1|2|3 statt 1|2|3|4 ist, weil der Test in Ihrem C-Stil for$i<$count war die Überprüfung, wenn es $i<=$count gewesen sein sollte -. Dies ist ein sehr häufiger Fehler mit C-Stil for Schleifen, die for (list) vollständig vermeiden)

Außerdem sollten Sie Ihre Unterrufe nicht mit & voranstellen. Es ist ein Überbleibsel von Perl 4, der in Perl 5 nicht mehr benötigt wird und Nebenwirkungen hat, die Sie wahrscheinlich nicht kennen und wahrscheinlich nicht wollen. Verwenden Sie einfach printC($count) anstelle von &printC($count).

Aber, ja, in diesem speziellen Fall ist join sowieso eine bessere Annäherung als for irgendwie.

Verwandte Themen