how GOTO works in c# [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a for loop in c# winform and I want to start for loop again if i=7
The code looks like this :
for (int i = 0; i < 10; i++)
{
if (i==7)
{
MessageBox.Show("you must start for loop again ");
//here I want to go back to for loop again
}
}
any ideas ?
also,I know this code makes no sense, I just wrote it for example — I have similar situation in my c# code.

In this case, just mutate i back to 0, like so:
for (int i = 0; i < 10; i++)
{
if (i==7)
{
MessageBox.Show("you must start for loop again ");
i = 0;
}
}
If you really want to use goto, then here is an example for that:
BackToTheStart:
for (int i = 0; i < 10; i++)
{
if (i==7)
{
MessageBox.Show("you must start for loop again ");
goto BackToTheStart;
}
}
It's worth keeping in mind if you didn't already know, goto is generally considered bad practice and an unwelcome legacy baggage C# brought from C style languages of yesteryear. In most cases you do not need it, like in this example, it's easier not to use it. And, most importantly, no one will ever thank you for adding a goto.

It's worth noting that this would be an infinite loop. Think about it: if you go back to 0 every time i reaches 7, how would it ever bet the case that i == 10? How would you break out of the loop? This may be a case of the XY problem - i.e. you probably don't actually want to do what you say you want to do here.
If you really want this to occur in an infinite loop, just do this:
while (true) {
for (int i = 0; i <= 7; i++) {
if (i == 7) {
// ..
}
}
}
Actually, I'm slightly baffled as to why you bother with the "for" loop at all in this case if you're only doing something in the case where i = 7; why bother with the for loop at all and just put the action in an infinite loop?
Also, if you're doing this on the UI thread, it'll appear to "hang" the UI because the UI thread won't ever be able to do anything other than service your for loop. Users won't even be able to close it normally.
Finally, as other people have pointed out, never use goto, it's a bad practice - Microsoft shouldn't have even included it in the language.

Related

How is Brainfuck interpereting loops that makes this code work?

This might sound stupid, but i need help with brainfuck.
so im writing an interpreter in c#, and I tried to use my interpreter on a real piece of code (+[----->+++<]>+.+.) which should print "hi".
But the while loop never ends, because the first value never gets back to zero, which makes sense, since at the end of each loop the first value should never be 0, since it's only going down, and 1 is not divisible by -5, so why does this code work in other interpreters, whats the logic that would make this actually work in brainfuck.
I'm not asking whats wrong with my interpreter, I'm asking how brainfuck would actually interpret this code, so I can implement it into mine. Because I'm not trying to figure out why this doesn't work in my interpreter, I'm trying to figure out why this code should work in the first place, that way I can optimize my interpreter for more cases.
After some tinkering of the code, and analyzing the values in other interpreters I found that the integers have limits and minimums, which allow it to function. I turned my interpreters code to this to account for them:
if (s == "+")
{
values[pos] += 1;
if (values[pos] > max) { values[pos] = min; }
}
if (s == "-")
{
values[pos] -= 1;
if (values[pos] < min) { values[pos] = max; }
}
Which fixed my main issue.

Why doesn't my code increase a variable everytime? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I am trying to make a code that loops through random numbers until it gets a six(this part is working) and then if you rolled a six in less than 6 tries but my code won't up my "amountOfMoney" variable if you get it in less than six. All it outputs is one even if you get under 6 two times in row. Here is the code:
class Program
{
static void Main(string[] args)
{
Start:
int attempt = 0;
int numberOfAttempts = 0;
int amountOfMoney = 0;
Random numberGen = new Random();
while (attempt != 6)
{
attempt = numberGen.Next(1, 7);
Console.WriteLine("Tom rolled: " + attempt + ".");
numberOfAttempts++;
}
Console.WriteLine("It took tom " + numberOfAttempts + " attempts to roll a six");
if(numberOfAttempts <= 6)
{
amountOfMoney++;
Console.WriteLine("You now have " + amountOfMoney + " dollars");
}
if(numberOfAttempts > 6)
{
amountOfMoney--;
Console.WriteLine("You now have " + amountOfMoney + " dollars");
}
Console.ReadKey();
goto Start;
}
}
You should be using the tools available to you to solve this (i.e the debugger), but it seems like you are new so I will risk the downvotes in an attempt to help you...
The code you have is pretty close to what you need. However the problem you have is a combination of using goto, and not understanding variable scope.
Let me be very clear: goto is very bad practice
When this line is hit:
goto Start;
It goes to the very top of your Main() method, the next 3 lines declare your variables and set them to 0. Thats why you are never able to persist the values.
You need to remove the goto and utilize a loop like you are already doing. Then put the variables you want to persist across loop iterations outside the scope of your new loop:
int amountOfMoney = 0;
while(someCondition)
{
//game logic here
amountOfMoney++;
}
//amountOfMoney has not reset every loop and now has all the changes you made to it
Console.WriteLine(amountOfMoney);
With your new loops you need to come up with an exit condition though. Is it a user's input that exits the loop (and the game), is it a fixed number of loops (use a for loop). That is up to you...
I made a simple "coin-flip" game here so you can see an example of what I am talking about. Doing the work for you wont help you learn but this should be more than enough to contextualize things for you.
I'm answering because this is actually an awesome teachable moment. What you have provided is one of the simplest examples of a very common design issue, an uncontextualized neologism. This label:
Start:
...seems innocent enough. But in the programming world, things are actually very, very, specific, and this label is nowhere near specific enough. What exactly is starting?
Whoever wrote this code...
int attempt = 0;
int numberOfAttempts = 0;
int amountOfMoney = 0;
...thought it was the start of the game.
Whoever wrote this code...
goto Start;
...thought it was the start of the round.
To fix this, make the label more specific, and put it in the right place.
P.S. Also, don't use goto and come up with an exit condition. But I think those lessons are less valuable.

In C families, in a loop why is "less than or equal to" more preferred over just "less than" symbol? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Why is it that in C family of languages when we use a counter for any loop the most preferred comparison is Greater Equal To <= or its inverse? Please take a look at these three pieces of code
for (var i = 0; i <= 5; i++)
{...}/// loop1
for (var i = 0; i < 6; i++)
{...}/// loop2
for (var i = 0; i != 6; i++)
{...}/// loop3
I understand why loop 3 should be discouraged as something in code can assign i > 5 causing infinite loop. But loop1 and loop2 are essentially the same and loop2 may be better performance wise since only one comparison is done. So why is loop1 more preferred. Is it just convention or is there something more to it?
Note: I have no formal training in programming. i just picked up C when I needed better tools to program 8051s rather than using assembly language.
For loops are often used to iterate over arrays, and the limit is the length of the array. Since arrays are zero-based, the last valid element is length-1. So the choice is between:
for (int i = 0; i < length; i++)
and
for (int i = 0; i <= length-1; i++)
The first is simpler, so it is preferred. As a result, this idiom has become common even when the limit is not an array size.
We don't use != because occasionally we write loops where the index increments by variable steps, and sometimes it will skip over the limit. So it's safer to use a < comparison, so these won't turn into infinite loops.
This is generally a matter of contextual semantics, facilitating 'those that come after you' to maintain the code.
If you need 10 iterations of something, this is usually written as starting from 0 and having an end condition with < or != because it means the 10 is literally part of the code, thus showing clearly that 10 iterations were intended. The non-inclusive notation is also more practical for zero-based arrays like C-style strings. Notation with != is generally discouraged because it can cause endless loops in case the indexer isn't just a straightforward increment, unexpected overflows occur or the like.
On the other hand, if you need a loop from and to a specific value, it's also clearer if you have the end condition literally in the code, for example with for(var i = 1; i <= 5; i++) it is clear right away that it's an inclusive loop from 1 to 5.
These are just common reasons cited for using one notation or the other, most good programmers decide which to use by context and situation. There is no reason performance- or otherwise to prefer one over the other.
Less than or equal to is not preferred. Traditionally, in C,
less than was preferred; in C++, not equals is by far the most
idiomatic. Thus, in C:
#define N 100
int array[N];
for ( int i = 0; i < N; i ++ ) {
// ...
}
and in C++, either:
int const N = 100;
int array[N];
for ( int i = 0; i != N; ++ i ) {
// ...
}
or even more often, if there is only one container, and the
index isn't needed otherwise:
for ( int* p = std::begin( array ); p != std::end( array ); ++ p ) {
// ...
}
(In pre-C++11, of course, we used our own implementations of
begin and end to do the same thing.)
Other forms are generally not idiomatic, and are only used in
exceptional cases.
Almost all for loops have the exact same header except for the upper bound. It is a useful convention that helps with quick understanding and making less mistakes. (And the convention is <, not <=. Not sure where you got that from.)
Programs that do the same thing are not necessarily equal when it comes to code quality. Coding style has an objective component to it in that it helps humans deal with the complexity of the task.
Consistency is an important goal. If you have the choice, prefer the alternative that the majority of team members is using.

Is It Ever Good Practice To Modify The Index Variable Inside a FOR Loop?

Given the code:
for (int i = 1; i <= 5; i++)
{
// Do work
}
Is is ever acceptable to change the value of i from within the loop?
For example:
for (int i = 1; i <= 5; i++)
{
if( i == 2)
{
i = 4;
}
// Do work
}
In my opinion, it is too confusing. Better use a while loop in such case.
It is acceptable, however, I personally think this should be avoided. Since it's creating code that will be unexpected by most developers, I find that it's causing something much less maintainable.
Personally, if you need to do this, I would recommend switching to a while loop:
int i=1;
while (i <= 5)
{
if (i == 2)
i = 4;
++i;
}
This, at least, warns people that you're using non-standard logic.
Alternatively, if you're just trying to skip elements, use continue:
for (int i = 1; i <= 5; i++)
{
if (i == 2 || i == 3)
continue;
}
While this is, technically, a few more operations than just setting i directly, it will make more sense to other developers...
YES
You see that frequently in apps that parse data. For example, suppose I'm scanning a binary file, and I'm basically looking for certain data structures. I might have code that does the following:
int SizeOfInterestingSpot = 4;
int InterestingSpotCount = 0;
for (int currentSpot = 0; currentSpot < endOfFile; currentSpot++)
{
if (IsInterestingPart(file[currentSpot])
{
InterestingSpotCount++;
//I know that I have one of what I need ,and further, that this structure in the file takes 20 bytes, so...
currentSpot += SizeOfInterestingSpot-1; //Skip the rest of that structure.
}
}
An example would be deleting items which match some criteria:
for (int i = 0; i < array.size(); /*nothing*/)
{
if (pred(array[i]))
i++;
else
array.erase(array.begin() + i);
}
However a better idea would be using iterators:
for (auto it = array.begin(); it != array.end(); /*nothing*/)
{
if (pred(*it))
++it;
else
it = array.erase(it);
}
EDIT
Oh sorry, my code is C++, and the question is about C#. But nevertheless the idea is the same:
for (int i = 0; i < list.Length; /*nothing*/)
{
if (pred(list[i]))
i++;
else
list.RemoveAt(i);
}
And a better idea might be of course just
list.RemoveAll(x => !pred(x));
Or in a slightly more modern style,
list = list.Where(pred);
(here list should be IEnumerable<...>)
I would say yes, but only in a specific cases.
It may be a bit confusing - if I set i=4 will it be incremented before the next iteration or not?
It may be a sign of a code smell - maybe you should do a LINQ query before and only process relevant elements?
Use with care!
Yes it can be. As there are an extremely enormous amount of possible situations, you're bound to find one exception where it would be considered good practice.
But stopping the theoretica lside of things, i'd say: no. Don't do it.
It gets quite complicated, and hard to read and/or follow. I would rather see something like the continue statement, although i'm not a big fan of that either.
Personally, I would say that if the logic of the algorithm called for a normally-linearly-iterating behavior, but skipping or repeating certain iterations, go for it. However, I also agree with most people that this is not normal for loop usage, so were I in your shoes, I'd make sure to throw in a line or two of comments stating WHY this is happening.
A perfectly valid use case for such a thing might be to parse a roman numeral string. For each character index in the string, look at that character and the next one. If the next character's numeric value is greater than the current character, subtract the current character's value from the next one's, add the result to the total, and skip the next char by incrementing the current index. Otherwise, just add the current character's value to the running total and continue.
An example could be a for loop where you want in a certain condition to repeat current iteration or go back to a previous iteration or even skip a certain amount of iterations (instead of a numered continue).
But these cases are rare. And even for these cases, consider that the for loop is just one means among while, do and other tools that can be used. so consider this as bad practice and try to avoid it. your code will also be less readable that way.
So for conclusion: It's achievable (not in a foreach) but strive to avoid this using while and do etc. instead.
Quoting Petar Minchev:
In my opinion, it is too confusing.
Better use a while loop in such case.
And I would say by doing that, you must be aware of some things that could happen, such as infinite loops, premature-canceled loops, weird variable values or maths when they are based on your index, and mainly (not excluding any of the others) execution flow problems based on your index and other variabes modified by the fail loop.
But if you got such a case, go for it.

Changing variables outside of Scope C#

I'm a beginner C# programmer, and to improve my skills I decided to give Project Euler a try. The first problem on the site asks you to find the sum of all the multiples of 3 and 5 under 1000. Since I'm essentially doing the same thing twice, I made a method to multiply a base number incrementally, and add the sum of all the answers togethor.
public static int SumOfMultiplication(int Base, int limit)
{
bool Escape = false;
for (int mult = 1; Escape == true; mult++)
{
int Number = 0;
int iSum = 0;
Number = Base * mult;
if (Number > limit)
return iSum;
else
iSum = iSum + Number;
}
regardless of what I put in for both parameters, it ALWAYS returns zero. I'm 99% sure it has something to do with the scope of the variables, but I have no clue how to fix it. All help is appreciated.
Thanks in advance,
Sam
Your loop never actually executes:
bool Escape = false;
for (int mult = 1; Escape == true; mult++)
Escape is set to false initially, so the first test fails (Escape == true returns false) and the body of the loop is skipped.
The compiler would have told you if you were trying to access variables outside of their defined scope, so that's not the problem. You are also missing a return statement, but that is probably a typo.
I would also note that your code never checks if the number to be added to the sum is actually a multiple of 3 or 5. There are other issues as well (for example, iSum is declared inside of the loop and initialized to 0 after each iteration), but I'll let you work that one out since this is practice. The debugger is your friend in cases like these :)
EDIT: If you need help with the actual logic I'll be happy to help, but I figure you want to work it out on your own if possible.
As others have pointed out, the problem is that the control flow does not do what you think it does. This is a common beginner problem.
My suggestion to you is learn how to use your debugger. Beginners often have this strange idea that they're not allowed to use tools to solve their coding problems; that rather, they have to reason out the defect in the program by simply reading it. Once the programs become more than a page long, that becomes impossible for humans. The debugger is your best friend, so get to know its features really well.
In this case if you'd stepped through the code in the debugger you'd see that the loop condition was being evaluated and then the loop was being skipped. At that point you wouldn't be asking "why does this return zero?", you'd be asking "why is the loop body always skipped?" Clearly that is a much more productive question to ask since that is actually the problem here.
Don't write any code without stepping through it in the debugger. Watch every variable, watch how it changes value (the debugger highlights variables in the watch windows right after they change value, by the way) and make sure that the control flow and the variable changes are exactly as you'd expect. Pay attention to quiet doubts; if anything seems out of the ordinary, track it down, and either learn why it is correct, or fix it until it is.
Regarding the actual problem: remember that 15, 30, 45, 60... are all multiples of both three and five, but you only want to add them to the sum once. My advice when solving Project Euler problems is to write code that is as like what you are trying to solve as is possible. Try writing the problem out in "pseudocode" first. I'd pseudocode this as:
sum = 0
for each positive number under 1000:
if number is multiple of three or five then:
add number to sum
Once you have that pseudocode you can notice its subtleties. Like, is 1000 included? Does the problem say "under 1000" or "up to 1000"? Make sure your loop condition considers that. And so on.
The closer the program reads like the problem actually being solved, the more likely it is to be correct.
It does not enter for loop because for condition is false.
Escape == true
returns false
Advice:
Using for loop is much simpler if you use condition as limit for breaking loop
for (int mult = 1; something < limit; mult++)
This way in most cases you do not need to check condition in loop
Most programming languages have have operator modulo division.
http://en.wikipedia.org/wiki/Modulo_operation
It might come handy whit this problem.
There are several problems with this code. The first, and most important, is that you are using the Escape variable only once. It is never set to false within your for loop, so it serves no purpose whatsoever. It should be removed. Second, isum is declared within your for loop, which means it will keep being re-initialized to 0 every time the loop executes. This means you will only get the last multiple, not the addition of all multiples. Here is a corrected code sample:
int iSum = 0;
for(int mult = 1; true; mult++)
{
int Number = Base * mult;
if(Number > limit)
return iSum;
else
iSum += Number;
}

Categories

Resources