Nested inline IF statements - c#

I am a little confused why this is not working:
id = (isChar ? (id + 1 > 122 ? 65 : id++) : id++);
The input here can either be an int or a char converted to an INT. I am then incrementing the id and increasing either the int or char. The problem is, when I input a char, the number does not seem to change?

This is an extremely poor programming practice that you're using. Conditional expressions should not have side effects; they should compute values. You are executing the side effect and then throwing away the side effect! You should either (1) make a side-effect-free version:
id = (isChar && id > 121) ? 65 : id + 1;
or (2) write your side-effecting version as statements, not expressions:
if (isChar && id > 121)
id = 65;
else
id++;
Let's take a look in more detail what is wrong with this simplified version of your original buggy code:
id = whatever ? 65 : id++;
Suppose whatever is false. What happens? id++ is morally equivalent to:
int PostIncrement(ref int x)
{
int temp = x;
x = temp + 1;
return temp;
}
So suppose you did:
id = whatever ? 65 : PostIncrement(ref id);
What happens? Suppose id is 1. You pass it by reference to PostIncrement. PostIncrement makes a copy of the value of id -- 1 -- in temp. It then adds one to that -- 2 -- and assigns the result to id. So id is now 2. Then it returns 1.
Back in the caller, id is now 2, and then you assign the result of PostIncrement, which was 1, and now id is 1 again.
Do not use id++ to mean id + 1 because that is not at all what it means.

Change id++ to id + 1 in both cases. You are throwing away the change from the increment in the assignment, which is executed last.
As a general rule, avoid side-effects (such as ++) in complex expressions. They make the whole expression intractable. This has tripped you up here.
Better yet, increment id beforehand since you always seem to increment it:
id += 1;
if (isChar && id > 122)
id = 65;
or
id = (isChar && id > 121) ? 65 : id + 1;

The other answers are correct. You should consider their advice first, however, it is possible to fix this simply by moving the ++ operator before the variable, i.e. ++id.
Essentially, putting ++ after your variable (postfix increment operation) returns the value of the variable before the increment occurs. By moving the ++ ahead of your variable (prefix increment operation), it returns the value of the variable after the increment is performed. Note that in both cases the incremented value is still stored in the variable, only the value returned by the operation is affected.
See ++ Operator (C# Reference) for more details on that.

Related

How to update variable from with if statement MQL5

I have been googling for two days now, but can't figure this out and it seems to be basic.
Within the void OnTick(), I would like to create a variable int a;. Lets say it starts out with no value int a;, then I test condition if a is NULL or || equals 1 like this if (a == NULL || a == 1) which should always return true the first time the if statement runs due to NULL. I then assign a value to the variable a = 0;, so now a should equal 0.
This should trigger the else if(a == 0) the next time OnTick() is called, at this point I assign a = 1; resulting in the if being triggered next time round, etc and infinitum, constantly checking and assigning values switching between 0 and 1.
void OnTick()
int a;
if (PositionsTotal() < 1)
{
if(a == NULL || a == 1)
{
a = 0;
}
else if(a == 0)
{
a = 1;
}
}
I do not know what is going on, but during Testing in Strategy tester, I am getting a long string of numbers which switches between negatives and positives always with the same number -123456789 or 123456789, always 9 digits long.
Or during Debugging from Meta Editor. A random positive 3 digit number which never changes!
So far I have had both 303 and 597.
Beyond frustrating and most likely answered somewhere else.
Just not sure how to phrase the search term.
Thanks for you help.
I think the problem is that you declare your variable a inside the method OnTick, so it starts with an arbitrary value every time you call this method. Try declaring it outside this method.

Does for loop parameters execute each iteration?

At some point I wanted to randomize if an array would be inverted or not while creating it.
One of the first things I figured was this:
bool reverse = Random.value > 0.5f;
for (
int i = reverse ? steps - 1 : 0;
reverse ? i >= 0 : i < steps;
i += reverse ? -1 : +1
) {
rotateScript.angles.Add(angleRange[0] + stepAdder * i);
}
Later I realized despite taking more lines, two for loops inside an if/else would be more readable.
But the question remained: Would those ternary conditions be executed each iteration, or just once?
Correct, the 2nd and 3rd components of the for statement are evaluated in every iteration.
This:
for( x; y; z ) a;
Is equivalent to:
x;
while( y ) { a; z; }
So y will be evaluated 1 more time than z.
As #Dai pointed out, the second and third statements must be evaluated at the end of each iteration.
This behaviour is detailed in ยง8.8.3 of the C# language specification. Paraphrased, it says about a
for ( initialiser; condition; iterator; ) { ... }
statement:
A for statement is executed as follows:
If a for-initializer is present, the variable initializers or statement expressions are executed in the order they are written. This step is only performed once.
If a for-condition is present, it is evaluated.
If the for-condition is not present or if the evaluation yields true, control is transferred to the embedded statement. When and if control reaches the end point of the embedded statement, the expressions of the for-iterator, are evaluated in sequence, and then another iteration is performed, starting with evaluation of the for-condition in the step above.
If the for-condition is present and the evaluation yields false, control is transferred to the end point of the for statement.
With your code
for (
int i = reverse ? steps - 1 : 0;
reverse ? i >= 0 : i < steps;
i += reverse ? -1 : +1
) {
rotateScript.angles.Add(angleRange[0] + stepAdder * i);
}
you do have a few options to make the ternary operator at reach iteration unnecessary.
You mentioned using an if/else with two for loops but I suggest that you do not do that because it duplicates code, which hinders its maintainability, and readability.
Option 1: Use a standard for loop:
You can put the logic into the code inside the loop, i.e.
for ( i = 0; i < steps; i += 1 )
{
int multiplier = reverse ? steps - 1 - i: i;
rotateScript.angles.Add(angleRange[0] + stepAdder * multiplier);
}
Option 2: Move the ternary logic out:
Calculate the limit and the increment first, i.e.
int start = reverse ? steps - 1 : 0;
int increment = reverse ? -1 : +1;
int limit = reverse ? -1 : steps;
for ( int i = start; i != limit; i += increment; )
{
rotateScript.angles.Add(angleRange[0] + stepAdder * i);
}
I prefer option 1 as I think most people find straightforward for loops easier to understand.

Showing different output from my acceptation

Hay I didn't know even If this question has asked before but my problem is as following.
In my c# console application I had declared a variable i with assigning a value as
int i = 0 and now I want increment i by 2, obviously I can use following cede.
int i = o;
i += 2;
Console.WriteLine(i);
Console.ReadLine();
//OUTPUT WILL BE 2
but this one is my alternate solution. As my lazy behavior I refuse to use this code and I had used following code.
int i = 0;
i += i++;
Console.WriteLine(i);
Console.ReadLine();
In above code I had accepted FIRST i++ will increment by one and than after it will again increment by i+=i but this thing is not happen.!!!
I doesn't know why this thing is happening may be I had done something wrong or some compilation problem.?????
Can any one suggest me why this happening????
I just want to know why code no 2 is not working? what is happening in there?
The i++ returns the value of i (0) and then adds 1. i++ is called post-increment.
What you are after is ++i, which will first increase by one and then return the increased number.
(see http://msdn.microsoft.com/en-us/library/aa691363(v=vs.71).aspx for details about increment operators)
i needs to start off with 1 to make this work.
int i = 1;
EDIT::
int i = 0;
i += i++;
Your code above expresses the following:
i + 0 then add one
if you use i += ++i; then you'll get i + 1 as it processed the increment beforehand.
What your code is doing:
"i++" is evaluated. The value of "i++" is the value of i before the increment happens.
As part of the evaluation of "i++", i is incremented by one. Now i has the value of 1;
The assignment is executed. i is assigned the value of "i++", which is the value of i before the increment - that is, 0.
That is, "i = i++" roughly translates to
int oldValue = i;
i = i + 1
//is the same thing as
i = oldValue;
The post-increment operator increments the value of your integer "i" after the execution of your i++
For your information:
i++ will increment the value of i, but return the pre-incremented value.
++i will increment the value of i, and then return the incremented value.
so the best way of doing the 2 step increment is like that:
i +=2

How and where do i use the i++ operator in C#?

I was wondering if anyone could tell me about the i++ operator in C#.
I know it adds one to the int value, but I wouldn't have a clue where to use it, and if its only for loop statements, or can be used in general projects.
If I could get some practical examples of where you might use the i++ operator, thank you.
This is post-increment,which means that the increment will be done after the execution of the statement
int i=0;
Console.Write(i++); // still 0
Console.Write(i); // prints 1, it is incremented
In general, given this declaration:
var myNum = 0;
anywhere you would normally do this:
myNum += 1;
You could just do this:
myNum++;
What you are referring to is the C# post increment operator, common use case are :
Incrementing the counter variable in a standard for loop
Incrementing the counter variable in a while loop
Accessing an array in sequential order (3)
Example (3) :
int[] table = { 0, 1, 2, 3, 4, 5, 6 };
int i = 0;
int j = table[i++]; //Access the table array element 0
int k = table[i++]; //Access the table array element 1
int l = table[i++]; //Access the table array element 2
So, whats the post increment operator really does ?
It return the value of the variable and then increment it's value by 1 unit .
The expression i++ is just like x == y > 0 ? x : z which both are syntactic sugar.
x = i++ saves you the space of writing x=i; i=i+1;
Is it good or bad? There is really no exact answer to this.
I personally avoid these expressions as they make my code look complex, sometimes hard to debug. Always think code readability instead of write-ability, always think how your code looks readable instead of how easy is it to write it

int[] arr={0}; int value = arr[arr[0]++]; Value = 1?

Today I came a cross an article by Eric Lippert where he was trying to clear the myth between the operators precedence and the order of evaluation. At the end there were two code snippets that got me confused, here is the first snippet:
int[] arr = {0};
int value = arr[arr[0]++];
Now when I think about the value of the variable value, I simply calculate it to be one. Here's how I thought it's working.
First declare arr as an array of int
with one item inside of it; this
item's value is 0.
Second get the value of arr[0] --0 in
this case.
Third get the value of arr[the value
of step 2] (which is still 0) --gets
arr[0] again --still 0.
Fourth assign the value of step 3
(0) to the variable value. --value =
0 now
Add to the value of step 2 1 --Now
arr[0] = 1.
Apparently this is wrong. I tried to search the c# specs for some explicit statement about when the increment is actually happening, but didn't find any.
The second snippet is from a comment of Eric's blog post on the topic:
int[] data = { 11, 22, 33 };
int i = 1;
data[i++] = data[i] + 5;
Now here's how I think this program will execute --after declaring the array and assigning 1 to i. [plz bear with me]
Get data[i] --1
Add to the value of step 1 the value
5 --6
Assign to data[i] (which is still 1)
the value of step 2 --data[i] = 6
Increment i -- i = 2
According to my understanding, this array now should contain the values {11, 27, 33}. However, when I looped to print the array values I got: {11, 38, 33}. This means that the post increment happened before dereferencing the array!
How come? Isn't this post increment supposed to be post? i.e. happen after everything else. What am I missing guys?
The postincrement operation occurs as part of evaluating the overall expression. It's a side effect which occurs after the value is evaluated but before any other expressions are evaluated.
In other words, for any expression E, E++ (if legal) represents something like (pseudo-code):
T tmp = E;
E += 1;
return tmp;
That's all part of evaluating E++, before anything else is evaluated.
See section 7.5.9 of the C# 3.0 spec for more details.
Additionally, for assignment operations where the LHS is classified as a variable (as in this case), the LHS is evaluated before the RHS is evaluated.
So in your example:
int[] data = { 11, 22, 33 };
int i = 1;
data[i++] = data[i] + 5;
is equivalent to:
int[] data = { 11, 22, 33 };
int i = 1;
// Work out what the LHS is going to mean...
int index = i;
i++;
// We're going to assign to data[index], i.e. data[1]. Now i=2.
// Now evaluate the RHS
int rhs = data[i] + 5; // rhs = data[2] + 5 == 38
// Now assign:
data[index] = rhs;
The relevant bit of the specification for this is section 7.16.1 (C# 3.0 spec).
For the first snippet, the sequence is:
Declare arr as you described:
Retrieve the value of arr[0], which is 0
Increment the value of arr[0] to 1.
Retrieve the value of arr[(result of #2)] which is arr[0], which (per #3) is 1.
Store that result in value.
value = 1
For the second snippet, the evaluation is still left-to-right.
Where are we storing the result? In data[i++], which is data[1], but now i = 2
What are we adding? data[i] + 5, which is now data[2] + 5, which is 38.
The missing piece is that "post" doesn't mean "after EVERYTHING else." It just means "immediately after I retrieve the current value of that variable." A post increment happening "in the middle of" a line of code is completely normal.
data[i++] // => data[1], then i is incremented to 2
data[1] = data[2] + 5 // => 33 + 5
I would expect the post-increment operator to increment the variable after its value is used.
In this case, the variable is incremented before the second reference to the variable.
If it would not be so, you could write
data[i++] = data[i++] + data[i++] + data[i++] + 5
If it would be like you say, then you could remove the increment operator because it doesn't do actually anything, in the instruction I reported.
You have to think of assignments in three steps:
Evaluate left hand side (=get address where the value should be stored)
Evaluate right hand side
Assign the value from step 2 to the memory location from step 1.
If you have something like
A().B = C()
Then A() will run first, then C() will run, and then the property setter B will run.
Essentially, you have to think of your statement as
StoreInArray(data, i++, data[i] + 5);
The cause might be that some compilers optimize i++ to be ++i. Most of the time, the end result is the same, but it seems to me to be one of those rare occasions when the compiler is wrong.
I have no access to Visual Studio right now to confirm this, but try disabling code optimization and see if the results will stay the same.

Categories