C# Increment operator (++) question:Why am i getting wrong output? - c#

I have a simple c# console application but i am getting wrong output why?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
int i = 100;
for (int n = 0; n < 100; n++)
{
i = i++;
}
Console.WriteLine(i);
}
}
}

i++ is an expression which returns i, then increments it.
Therefore, i = i++ will evaluate i, increment i, then assign i to the original value, before it was incremented.
You need to use ++i, which will return the incremented value.

I'm guessing that you really want an explanation as to why it doesn't work as expected, rather than to actually get the result since you can get that by setting i equal to 200 in the first place.
The postincrement operator is applied after a temporary copy of the variable is created. The temporary is used for operations in the statement then the assignment is performed, thus your loop is equivalent to:
for (int n = 0; n < 100; n++)
{
j = i;
i++;
i = j;
}
Since that's the case, the increment is basically discarded and i is never actually incremented.

i = i++;
This sets i to the old value of i, then increments it. I think you want:
i++;
Or better yet if your compiler is lame and doesn't optimize the return:
++i;
Cheers.

The line i = i++; writes twice to the variable i. The post increment is executed first, but then the assignment statement overwrites it.
Try just i++;

Just use i++, not i = i++.

Related

How to fix 'Use of unassigned local variable' in C# [duplicate]

This question already has answers here:
What does "Use of unassigned local variable" mean? [duplicate]
(11 answers)
Closed 3 years ago.
I am new to C#, my last programming language was C
I kept getting Use of unassigned local variable 'average'
The average it is pertaining was the average /= 10;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
int i, average;
int[] scores = new int[10];
Console.WriteLine("Enter 10 scores");
for (i = 0; i < 10; i++)
{
scores[i] = Convert.ToInt32(Console.ReadLine());
}
for (i = 0; i < 10; i++)
{
average = scores[i] + scores[i + 1];
i++;
}
average /= 10;
Console.WriteLine("Average of All the Scores: {0}", average);
Console.Read();
}
}
}
When you declare the variable 'average', set it to 0.
Here's a fixed version of your code, with comments as to why I made the change:
class Program
{
static void Main(string[] args)
{
//fix the 'use of undefined' error
int average = 0;
int[] scores = new int[10];
Console.WriteLine("Enter 10 scores");
//it's better to scope loop iteration variables to the loop unless you specifically need them outside
for (int i = 0; i < 10; i++)
{
scores[i] = Convert.ToInt32(Console.ReadLine());
}
for (int i = 0; i < 10; i++)
{
//your old code would crash here, and had the wrong algorithm for calculating an average; it didn't sum all the entered values, just the last two
average += scores[i];
}
average /= 10;
Console.WriteLine("Average of All the Scores: {0}", average);
Console.Read();
}
}
I was puzzled as to why the error occurred too because the second loop was clearly assigning a value and I knew that inner scopes could set values and the compiler would recognise them.. learning day for me too as I was formerly unaware that some loops are excluded even when they're set up so they look like they will definitely run. In simple terms it seems that when a loop is set up so that its running is conditional on a variable, the flow analysis considers that in some scenarios the loop might not run even though it's clear to the human reading the code that the loop will always run. Consider these:
//this is fine, flow analysis determines this loop will always run
int average;
while(true){
average = 0;
break;
}
average /= 10;
//this raises the same error even though we as a human can definitely see this loop will always run
int average;
int w = 0;
while(w<1){
average = 0;
}
average /= 10;
Making the loop conditional on a variable meant the compiler wa and longer sure the variable was assigned
As another more involved example, you could also fix your error with this bizarre construct as your first loop:
for (int i = 0; true; i++)
{
average = 0;
scores[i] = Convert.ToInt32(Console.ReadLine());
if(i >= 10)
break;
}
Again the compiler can be sure this loop will always run and your variable will be assigned
here's Peter's comment in case the other answer/the comment goes away:
the compiler doesn't implement any static flow analysis that would confirm that the average variable is set. According to the "definite assignment" rules of C#, loops are ignored because it's possible for a loop to not iterate even once. Thus, average is not definitely assigned, and thus the error. See marked duplicate, and of course the C# language specification, for more details.

Pre Increment of an operator [duplicate]

This question already has answers here:
What is the difference between i++ and ++i?
(7 answers)
Closed 3 years ago.
I dont understand why the value of i and k is still 5 in line number 19 ,20,after post increment?
The value of i is still 5 though after post increment.
`using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Increment
{
class Program
{
static void Main(string[] args)
{
int i = 5;
int j = 10;
Console.WriteLine("before incrementing{0}",i);
i=i++;
Console.WriteLine("after incrementing {0}",i); //i=5?
int k = i;
Console.WriteLine("after incrementing i and assign {0}", k);//K=5?
}
}
}`
Imagine post-increment and pre-increment as functions:
int PreIncrement(ref int i)
{
i = i + 1;
return i;
}
int PostIncrement(ref int i)
{
int valueBefore = i;
i = i + 1;
return valueBefore;
}
In this case
i = i++;
would be the equivalent of
i = PostIncrement(ref i);
You are performing two actions, in this order:
Incrementing i
Setting i to equal the value it equalled before it was incremented
The documentation for ++ has reasonably clear examples. "The result of x++ is the value of x before the operation, as the following example shows... ."
That means however you use x++ in an expression you will be getting the initial value, i.e. prior to x being incremented. So if x is 4 then the value 4 will be used in the expression and x will be incremented to 5. If the expression's value is assigned to a variable then the variable is set to 4. You happen to have chosen x as the target of the assignment, thus overwriting the post-incremented value.

How to retrieve values from Queue using for loop in C#?

class Program
{
static void Main(string[] args)
{
Queue ar = new Queue();
ar.Enqueue(45);
ar.Enqueue(23);
ar.Enqueue(2);
ar.Enqueue(87);
foreach (int x in ar)
{
Console.Write("{0} ", x);
}
Console.ReadLine();
}
}
I know how to retrieve values from a queue using foreach loop. but May I know it is possible to do same thing with the help of for loop ?
I tried following code. but ar[i] is not a valid code. what is the suitable code for ar[i] ?
for (int i = 0 ; i < ar.count ; i++) {
Console.Write("{0} ", ar[i]);
}
It doesn't make much sense to use a for-loop for a Queue since it's not a collection with an index(like IList<T>). So you cannot access items randomly (as with an array: ar[0]). You can use Queue<T>.Dequeue to get the first and remove it or use Queue<T>.Peek to return the first without removing it.
If you used a for-loop you would even get an expected behaviour:
for(int i = 0; i < ar.Count; i++)
Console.Write("{0} ", ar.Dequeue());
Does this display and show all 4 items? No, only the first two because Queue.Count decreases dynamically in the loop whereas the counter variable i increases, hence the loop stops at 2.
So a for-loop is simply the wrong type of loop for this collection. A while is more appropriate:
while(ar.Count > 0)
Console.Write("{0} ", ar.Dequeue());

Step n before an operation in a C# for loop

A standard "for" loop I use is something like that:
for (int i = 0; i < x; i++)
which increments i by 1 every time after it passes thru a loop.
I was wondering if there is anything like a VB's Step n operation in C#'s "for" loop. I googled and found out the only thing I can possibly do is (assume n=2)
for (int i = 0; i < x; i += 2)
That's fair enough. But that brings me to the next question. What if I want to change a loop that increments i BEFORE it goes into it, like:
for (int i = 0; i < x; ++i)
Is there any elegant way to do it, or do I need to go into first loop already with i incremented and increment it at the end of each loop OR before beginning all loops after the first one OR do other crazy stuff?
i += 2
for (int i = 0; i < x; i++)
{ i++; }
or
i += 2
for (int i = 0; i < x; i += 2)
or
for (int i = 0 - 2; i < x - 2; i += 2)
I assume incrementing before a loop might not be possible in all cases, hence i thought there should be some other way to do it.
I was wondering if there is anything like a VB's Step n
You have the right C# equivalent:
for (int i = 0; i < x; i += 2)
What if I want to change a loop that increments i BEFORE it goes into it
I may be missing something, but it sounds like you just want to change your starting value:
for (int i = 1; i < x; i++)
Also note that:
using ++i or i++ makes no real difference here, since you're not doing anything with the return value within the for statement, which is the only difference between using ++i and i++
you can't do the following:
i += 2;
for (int i = 0; i < x; i += 2)
because you can't re-declare i as part of the for loop if it;'s already declared outside of the loop.
EDIT
The for loop for (initializer; condition; iterator) is functionally equivalent to:
{
initializer;
while(condition)
{
.. do something
iterator;
}
}
It sounds like you want some sort of for loop that is equivalent to:
{
initializer;
while(condition)
{
iterator;
.. do something
}
}
there is no such single-statement construct in C#. If you want that series of events you'll have to use a while loop like the above or change the statements in your for loop to provide equivalent functionality.
Just initialize i to 2 to start at 2 rather than trying to execute the looping statement before the body.

Prefix and postfix increment in for loop

Given the following code
int j = 0;
for (int i = 0; i < str.Length; ++i) {
if (i==j) {
Console.WriteLine ("equal");
}
j++;
}
I expected that ++i would change i from initial 0 to 1 and thus i==j evaluated to false.
But it did not. Why?
If you have a loop in the form for (a; b; c) { d; }, you can treat this as the following while loop:
a;
while(b) {
d;
c;
}
As you can see, the increment doesn't occur until after the first iteration, regardless of whether it's a pre- or post- increment.
++i (or anything in the 3rd segment) will not be evaluated until after the first iteration.
No matter what though, even if it evaluated before your if, it would still not work the way you thought it did.
Doing i++ or ++i won't change anything because it would have been evaluated prior to it being used.
The true difference comes when you use it like so:
int i = 0;
if (i++ == 0) { /* True because the old value of "i" was used to compare */ }
i = 0;
if (++i == 0) { /* Not true because "i" got changed to 1 before the compare. */ }
i++ increments and evaluates to (i.e. results in, similar to returning) i's old value
++i increments and evaluates to i's new value
The statements i++; and ++i; are the same because you don't use the result, so the only important part is that they both increment i. Used in a for loop how you are, you're using them as standalone statements, you aren't using the values of the expressions i++/++i.
The compare is evaluated before the increment. Prefix or postfix makes no difference.

Categories

Resources