Post increment operator not incrementing in for loop [duplicate] - java

This question already has answers here:
What is x after "x = x++"?
(18 answers)
Closed 8 months ago.
I'm doing some research about Java and find this very confusing:
for (int i = 0; i < 10; i = i++) {
System.err.print("hoo... ");
}
This is never ending loop!
Anybody has good explanation why such thing happens?

for (int i = 0; i < 10; i = i++) {
The above loop is essentially the same as: -
for (int i = 0; i < 10; i = i) {
the 3rd part of your for statement - i = i++, is evaluated as: -
int oldValue = i;
i = i + 1;
i = oldValue; // 3rd Step
You need to remove the assignment from there, to make it work: -
for (int i = 0; i < 10; i++) {
(On OP request from Comments)
Behaviour of x = 1; x = x++ + x++; : -
As far as your issue as specified in the comment is concerned, the result of the following expression: -
x = 1;
x = x++ + x++;
is obtained as follows: -
Let's mark different parts of the second statement: -
x = x++ + x++;
R A B
Now, first the RHS part (A + B) will be evaluated, and then the final result will be assignmed to x. So, let's move ahead.
First A is evaluated: -
old1 = x; // `old1 becomes 1`
x = x + 1; // Increment `x`. `x becomes 2`
//x = old1; // This will not be done. As the value has not been assigned back yet.
Now, since the assignment of A to R is not done here, the 3rd step is not performed.
Now, move to B evaluation: -
old2 = x; // old2 becomes 2. (Since `x` is 2, from the evaluation of `A`)
x = x + 1; // increment `x`. `x becomes 3`.
// x = old2; // This will again not be done here.
Now, to get the value of x++ + x++, we need to do the last assignment that we left in the evaluation of A and B, because now is the value being assigned in x. For that, we need to replace: -
A --> old1
B --> old2 // The last assignment of both the evaluation. (A and B)
/** See Break up `x = old1;` towards the end, to understand how it's equivalent to `A = old1; in case of `x = x++`, considering `x++ <==> A` in this case. **/
So, x = x++ + x++, becomes: -
x = old1 + old2;
= 1 + 2;
= 3; // Hence the answer
Break up of 3rd part of x = x++, to see how it works in x = x++ + x++ case: -
Wonder why the replacement is done as A --> old1 and not x --> old1, as in case of x = x++.
Take a deep look at x = x++ part, specially the last assignment: -
x = oldValue;
if you consider x++ to be A here, then the above assignment can be broken into these steps: -
A = oldValue;
x = A;
Now, for the current problem, it is same as: -
A = old1;
B = old2;
x = A + B;
I hope that makes it clear.

You're using post-increment: i = i++;, it means something like this:
temp = i;
i = i + 1;
i = temp;
because 15.14.2 Postfix Increment Operator ++:
The value of the postfix increment expression is the value of the variable before the new value is stored.
That is why you have the old value.
For-loop done right:
for (int i = 0; i < 10; i++) {
System.err.print("hoo... ");
}

because of i=i++
for (int i = 0; i < 10; i++) {
System.err.print("hoo... ");
}

i++ will report the value of i, and THEN increment. This also means that you don't need to set i equal to i++, just change to
for (int i = 0; i < 10; i++) {

The problem is in the statement i=i++, this statement does three operations in sequence to complete. these are two operations in i++ and one assignment( = ) operation. These are;
i++ does two operation before any operation
Returns i
Increments i
finally assignment operation
Assigns returned value
So i is incremented before assignment making it to have old value.
Lets see i=i++ in the first loop( where i = 0 ) with the three operations
returns 0 , it will not be assigned to i until the next operation is done
increments i ( i= 0 + 1 = 1 )
assigns returned value 0 to i, ( i = 0), finally i having its old value.
In i++ first i is returned, but immediately before any operation is done it is incremented(i becomes i+1 ), However we are yet left with assignment operation to complete so that the returned value will be assigned to i making it to have old value, thereby entering infinite loop.
so replace i=i++ with i++or i=i+1

Related

Understanding the for loop in Java

I'm new to Java.
I can't seem to understand why these two codes produce different outputs.
Please explain this to me.
What is the difference of y<=x; and y<=5;. As you can see the x is 5 too, I don't understand why I get different outputs.
for (int x = 0; x < 5; x++) {
for (int y = 1; y <=x ; y++) {
System.out.print("x");
}
for (int g = 4; g >= x; g--) {
System.out.print("*");
}
System.out.println();
}
Output:
*****
x****
xx***
xxx**
xxxx*
Code:
for (int x = 0; x < 5; x++) {
for (int y = 1; y <= 5; y++) {
System.out.print("x");
}
for (int g = 4; g >= x; g--) {
System.out.print("*");
}
System.out.println();
}
Output:
xxxxx*****
xxxxx****
xxxxx***
xxxxx**
xxxxx*
Basically the main difference is this line:
for(int y=1; y<=x; y++)
resp.
for(int y=1; y<=5; y++)
The number of times the loop is executed is different. Namely in the first case it is variable (so the number of 'x' increases), in the second case it is fixed (5 'x' printed each time).
(edit: typo)
xstarts at 0 so the first iteration has the condition y<=0, the second will have y<=1 and so on .. till y<=5
While the second one will have y<=5in every iteration, thats why you get xxxxx in every line.
In the first code you print x times the "x" String in each row.
for(int y=1; y<=x; y++) {
System.out.print("x");
}
BTW, it prints the following (which is different than what you claim in the question):
*****
x****
xx***
xxx**
xxxx*
In the second code you print 5 times the "x" String in each row.
for(int y=1; y<=5; y++) {
System.out.print("x");
}
As you can see the x is = 5 too
No, x iterates from 0 to 4, so in each iteration of the outer for loop, it has a different value.
In your first code your for(int y=1; y<=x; y++) for iterations of outer for loop is -
for(int y=1;y<=0;++y) (for first iteration of outer loop)
for(int y=1;y<=1;++y) (for second iteration of outer loop)
for(int y=1;y<=2;++y) (for third iteration of outer loop)
for(int y=1;y<=3;++y) (for fourth iteration of outer loop)
for(int y=1;y<=4;++y) (for fifth iteration of outer loop)
But in your second code its always -
for(int y=1; y<=5; ++y)
for all iterations of outer for loop.
It is very simple the will run for 5 time times and every itreation its value will be increamented by 1 i.e. from 0 to 4.
So in first loop inner loop will have the condition like this:
for (int y = 1; y <= x; y++) {
System.out.print("x");
}
But since in first loop the value of x is 0 hence it literally means:
for (int y = 1; y <= 0; y++) {
System.out.print("x");
}
But in the last iteartion of outer loop the value of x is 4 hence this is equivalent to:
for (int y = 1; y <= 4; y++) {
System.out.print("x");
}
So it iterates 4 times.
In your first example y is first less than x = 1 and during the next iteration it will be less x= 2 ... Because x values changes with your first for loop.
For the second example however you state that y have to be less than 5 which doesn't change at all.
They are different because in the first case your x varies from 0 to 4 based on :
for(int x=0; x<5; x++)
In the case second case x is fixed at 5.
I have replaced your two inner for loops with a new stringRepeat function. It might be easier to understand this way.
public class ForLoopStarsAndCrosses {
public static void main(String[] args) {
/// the total length ot the x's and stars
final int length = 5;
// start with 1 x until one less than the length (in this case 4)
for(int x = 1; x < length; x++) {
// the number of stars equals the total length minus the number of x's
final int nbStars = length - x;
// add the x's and the stars
final String output = stringRepeat("x", x) + stringRepeat("*", nbStars);
System.out.println(output);
}
System.out.println();
}
/** Repeat the string s n times */
private static String stringRepeat(String s, int n) {
String result = "";
for (int i = 0; i < n; i += 1) {
result += s;
}
return result;
}
}
Firstly, you should understand the difference between value and variable. Value is a constant as you write 5 but variable can be changeable.
For your question, first code and first round:
x = 1, y<= 1 and output: x
for(int y=1; y<=x; y++){
System.out.print("x");
}
but for the second code and first round:
y<=5 so output is: xxxxx
for(int y=1; y<=5; y++){
System.out.print("x");
}
it is very simple.
The purpose of loops (can be for, while, do-while) is that, how many number of times the same set of statements to be executed under a specific condition. "for" is a definite loop where there will be an index starting with an integer, keep increment it until the condition is achieved. "while" is a indefinite loop where there is no index and it will be executed until the condition is achieved. "do-while" is a loop similar to "while", which will be executed atleast once and then validates the condition for the next iteration.
Based on the above details,
for(int x=0; x<5; x++){
for(int y=1; y<=x; y++){
for(int x=0; x<5; x++){
for(int y=1; y<=5; y++){
The diff between these two conditions is that,
First condition:
In the first iteration, value of x is 0 and for the second loop y is started with 1.
Here when it compares the value with x which is 0 and 1<=0 which is false, this condition is failed and the statements under Y will not be executed and the control will go back control of x.
Second condition:
In the first iteration, value of x is 0 and for the second loop y is started with 1.
Here when it compares the value with 5, 1<=5 which is true, this condition is valid and the statements under Y will be executed and the control will go back control of x until y becomes 6 and condition checked is 6<=5 which is false, this condition is failed and the statements under Y will not be executed and the control will go back control of x
Note: Due to low reputation, I can't add comments and had to contribute this as an answer. Don't downvote this, instead suggest corrections by comment on the same.

Loop for grabbing certain char's in a string

If I have a string and an int, I want to be able to create a loop that will print the first char of the string, followed by each the char at value of that int.
e.g. If I have the word "Miracle" and the int 2, the result should be "Mrce". My code does this, but stops a char short for certain words.
System.out.println(str.charAt(0));
while (n <= str.length())
{
System.out.println(str.charAt(n));
n = n+n;
}
This works for strings like "abcdefg" and int 3. It prints "adg", but if the string is "miracle" and int 2, it prints "mrc" and not "mrce".
I'm pretty sure the problem is in the "n= n+n" statement.
Because if the int is 3 and the string is greater than 3 it will loop, but in the n=n+n statement it will loop enough that n will be greater than str length and it halts.
How can I correct this?
You are right, your problem is with n=n+n because it multiple n with 2 in every step so you must change that.
change your code like this :
int m = 0;
while (m < str.length())
{
System.out.println(str.charAt(m));
m = m+n;
}
n = n+n; means that in each iteration you are multiplying your n by 2, so
iteration | n
----------+-------
1 | 3
2 | 3+3=6
3 | 6+6=12
and so on.
What you need is temporary variable (iterator) which will use n but will not change it.
Generally more readable way to write it would be with for loop like
for (int i = 0; i < str.length(); i = i+n){//or `i += n`
^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^
// start at continue when in next step
System.out.print(str.charAt(i));
}
I'll answer with a counterquestion: where is this mentionned int? What walue should it have, and what value does it have?
In short, you should have one variable which has the step value and another variable which acts as a cursor.
Something like
int cursor = 0;
while (cursor <= str.length()) {
System.out.println(str.charAt(cursor));
cursor += stepValue;
}
Here you see that it is necessary to have two distinct variables here.
It is working for first few instances as 2+ 2 = 4, but after that - its doing 4 + 4 = 8, while you need is 4 + 2 = 6.
Take a new var (v), assign it the initial value, & instead of doing n = n + n, do
n = n + v
I think this is what you need
int n = 0;
int skip = 2;
while (n < str.length())
{
System.out.println(str.charAt(n));
n+=skip;
}
First of all, you have an error here:
n <= str.length()
It should be
n < str.length()
because strings are indexed from 0 to length-1.
Also make sure you are indexing from 0, not from 1.
Another thing is that you are adding a bigger number each time. So yes - you are right about n+n - it's wrong.
You should do something like this:
n = ...;
for (int i = 0; n * i < str.length(); ++i)
{
int index = n * i;
System.out.println(str.charAt());
}
This way you have n * 0, n * 1, n * 2, ..., which is what you want.
There are two things wrong in your code:
If n == str.length(), it will throw an exception, as it tries to
access str.charAt(n), which in that case doesn't exist.
Another thing, n = n + n will change the value of n every time, so you
will add a bigger number every time instead of the same.
You could use a for-loop for a cleaner approach though:
for (int i = 0; i < str.length(); i += n) {
System.out.println(str.charAt(i));
}

how to change variables in a while-loop used outside the loop in java

(...)
int x = 1;
int y = 1;
System.out.println(x);
while ( y == 1)
{
x = 2;
y = y + 1;
}
How can I change afterwards the x of the System.out.println?
I wrote it very easy but I want to change the x in the while loop and use it at the beginning
You can't. You have to move the System.out.println line to after the while loop to use the newly calculated value.

Questions about array

Here is my code and it works perfectly fine.
import java.util.Random;
class apples
{
public static void main(String args[])
{
Random rand = new Random();
int frequency[] = new int[7];
for(int roll = 1;roll < 1000;roll++){
++frequency[1+rand.nextInt(6)];
}
System.out.println("Face\tFrequency");
for(int face = 1;face < frequency.length;face++){
System.out.println(face + "\t" + frequency[face]);
}
}
}
I do not understand this line of code
++frequency[1+rand.nextInt(6)];
When I removed the "++" operator, it couldn't be compiled. I know that it will add 1 to the randon numbers generated from 0 to 5 but why there is a "++" in front of frequency ? Why is it neccessary to put the "++" operator there ?
The ++ operator is incrementing the frequency at the specified index. In this case, it's the same as saying:
for(int roll = 1;roll < 1000;roll++){
int index = 1+rand.nextInt(6);
frequency[index] = frequency[index] + 1;
}
Removing the ++ operator, you're left with:
for(int roll = 1;roll < 1000;roll++){
frequency[1+rand.nextInt(6)];
}
The line frequency[1+rand.nextInt(6)] makes no sense; it is not an operation, it does not do anything.
EDIT:
Perhaps a better illustration: let x be the value looked up in the frequency array. Then the original is equivalent to:
for(int roll = 1;roll < 1000;roll++){
int x = frequency[1+rand.nextInt(6)];
++x; // Equivalent to "x = x + 1"
}
Whereas if you remove the increment operator, your resulting loop would be:
for(int roll = 1;roll < 1000;roll++){
int x = frequency[1+rand.nextInt(6)];
x; // ...what?
}
The statement without the ++ looks at the contents of the array, but does not do anything with the value. Adding the ++ operator tells it to increment the value found there.
You probably are thinking that frequency[1+rand.nextInt(6)] is adding a value to the array. It is not. It is looking up a location in memory from a random location.
++ is a shorthand for
int i = 1+rand.nextInt(6);
frequency[i] = frequency[i] + 1;
Removing it causes no increment expression is executed.
that line is equivalent to this line of code
int index = 1+rand.nextInt(6);
frequency[index] = frequency[index]+1 ;
so if you removed '++' you make the statement incomplete like the following:
int x= 5;
x;
so it gives you error

Beginner: Trying to run an sum/average class getting an error

When I run this class I am not getting a the sum/average. I am getting an error listed below. I am not sure why I am getting it. I am a student very new at this.
public class DebugEight2
{
public static void main(String[] args)
{
int[] someNums = {4,17,22,8,35};
int tot;
int x;
int sum = 0;
for(x = 0; x <= someNums.length; ++x)
tot = someNums[x];
sum = sum + someNums[x];
System.out.println("Sum is " + sum);
System.out.println("Average is " + sum * 1.0 / someNums.length);
}
}
Error:
"Exception in thread "main" java.lang.ArrayIndexOutofBoundsException: 4 at DebugEight1.main (DebugEight1.java:17)"
Array index starts from 0 and goes till it's length -1 See that <= in your for loop. So this for(x = 0; x <= someNums.length; ++x) should be for(x = 0; x < someNums.length; ++x)
Problem is your loop condition, remove the equal sign like this
for(x = 0; x < someNums.length; ++x)
You should also wrapp the code which is supposed to be inside the loop into brackets (without them, only the next line after the for loop condition will be executed)
for(x = 0; x < someNums.length; ++x) {
tot = someNums[x];
sum = sum + someNums[x];
}
first you should remove = from <= someNums.length; i will look like this < someNums.length; and then change ++x to x++ if you put ++x when loop starts it will check condition < someNums.length; and then pluse one +1 to x and so on, currently your array length is 5 when loop goes on last increment its size is 6 and there is no item on 6 location thats why it is throwing exception so you have you change it ++x to x++
public class DebugEight2
{
public static void main(String[] args)
{
int[] someNums = {4,17,22,8,35};
int tot;
int x;
int sum = 0;
for(x = 0; x <someNums.length; x++) /// just change here
tot = someNums[x];
sum = sum + someNums[x];
System.out.println("Sum is " + sum);
System.out.println("Average is " + sum * 1.0 / someNums.length);
}
}
Arrays are zero based and their indices go from 0 to someNums.length -1
You not only exceeding the bounds of the array but the variable sum is being assigned outside of scope of the loop. Adjust the upper bounds of the array and add braces:
for (x = 0; x < someNums.length; x++) {
tot = someNums[x];
sum = sum + someNums[x];
}
Hope this helps
You want to iterate while x is lesser than someNums.length; since max index in array is arraysLength - 1, so change x <= someNums.length; to x < someNums.length; in for loop
There is no need for tot (I assume it should store total numbers) variable because you already have someNums.length which represents how many numbers you summed. BTW you already are calculating avg using sum and someNums.length. So you can safely remove
tot = someNums[x];
from your code.
What you did is you looped beyond the scope of the array. Try doing someNums.length, you will get the number 5.
Going to your for loop we now know that it starts at 0 and increments until it gets to 5. And the for loop is traversing over the array and is pointing at the positions in your array.
So let's traverse through your loop.
At x = 0, someNums[x] = 4.
At x = 1, someNums[x] = 17,
At x = 2, someNums[x] = 22,
At x = 3, someNums[x] = 8,
At x = 4, someNums[x] = 35,
As you can see, your array has now ended, you no longer have any more elements to traverse over. But we have previously stated that your for loop increments until it gets to 5.
So at x = 5, someNums[x] will have to give you an error since you are pointing at a position and trying to retrieve information from that position that essentially does not exist.
There are two ways to solve your problem:
You change the loop to for(int x = 0; x < someNums.length; x++)
You change the loop to for(int x = 0; x <= someNums.length - 1; x++)
These will solve your problem because they will stop your loop at 4 and not at 5, therefore you will no longer receive an error.

Categories

Resources