For Loop Expression Syntax Wrong - c#

What is wrong with the following for loop syntax the crv variable is an array and I want an increment of 2:
for(int i<0; i<crv.Count;i+2)
{
//Code Here
}
My compiler only says Semicolon expected which is not a very useful feedback...

You need to start out initializing i to zero, not comparing it to zero. Additionally your last statement doesn't actually change i, it just returns a value of i+2 and does nothing with that value, you need to actually set i to that result.
for(int i = 0; i < crv.Count;i+=2)
{
//Code Here
}

The biggest error is that i+2 is not reassigned to i.
for(int i = 0; i<crv.Count;i = i+2)
{
//Code Here
}
You are throwing away the increment and i never changes value.
Then, you are not initializing i but checking whether it is less than 0.

Please note: first section is assignment You can't use comparison as int i<0;, instead it should be int i=0 or int i = -10 or anything similar as required.
Also in the increment section, either assign the updated value back to i
for(int i =0; i<crv.Count; i+=2)
{
//Code Here
}
or do the same in the body (just mentioning the option, which is useful in some specific scenarios)
for(int i =0; i<crv.Count;)
{
//Code Here
i+=2;
}

While most of these answers do tell you how to fix your code they don't tell you why it doesn't work which I think is important for you to understand.
a for loop consists of three parts, separated by semicolons.
for(part1;part2;part3)
part1 is executed only once - when the execution of the loop first begins. (this is normally where you assign an initial value to your counter)
part2 is then executed next, checking if its value is true or false.
If is true, then the body of the loop is executed
Then part3 is executed, (as you're attempting to do) this is normally where you increment
Then part2 is checked again, if its true, it goes through the process again, if its false it exists the loop

The first part of the for loop decides on i's initial value. in your example, you have "<", which isn't a solid value. Try i=0 instead. also, the last part reads as i, in addition to 2, instead of adding two each iteration. try i+=2 instead.

Related

Is using a math class method in a loop condition slow?

if i have a for loop for example and and i want to use something like Math.round() to round the number but i only need to round the number one time(i.e the number doesn't change throughout the loop) is it better to store it into a variable and then use the variable to in the condition or does it not matter?
for (int i = 0;i < Math.Round(x);i++)
{
//Some code
}
vs
for (int i = 0,roundedX = Math.Round(X); i<roundedX;i++)
{
//Some code
}
The compiler will evaluate the termination condition on every loop iteration.
The compiler and the JITter might hoist some expression or part of an expression outside the loop if it deems it is invariant, meaning it doesn't change. This, however, is usually only done with simpler expressions.
If the Math.Round(X) expression could've been done without an actual method call then perhaps but in this particular case the rounding will happen on each loop iteration.
As such, if you're at last line defense for performance problems, you might consider moving this out and into a variable:
int goal = (int)Math.Round(X);
for (int i = 0; i < goal; i++)
...
As this will call the Math.Round method only once, you only get the performance hit once.
Note that if X changes as part of the loop, then obviously you want to keep your original code.
I would suggest defining a variable
var roundedX = Math.Round(X);
for (int i = 0; i < roundedX; i++)
{
//Some code
}

Why do these errors appear? c# - hangman game

I'm fairly new to coding (especially c#) - this is an assignment for a programming fundamentals class - I'm not looking for the answer - I'm looking for someone to explain why I get these two 'error's for a boolean method I'm supposed to create to check if the user's guess for a letter or the full word in a game of hangman.
The errors I get are - 'Unreachable Code detected - for the idx++ part - which doesn't make sense as I've used it in other separate methods..
And Program.CheckGuess(char[], char[], char[], string: not all code paths return a value.
I know I'm not fully finished the aspect. It's probably staring at me in the face - just looking for some guidance. Thanks.
static bool CheckGuess(char[] secrets, char[] mask, char[] letters, string guess)
{
int misses = 0; bool condition = false;
for (int idx = 0; idx < secret.Length; idx++)
{
guess.ToCharArray();
if (mask[idx] == guess[idx])
{
//reveal character or word
condition = true;
}
else
{
misses = misses + 1;
condition = false;
}
return condition;
}
}
You should understand that a return statement, when executed, makes the control jump out of the method and back to the caller.
In your code, your return is statement is placed inside the for loop. When an iteration of the for loop is executed, the control jumps out of the method immediately and goes back to the caller of the method.
As you know, the last part in a for loop header (idx++) is executed when an iteration has finished executing. However, in your case, an iteration will never finish because it just jumps back to the caller when control reaches return. This is why the first error occurred.
You should also understand that every method which doesn't have void as the return type needs to return no matter what.
So what if the for loop's condition (the middle part) is never true? The for loop will never be executed, right? If the for loop isn't executed, then what should the method return?
The error says that not all code path returns a value because the method would not return if the for loop isn't executed.
To fix this, you just need to move the return statement out of the for loop:
static bool CheckGuess(char[] secrets, char[] mask, char[] letters, string guess)
{
int misses = 0; bool condition = false;
for (int idx = 0; idx < secret.Length; idx++)
{
guess.ToCharArray();
if (mask[idx] == guess[idx])
{
//reveal character or word
condition = true;
}
else
{
misses = misses + 1;
condition = false;
}
}
return condition;
}
Because you have a return statement.
When this return inside your for loop is reached, the program jumps out of the loop and thus makes you i++ unreachable.

Loop does not iterate properly when exited

My XNA program has a while loop (originally a for loop that had the same problem which I changed to allow cleaner exiting) that is supposed to loop through an array of class unitTank, find the first null entry and create a new object at that position, like so:
public void createBlueTank(float X, float Y)
{
Boolean done = false;
int i = 0;
while (i < blueTank.Length - 1 && done == false)
{
if (blueTank[i] == null)
{
blueTank[i] = new unitTank(0, new Vector2(X, Y), this);
done = true;
}
i++;
}
}
blueTank's creation method works fine (I have checked), the issue here is that if the loop includes any code that allows it to exit in any way, the prior code in the iteration doesn't get implemented. That is, if I remove the done = true; (or the break in the original for loop) then the loop creates a new unitTank for each null value in array blueTank in the manner intended, but if I change it to exit the loop after the first time this is done, it doesn't happen at all.
Additionally, I have noticed that if I change all the references to i inside the if statement after the check that blueTank[i] is null to i+2 (because within the testing environment indexes 0 and 1 are defined, but 2 onwards are not); or if I change the initialisation of i to int i = 2, then the loop works as expected. Is this an issue with the if statement erroneously reading blueTank[0] as null, but the assignment statement not overwriting the existing instance inside that index, and then the loop getting cancelled before it ever reaches a truly null index? If so, why is this happening?
Is this an issue with the if statement erroneously reading blueTank[0] as null, but the assignment statement not overwriting the existing instance inside that index,
I think that it makes perfect sense that either blueTank[0] or bluetank[1] actually is null at that time. Put a break-point in the debugger and you should be able to see which values are null
How to use the debugger
So just to rule out a simple typo as being the problem... you are saying that this for loop doesn't work?
for (var i = 0; i < blueTank.Length; i++)
{
if (blueTank[i] == null)
{
blueTank[i] = new unitTank(0, new Vector2(X, Y), this);
break;
}
}

Does for loop count elements added into itself during the loop?

My question is, that when I loop through a list with for loop, and add elements to it during this, does it count the elements added while looping?
Simple code example:
for (int i = 0; i < listOfIds.Count(); i++) // Does loop counts the items added below?
{
foreach (var post in this.Collection)
{
if (post.ResponsePostID == listOfIds.ElementAt(i))
{
listOfIds.Add(post.PostId); // I add new item to list in here
}
}
}
I hope my explanation is good enough for you to understand what my question is.
Yes, it usually does. But changing a collection at the same time you're iterating over it can lead to weird behavior and hard-to-find bugs. It isn't recommended at all.
If you want this loop run only for preAdded item count then do this
int nLstCount = listOfIds.Count();
for (int i = 0; i < nLstCount ; i++)
{
foreach (var post in this.Collection)
{
if (post.ResponsePostID == listOfIds.ElementAt(i))
{
listOfIds.Add(post.PostId);
}
}
}
Yes it surely will.The inner foreach loop will execute and add the elements the outer collection and thus will increament the count of the elements.
listOfIds.Count=2 //iteration 1
listOfIds.Add(//element)
when it come to the for loop again
listOfIds.Count=3 //iteration 2
As a slightly abridged explanation of the for loop. You're essentially defining the following:
for (initializer; condition; iterator)
body
Your initializer will will establish your initial conditions, and will only happen once (effectively outside the loop).
Your condition will be evaluated every time to determine whether your loop should run again, or simply exit.
Your iterator defines an action that will occur after each iteration in your loop.
So in your case, your loop will reevaluate listOfIds.Count(); each time, to decide if it should execute; that may or may not be your desired behaviour.
As Dennis points out, you can let yourself get into a bit of a mess (youy loop may run infinitely) if you aren't careful.
A much more detailed/better written explanation can be found on msdn: http://msdn.microsoft.com/en-us/library/ch45axte.aspx

c# syntax question - for loop and end of line

I am currently learning c# and reading a few books. I can do quite a few things, however only from modifying examples - it really frustrates that I do not actually understand how/why some of the more basic items work.
I have just done a console application that takes arguments and displays them all one by one.
The code is:
using System;
class test
{ static int Main(string[] argsin)
{
for (
int i = 0;
i < argsin.Length;
i++
)
Console.WriteLine("Argument: {0}", argsin[i]);
Console.ReadLine();
return -1;
}
}
Now, this works perfectly, but coming from a basic (no pun!) understand of Visual Basic, how/why does it know to print the correct argument and then go on to the next without quitting the application after the first Console.WriteLine... I feel I have missed the fundamentals of how this works!
Next, why is it that inside the for loop, each line ends with a semicolon apart from i++?
I keep forgetting to add it from time to time, and then when trying to work out why it wasn't compiling, I added one where I wasn't meant to!
Your code is formatted a bit strangely, if you reformat it as this I think it's easier to understand:
using System;
class test
{
static int Main(string[] argsin)
{
for (int i = 0; i < argsin.Length; i++)
{
Console.WriteLine("Argument: {0}", argsin[i]);
}
Console.ReadLine();
return -1;
}
}
So as you can see int i = 0; i < argsin.Length; i++ are not 3 different lines, they are all just arguments to the for loop.
And adding the { and } makes it easier to see what lines of code are inside the for loop.
I will try to explain the loop by comparing to VB syntax.
In C#: for (int i = 0; i < 5; i++)
In VB: For i = 0 To 4
The i = 0 part is the same in both, so I guess it's clear - this is used to initialize the loop iterator.
The i < 5 part in C# becomes 0 to 4 in VB.... you can think of this as though VB is doing a "shortcut", but the meaning in both is the same: that is the loop condition, i.e. what is the condition that the loop will keep running, in this case the loop will keep running as long as i is less then 5.
And finally, the i++ part which is required in C# to tell "what will happen to the iterator after each iteration?" is not needed in good old friendly VB that will simply increment it by 1 for you, always - by default.
Why having semicolon after each part of the loop? Because each part has its own meaning and usage so the compiler must know how to separate the parts when building the final code. Why not having semicolon after the i++ part? Same reason that you don't have comma after last argument passed to function e.g. Console.WriteLine("Argument: {0}", argsin[i], );
About the loop having no "block" only one line, it was explained in the other answers, rule of thumb is that C# allow single line blocks to appear without the brackets.
By convention c# and all c like languages when presented with a for loop (or and if statement etc) will run the line immediately after. Personally I don't like writing code like this, i feel it lacks readability.
To clarify we can add curly braces to denote scope
for (
int i = 0;
i < argsin.Length;
i++
)
{
Console.WriteLine("Argument: {0}", argsin[i]);
}
Console.ReadLine();
return -1;
now what the for loop executes is clearly defined (and if we wanted to do more in our loop we would add the extra instructions in between the curly braces).
edit:
The reason for the semi colons as you define your for loop is that each part of that definition is a separate statement.
int i = 0; //creates an integer i and sets its value to 0
i < argsin.Length; sets our comparison operation to define when the loop ends
i++ //what to do at the end in this case increment i by 1
Each needs to be treated independent of the others and as the semi colon denotes the end of a statement in c# (which is why each line ends in it) we use it to break up the statements so the compiler can read it.
While the 2 semicolons are mandatory the arguments are not we could if we wanted change it to be this.
int i = 0;
for (;;)
{
if(i>=argsin.Length){
break;
}
Console.WriteLine("Argument: {0}", argsin[i]);
i++;
}
This is functionally identical to the way you wrote it but I've moved all the logic out of the for statement to its equivalent position inside (or outside in the case of defining i) the loop
The reason why you application prints the right number of arguments is that the WriteLine statement is part of the loop. In C# if you've only got one line of code after a for statement then you don't need curly brackets. (This is the same for if too)
So
for (int i = 0; i < argsin.Length; i++)
Console.WriteLine("Argument: {0}", argsin[i]);
is the same as
for (int i = 0; i < argsin.Length; i++)
{
Console.WriteLine("Argument: {0}", argsin[i]);
}
As the for the semi-colon after the i++ thats just how it is. Normally the for statement is written on one line as I've done in my samples above.
Hope this helps.
I've brushed your formatting a little up, which gives you an easier understanding on how it works.
using System;
class test
{
static int Main(string[] argsin)
{
for (int i = 0; i < argsin.Length; i++ )
Console.WriteLine("Argument: {0}", argsin[i]);
Console.ReadLine();
return -1;
}
}
There's a special rule for C-like languages: You define it's scope using if(true) { ... } similar to If True Then ... End If, but if you only have one line, you can decide not to use brackets. Therefor the next line after the if or for[each] will be used for the scope.
The i++ does not end with a ; because it is within the declaration of the for.
Also, don't forget to have a look at the foreach loop.
If I rewrite your method with different formatting (but identical syntax), it may make things clearer:
static int Main(string[] argsin)
{
for (int i = 0; i < argsin.Length; i++)
{
Console.WriteLine("Argument: {0}", argsin[i]);
}
Console.ReadLine();
return -1;
}
Remember that c# doesn't use a line break for statement termination (unlike VB). The "third line" in your 'for' loop isn't actually a "line," it's just the third expression, and is terminated by the closing bracket.
The reason the loop continues rather than quitting is because (without squiggly brackets to indicate a statement block) the 'for' loop will only loop the single statement immediately following the loop - that is, the 'Console.WriteLine'. I'm guessing that you thought that the 'ReadLine' and 'return' statements would be part of the loop but, in C# syntax, that's not the case. (I added the bracess to my version to make the scope of the loop clearer).
I'll answer the part of your question...
for is a construct that has initializer, loop statement, and terminating condition.
So
for (X, Y, Z) { }
would be equivalent to
X;
while (Y)
{
// code
Z;
}
As for your question about not quiting the application - for () will bind to first NEXT statement, or statement BLOCK. In your case, you have only one line as a statement. If there would be more lines, you should write them encased in { and }.
Typical syntax for a for loop is:
for( int i = 0; i < argsin.Length; i++ )
{
//<CODE>
}
So you'd read it (in your mind) as: "With the temporary value 'i' starting at the value 0, while 'i' is less than 'argsin.Length', do '//' with i as the value, always ending with 'i++'"
A for loop just gets translated to:
{
int i = 0;
while( i < argsin.Lenth )
{
//<CODE>
i++;
}
}
(The extra surrounding braces are to say that 'i' goes out of scope and can no longer be used when the brace closes). Like any 'if' or 'while' statement the closing parenthesis provides the 'end-of-statement' "Character" (if you will) and so the semicolon is unnecessary. Earlier they are a must because you have to know where to end each statement.
[EDIT]
By the way: there's a little more to it than a straight translation. There are cases where you can include multiple initializations, and multiple 'at the end of each loop' instructions. Don't worry about those until you understand what's going on.
That is the basic of the for loop, in that loop, you declare that the starting value of integer i is zero and it should continue to loop until i is equal to the length of string[] argsin and increase the value of i on each iteration. Which means if the length of your argsin array is 5, the loop will
// first run
for(int i = 0;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[0]);
// second run
for(int i = 1;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[1]);
// third run
for(int i = 2;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[2]);
// forth run
for(int i = 3;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[3]);
// fifth run
for(int i = 4;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[4]);
After 5 runs, i will be 5 and will not meet 5 < 5 and quit this loop and go on with the next statement.

Categories