2010-08-31 2 views
8

Ich studiere dieses Codebeispiel:Wie funktioniert die Anweisung in diesem Beispiel?

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(); 
    } 
} 

Ich verstehe nicht, warum die „nicht gefunden“ Anweisung aufgerufen und die entsprechende Meldung Druck auf Konsole, wenn ich eine Such Zahl wie 10, in diesem Fall gehe eingeben: Gefundene Anweisung wird ausgeführt, also wird goto: NotFound-Anweisung niemals aufgerufen, aber trotzdem wird die entsprechende Nachricht auf der Konsole ausgegeben, ich verstehe nicht, wie in diesem Fall das Programm niemals auf diese "NotFound" -Etikette springt.

Bitte, wenn Sie mir jetzt eine Hand darüber ...

Dank

+10

Groß Beispiel 'goto' Missbrauch – Andrey

+1

Sie wirklich diese Umstrukturierung sollte nicht gehe trotzdem zu verwenden. Es wird im Allgemeinen nicht als gute Übung angesehen, so dass Sie bei der Code-Überprüfung eine Menge Kopfschütteln erleiden werden, und es ist in der Regel nicht zu halten. Um ehrlich zu sein, gibt es einen unverwechselbaren Code-Geruch. – Cruachan

Antwort

7

Eww GOTOs, würde ich verwenden und if/else Aussage, aber wenn Sie GOTOs benötigen:

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

Es heißt, weil der Code innerhalb des Found-Label hat nichts zu erzwingen über den Code int überspringen er NOTFOUND label (es sei denn, Sie rufen goto erneut auf, wird die Ausführung durch das Label fallen und nicht übersprungen).

Das heißt, nicht goto verwenden! Ich gehe so weit zu sagen, dass es immer eine schlechte Idee ist und neu geschrieben werden kann.

In Ihrem Fall können Sie eine einfache Boolesche Flag, um loszuwerden Ihrer goto hinzu:

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

Diese Umschreibung wird immer alle Elemente im Array durchsuchen, auch wenn das Element bereits gefunden wurde. Sie können dies vermeiden, indem Sie einen Test in der for-Schleife hinzufügen oder indem Sie Contains verwenden. –

+0

Gotos gelten als eine brauchbare Alternative für Status-Return-Code, wo andere Methoden viel zu kompliziert und schlampig sind. Sicherlich sind in diesem Fall gotos besser als ein boolescher Wert zum Verlassen der Schleife. – Novikov

+0

@Mark Byers - Sie haben Recht. Ich entfernte einfach das Goto-Problem. Ich habe mein Beispiel aktualisiert, um aus den Schleifen auszubrechen, sobald etwas gefunden wird (ich würde das Enthält-Beispiel einschließen, aber das OP sagt nie, dass er Contains verwenden kann ... und Sie haben sich schon darum gekümmert). –

1

Weil Sie gerade zum Found Label springen und fahren bis zur Not Found Label fallen. Du brauchst ein drittes Label namens EndFound und gehst nach dem Fund zu ihm.

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

ich diesen Code neu schreiben würde die Verwendung von goto zu vermeiden:

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

Weil Nachdem es zu Found gesprungen ist, geht die Ausführung einfach weiter zur nächsten Zeile, die zufällig die "nicht gefunden" -Konsolen-Schreibleitung ist. Sie müssen noch ein weiteres goto hinzufügen, um darüber zu springen (oder noch besser, dies neu zu entwerfen, um die gotos völlig zu vermeiden)

Es ist genau so ein Problem, das GOTOS vermieden werden sollte.

1

Wenn Sie nicht möchten, dass die "Not Found" -Statements ausgeführt werden, wenn die "Found" -Statements ausgeführt werden, verwenden Sie ein anderes Goto, um den NotFound-Teil zu überspringen. gehe zu einem Abschnitt, aber das bedeutet nicht, dass der Abschnitt nicht ausgeführt wird, wenn er nicht über einen Goto angesprungen wird. Denken Sie daran, dass der Code in einer Top-Down-Version ausgeführt wird. Wenn Sie also nicht einen Teil des Codes überspringen, wird er ausgeführt.

Beispiel:

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

goto ReadKey; 

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

ReadKey: 
    Console.ReadKey();