tags:

views:

117

answers:

6

Hi,

I am studying this code sample:

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

I do not understand why the "Not Found" statement was called and its corresponding message print on console if i enter a seek number like 10, in this case goto: Found statement is executing, so goto: NotFound statement will never be called, but still its corresponding message is printed on console, i do not understand how since in this case program never jumps to this "NotFound" label.

Please if you now give me a hand about this...

Thanks

+2  A: 

It's being called because your code inside of the Found label has nothing to force it to skip over the code int he NotFound label (unless you call goto again, the execution will fall through the label rather than skip it).

That being said, don't use goto! I'll go as far to say that it's always a bad idea and can be re-written.

In your case, you can add a simple boolean flag to get rid of your 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();
}
Justin Niessner
This rewrite will always search all elements in the array even if the element has already been found. You could avoid this by adding a test in the for loop, or by using Contains.
Mark Byers
Gotos are considered a viable alternative for status returning code where other methods are far too involved and sloppy. Certainly in this case gotos are better than having a boolean for exiting the loop.
Novikov
@Mark Byers - You're right. I was simply removing the Goto issue. I updated my example to break out of the loops as soon as something is found (I would include the Contains example, but the OP never says he's able to use Contains...and you already took care of that one).
Justin Niessner
@Nokikov, I would certainly not consider `goto` a viable option in this case. If you don't want to use booleans for exiting the loop, there's always Mark's method or an alternate solution of making this a function and doing an early return.
Anthony Pegram
@Nokikov - I agree with @Anthony. In no way, shape, or form is a goto a viable option in this case.
Justin Niessner
Or you could do the check in the first set of double for loops, and just omit the second set (and keep the isFound=true without the break like you had). Since the first double for loop sets up the `myArrayTable`, you could also throw in the check there.
SwDevMan81
+1  A: 

Because you just jump to the Found label and proceed to fall through to the Not Found label. You'd need a third label called EndFound and go to it after found.

Found: 
    Console.WriteLine("Numarul a fost gasit");
    goto EndFound;
NotFound:
    Console.WriteLine("Numarul nu a fost gasit !");
EndFound:
Novikov
+4  A: 

Eww goto's, I would use and if/else statement, but if you need goto's:

    Found: 
      Console.WriteLine("Numarul a fost gasit");
      goto End;
    NotFound:
     Console.WriteLine("Numarul nu a fost gasit !");
    End:
    Console.ReadKey();
SwDevMan81
+6  A: 

I would rewrite this code to avoid the use of goto:

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

Because after it jump to Found, execution just continues to the next line, which happens to be the "not found" console write line. You need to add yet another goto to jump over that (or better yet, redesign this to avoid the gotos entirely)

It is exactly problem like this, that gotos should be avoided.

James Curran
+1  A: 

if you don't want the "Not Found" statments to execute if the "Found" statments execute, use another goto, to skip the NotFound portion. goto jumpts to a section, but that doesn't mean the section won't be executed if it is not jumped to via a goto. Remember, the code executes in a top down fasion, so unless you somehow skip over a peice of code, it will execute.

example:

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

goto ReadKey;

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

ReadKey:
    Console.ReadKey(); 
Jeremy