2010-10-23 6 views
5

Ho questo programma che non funziona come previsto. Aiutami.Perché il mio loop Perl è spento di uno alla fine?

Voglio stampare l'intestazione di una riga.

Se l'input è 4, desidero emettere 1|2|3|4.

Non funziona come tutti, se ho il codice di protezione $count valore funziona parzialmente ma manca l'ultimo numero.

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"; 

risposta

11

Il problema è qui:

my $count = @_; 

L'assegnazione avviene in uno scalare contesto che assegna il numero di elementi in ordine @_-$count, che il vostro caso è 1, come sei passando l'argomento 1 alla funzione.

Per risolvere questo problema si può fare:

my ($count) = @_; 

o

my $count = $_[0]; 

qui è un altro problema:

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

Utilizzando my che hai fatto $ilocali a il corpo di for e non sarà disponibile fuori it. Quindi il tuo print finale al di fuori dello for non stampa nulla. Per risolvere questa mossa la dichiarazione di $i fuori del ciclo:

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

fanno sempre un punto di scrivere

use strict; 

nella parte superiore del vostro programma che vi permette di catturare questi bug.

Il modo perl di fare ciò che la vostra funzione fa è:

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

suppongo che faremmo un buon team di codifica sincronizzato –

+0

Mi piace il modo perfetto. – Tom

+0

Grazie per la mini lezione. – user485167

1

$i non esiste una volta che hai lasciato il for ciclo a causa di dove è dichiarata.

Si potrebbe fare

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

Ancora più semplice:

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

Un vero hacker Perl potrebbe scrivere qualcosa del genere:

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

Una volta capito come funziona, si' scoprirai che hai imparato qualcosa in più su Perl.:-)

0

Un altro po 'di "essere più Perlish" è non utilizzare il ciclo for stile C. C'è quasi mai una necessità di usare uno stile C for in Perl.

Invece di

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

uso

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

Sono quasi equivalente, tranne quest'ultima versione è sia più facilmente leggibile e più resistente agli errori off-by-one. (Il motivo per cui il tuo codice stampava solo 1|2|3|4 invece di $i<$count è stato il - è un errore molto comune con lo stile C for loop che evita completamente il codice for (list).)

Inoltre, non effettuare il prefisso delle chiamate secondarie con &. È un holdover di Perl 4 che non è più necessario in Perl 5 e ha effetti collaterali di cui probabilmente non sei a conoscenza e probabilmente non vuoi. Basta usare printC($count) anziché &printC($count).

Ma, sì, in questo caso particolare, join è probabilmente un approccio migliore di for comunque.

Problemi correlati