I have a loop with an index. But the index jumps up and down from time to time, so a for loop is out of the question. But I still need the index. I just don't like the idea of having a temporary index in my function which I am only using for one loop. e.g.
...
int i = 0;
while( i < something)
{
if(a)
i++:
else
i--:
}
...
Can I make i temporary for the loop? Maybe something like this?
...
temporary (int i = 0)
{
while( i < something)
{
if(a)
i++:
else
i--:
}
}
...
You can use the for loop in order to achieve this. the variable i will live only inside the for loop scope.
for (int i = 0; i < something;;)
{
if(a)
i++:
else
i--:
}
}
You can limit the range of a variable by enclosing its declaration and its use within curly braces. It looks a litte bit strange, but it works fine.
Then your i variable can't be accessed outside of this scope as shown below (you will get a compilation error) :
MyMethod()
{
// ... lots of code here
{
int i=0;
while( i < something)
{
if(a)
i++;
else
i--;
}
i--; // ok
}
i--; // error : The name 'i' does not exist in the current context
// ... some more code here
}
Related
I'm trying to find out if a number is prime or not. But I've got an error of "unreachable code detected", which I think is effecting the error of "not all code paths return a value". The error seems to occur in the for loop at i++. Can anyone help me please?
static void Main(string[] args)
{
Console.WriteLine(isPrime(10));
}
public static bool isPrime(int n)
{
for (int i = 2; i < n; i++)
{
if (n % i == 0)
{
return false;
}
return true;
}
}
"Unreachable code detected" means that some code can never be executed. Consider:
int something()
{
if (true)
return 1;
else
return 2; //Obviously we can never get here
}
"Not all code paths return a value" means that you've defined a method with a return value (like "bool" in your example) and there is some way for the method to execute without returning a value.
Consider:
int something(bool someBool)
{
if (someBool)
return 1;
//if someBool == false, then we're not returning anything. Error!
}
Your code has two problems:
You have return true inside the for loop (outside of any conditional). Because return immediately exits the function (returning control to the caller) the i++ statement of the for loop will never get executed (hence your bug). You likely intended for that to be outside the for loop.
Another problem with that being in the loop is that the loop is not guaranteed to execute. If the n passed was 2 or less, you would skip the loop entirely, and there is no return statement in that case. This isn't allowed (since you always need to return a value from a non-void function) so you get a compiler error.
Below is an example of how to get this return working with a for loop and embedded If condition.
private bool WinOneLevelOne()
{
//For loop to check all the items in the winOne array.
for (int i = 0; i < winOne.Length; i++)
{
//If statement to verify that all the gameobjects in the array are yellow.
if (winOne[i].gameObject.GetComponent<MeshRenderer>().material.color != Color.yellow)
{
//Keeps the boolean at false if all the gameobjects are not yellow.
return false;
}
}
return true;
As we all know, most for loops take on this form:
for (int i = 0; i < whatever; i++)
{
//do stuff
}
I am writing a method at the moment where it is not appropriate to include "i++" as in the format above because i is being updated in a loop nested within this loop. So for now, I have this:
List<Item> itemList = new List<Item>();
PopulateListOfItems(itemList);
List<List<Item>> itemSubListList = new List<List<Item>>();
for (int i = 0; i < itemList.Count; //i doesn't need updating here)
{
List<Item> subList = new List<Item>();
for (int j = 0; j < subListSize && i < itemList.Count; j++)
{
subList.Add(itemList[i++]);
}
itemSubListList.Add(subList;
}
Is there a standard way to write such a loop, perhaps including some sort of dummy code where i++ would normally go to make it clear no update is needed? Perhaps something like...
for (int i = 0; i < whatever; true)
{
//do stuff
}
... or am I just at the end of a long week and my brain is too fried to realize I really should just be using a while loop or something?
By the way, I've written this in C#, yes, but this can apply to a variety of languages.
Just omit it:
for (int i = 0; i < whatever; )
{
//do stuff
}
In fact, all parts of the for-loop are optional (in C# at least, this may not be the same for all C-like languages). The following creates an infinite loop:
for (;;)
{
//do stuff
}
Of course, you could also accomplish this with a while-loop, as the other answers have suggested. Both solutions are perfectly valid and which one you choose is mostly a matter of style. In general, you should pick the solution which you find most clearly communicates to the reader what the code is trying to do.
Just use a while loop instead of a for loop.
var i = 0;
while (i < whatever)
{
// Do stuff including updating i.
}
The for loop construct is just syntactic sugar for a while loop, and all for loops decompose into while loops.
for(int i = 0; i < whatever; i++)
{
//do stuff
}
ultimately means:
{
int i = 0;
while(i < whatever)
{
//do stuff
i++;
}
}
(note the additional curly braces for scoping of the integer)
Any parts of the for loop that you omit are also omitted from the decomposed while loop and thus you have to handle them manually. If you don't use all three parts, you really may as well just write a while loop (especially if one of the parts you omitted was the variable initializer, because of the variable scope I mentioned).
Is there an equivalent method of performing the job of redo in C#? i.e. going back to the top of the loop and re-execute without checking conditions or increasing the loop counter. Thanks.
for (int i = 0; i < 100; i++)
{
do
{
DoYourStuff();
} while (ShouldWeDoThatAgain());
}
Do...while is like a standard while loop, except instead of checking its conditional before each iteration, it checks after. That way, the code inside the loop will always execute at least once. Stick that inside a for or foreach loop, and that should get you the behavior your want. This is a bit simpler than Simon's answer, as it doesn't require an extra variable, doesn't use continue, and doesn't mess with the loop counter at all.
Why not simply:
Although goto is not really everyone's favourite, it's quite readable in this case...
for(...)
{
redo:
//...
if (...)
goto redo;
}
No. The closest you'll get is something like this:
bool redoCalled = false:
for (int i = 0; i < 10; i++) {
if (redoCalled) {
i--;
redoCalled = false;
}
// other stuff here
if (redoWanted) {
redoCalled = true;
continue;
}
}
I want to make a loop using an already-defined iterator.
At present I am using
int i;
while (i<10)
{
Console.Writeline(i);
i++;
}
This is ugly because someone else might later remove the i++. If it is separated from the while statement by a large block of code, it will not be clear what it is for.
What I'd really like is something like
int i;
for (i<10; i++)
{
Console.Writeline(i);
}
This makes it clear what's going on, but it's not valid C#.
The best I've come up with so far is
int i;
for (int z; i<10; i++)
{
Console.Writeline(i);
}
But that's ugly. Does C# give me an elegant way of doing it?
Well, you don't have to have anything inside the first part of the loop:
for (; i < 10; i++)
{
Console.WriteLine(i);
}
Is that what you're looking for? Personally I would typically try to avoid this sort of situation anyway though - I find it pretty unusual to want a loop without a new variable.
Just use an empty first part of the "for":
int i;
for (; i<10; i++)
{
Console.Writeline(i);
}
You can also assign the variable to itself in the first part of the loop like this:
int i;
for (i=i; i<10; i++)
{
Console.Writeline(i);
}
I find that it's slightly clearer than leaving the first part of the loop blank, however Visual Studio will give you a warning "Assignment made to the same variable; did you mean to assign it to something else?"
I am writing a for loop with multiple if statements.
Is it possible that if the if statement (or one part of it) in the for statement evaluates to false, then the loop does not exit but the integer to iterates increments by one and continues through the loop (I need functionality like the continue; keyword).
Example:
for (int i = 0; i <= Collection.Count && Collection[i].Name != "Alan"; i++)
{
// If name is not Alan, increment i and continue the loop.
}
Is this possible?
Thanks
You need functionality like the continue keyword - have you considered using the continue keyword, then?
Update: Your example code is hard to decipher the intention of.
for (int i = 0; i <= Collection.Count && Collection[i].Name != "Alan"; i++)
{
// If name is not Alan, increment i.
}
The for loop has three parts to it, separated by two semi-colons. The first part initializes the loop variable(s). The second part is an expression that is evaluated each time an iteration is about to start; if it is false, the loop terminates. The third part executes after each iteration.
So your loop above will exit at the first "Alan" it encounters, and also it will increment i every time it finishes an iteration. Finally, if there are no Alans, it will execute the last time with i equal to Collection.Count, which is one larger than the maximum valid index into the collection. So it will throw an exception for sure, as you try to access Collection[i] when i is out of range.
Maybe you want this:
foreach (var item in Collection.Where(i => i.Name != "Alan"))
{
// item is not an "Alan"
}
You can think of the Where extension method as a way of filtering a collection.
If this seems obscure, you can achieve the same thing with the continue keyword (as you guessed):
foreach (var item in Collection)
{
if (item.Name == "Alan")
continue;
// item is not an "Alan"
}
Or you can just put the code in the if's block:
foreach (var item in Collection)
{
if (item.Name != "Alan")
{
// item is not an "Alan"
}
}
Do you mean like this?
for (int i = 0; i < 100; ) {
if (!condition1) {
i++;
}
if (!condition2) {
i++;
}
if (!condition3) {
i++;
}
}
Do you want the incrementor for finishing the for loop to be in the body of the loop?
I am not sure I understand correctly. You have a for loop something like this
for (int i = 0; i < 10; i++)
{
// do something
if (!b1)
i++
// do something
}
Edit:
If you use continue it increments i for only once. If you use i++ in loop it increments twice obviously. If you only want to icrement on a condition, Use the for loop like this
for (int i = 0; i < 10) // and this is very similar to a while loop.
From your sample code, I think you are searching for the name "Alan".
Is this correct?
If so, structure your loop like:
for (int i = 0; i < Collection.Count; i++)
{
if (Collection[i].Name == "Alan")
{
break; // We found the name we wanted!
}
// Otherwise: Keep going to look for the name further on.
}
if (i == Collection.Count)
{
Console.WriteLine("Alan is not found");
}
else
{
Console.WriteLine("Alan found at position {0}", i);
}