2010-08-31 23 views
8

Sto studiando questo esempio di codice:Come funziona la dichiarazione goto in questo esempio?

class Program 
{ 
    static void Main(string[] args) 
    { 
     int x = 10; 
     int y = 10; 

     int generate=0; 

     string [,] myArrayTable = new string[x, y]; 

     Console.WriteLine("Enter a seek number: "); 
     string cautat = Console.ReadLine(); 

     for (int i = 0; i < x; i++) 
     { 
      for(int j = 0;j < y; j++) 
      { 
       myArrayTable[i, j] = (generate++).ToString(); 
      } 
     } 

     for(int i=0;i<x;i++) 
     { 
      for(int j=0;j<y;j++) 
      { 
       if(cautat.Equals(myArrayTable[i,j])) 
       { 
        goto Found; 
       } 
      } 
     } 

     goto NotFound; 

     Found: 
      Console.WriteLine("Numarul a fost gasit"); 

     NotFound: 
     Console.WriteLine("Numarul nu a fost gasit !"); 

     Console.ReadKey(); 
    } 
} 

Non capisco il motivo per cui l'affermazione "Not Found" è stato chiamato e la sua stampa relativo messaggio sulla console se entro in un numero di cercare come 10, in questo caso goto: L'istruzione Found è in esecuzione, quindi goto: l'istruzione NotFound non verrà mai chiamata, ma il suo messaggio corrispondente verrà stampato sulla console, non capisco come da quando in questo caso il programma non salta mai a questa etichetta "NotFound".

Per favore, se ora mi dai una mano su questo ...

Grazie

+10

grande esempio di 'goto' abuso – Andrey

+1

Si dovrebbe ristrutturare questo non utilizzare goto in ogni caso. Non è considerato una buona pratica in generale, quindi avrai un sacco di scuotimenti sulla revisione del codice, e tende a essere non mantenibile. Per essere sinceri c'è un inconfondibile odore di odore di codice che emana da questo. – Cruachan

risposta

7

Eww goto di, vorrei utilizzare e if/else affermazione, ma se avete bisogno di goto di:

Found: 
     Console.WriteLine("Numarul a fost gasit"); 
     goto End; 
    NotFound: 
    Console.WriteLine("Numarul nu a fost gasit !"); 
    End: 
    Console.ReadKey(); 
4

E 'essere chiamato perché il codice all'interno dell'etichetta Trovato ha nulla da costringerlo a saltare il codice int egli notfound etichetta (a meno che non chiami nuovamente goto, l'esecuzione ricadrà sull'etichetta anziché saltarla).

Detto questo, non utilizzare goto! Mi spingo fino a dire che è sempre una cattiva idea e può essere riscritta.

Nel tuo caso, è possibile aggiungere un semplice flag booleano per sbarazzarsi del vostro goto:

static void Main(string[] args) 
{ 
    int x = 10, y = 10; 
    bool isFound = false; 

    // Rest of the body 

    for(int i=0;i<x;i++) 
    { 
     for(int j=0;j<y;j++) 
     { 
      if(cautat.Equals(myArrayTable[i,j])) 
      { 
       isFound = true; 
       break; 
      } 
     } 

     if(isFound) 
      break; 
    } 

    if(isFound) 
     Console.WriteLine("Numarul a fost gasit"); 
    else 
     Console.WriteLine("Numarul nu a fost gasit!"); 

    Console.ReadKey(); 
} 
+1

Questa riscrittura cercherà sempre tutti gli elementi dell'array anche se l'elemento è già stato trovato. È possibile evitare ciò aggiungendo un test nel ciclo for oppure utilizzando Contains. –

+0

I Gotos sono considerati un'alternativa valida per il codice di ritorno dello stato in cui altri metodi sono troppo coinvolti e sciatti. Certamente in questo caso i gotos sono migliori di un booleano per uscire dal ciclo. – Novikov

+0

@ Marco Byers - Hai ragione. Stavo semplicemente rimuovendo il problema Goto. Ho aggiornato il mio esempio per uscire dai loop non appena viene trovato qualcosa (includerei l'esempio Contains, ma l'OP non dice mai che è in grado di usare Contains ... e tu te ne sei già occupato). –

1

perché basta saltare all'etichetta Trovato e procedere a cadere attraverso l'etichetta non trovato. Avresti bisogno di una terza etichetta chiamata EndFound e vai su di essa dopo averla trovata.

Found: 
    Console.WriteLine("Numarul a fost gasit"); 
    goto EndFound; 
NotFound: 
    Console.WriteLine("Numarul nu a fost gasit !"); 
EndFound: 
6

vorrei riscrivere il codice per evitare l'uso di goto:

string message; 
if (myArrayTable.Cast<string>().Contains(cautat)) { 
    message = "Found"; 
} else { 
    message = "Not found!"; 
} 
Console.WriteLine(message); 
0

Perché dopo aver saltato su Found, l'esecuzione continua semplicemente alla riga successiva, che sembra essere la linea di scrittura della console "non trovata". È necessario aggiungere ancora un altro goto per saltare sopra (o meglio ancora, riprogettarlo per evitare completamente il gotos)

È esattamente un problema come questo, che il gotos dovrebbe essere evitato.

1

se non si desidera eseguire le statistiche "Non trovato" se si eseguono le statistiche "Trovato", utilizzare un altro goto, per saltare la parte di NotFound. goto salta a una sezione, ma ciò non significa che la sezione non verrà eseguita se non viene saltata su un goto. Ricorda, il codice viene eseguito in un modo top-down, quindi, a meno che tu non salti in qualche modo su un peice di codice, verrà eseguito.

esempio:

Found: 
    Console.WriteLine("Numarul a fost gasit"); 

goto ReadKey; 

NotFound: 
    Console.WriteLine("Numarul nu a fost gasit !"); 

ReadKey: 
    Console.ReadKey(); 
Problemi correlati