Code snippet:
int i=0;
for(int i=0;i<1;i++){
i=--i-i--;
System.out.println("for loop i= "+i);
}
System.out.println("i value outside for loop= "+i);
output:
for loop i= 0
i value outside for loop= 1
The value of i inside for loop is zero and outside for loop i is 1. Could you please help me understand it?
i=--i-i--; changes the value of i to -1 and then back to 0, because it assigns to it -1-(-1), which is 0. The reason for this result is that pre-decrement operator - --i - returns the decremented value -1 while post-decrement operator - i-- - returns the value prior to decrementing it (therefore it returns -1 instead of -2).
However, the loop's i++ clause increments i to 1, which causes the loop to terminate. Therefore the value of i is 1 after the loop.
Note that you have a typo in your question. You are declaring i twice in the same scope. In order for the code to pass compilation (and display the output you claim you got), you should change it to:
int i=0;
for (i = 0; i < 1; i++) {
i = --i-i--;
System.out.println("for loop i= "+i);
}
System.out.println("i value outside for loop= "+i);
Related
I'm currently struggling understanding this loop:
class Test{
public static void main(String args[]){
int i=0, j=0;
X1: for(i = 0; i < 3; i++){
X2: for(j = 3; j > 0; j--){
if(i < j) continue X1;
else break X2;
}
}
System.out.println(i+" "+j);
}
}
So far I know that the values of the variable will be:
0 3
1 3
2 3
and finally will print 3 3.
After the third iteration the condition on X1 will be false resulting in an interruption of the loop statement. While it's clear to me why the value of i is equal to 3, I do not understand why the value of j is 3 as well. Initially the value of j is 0, when we enter in the loop is 3, but in the last iteration we do not enter really in the X2 loop, since i<3 evaluate false. So the question is why the compiler "save" the value of k ? And even if the compiler save the value of j from the previous iteration should be 2 ...
j-- is dead code here and will never be reached. Think about how the code works for a moment here:
X2: for(j = 3; j > 0; j--){
if(i < j) continue X1;
else break X2;
}
If one situation you continue to the outer loop, in the other situation you break out of this loop. This loop actually never even goes past a single iteration so you might as well just write this like this:
int i=0, j=0;
X1: for(i = 0; i < 3; i++){
j = 3;
if(i < j) continue X1; //This line does nothing at this point as well since the loop will iterate anyway
}
This is exactly the same as your current code, which clearly shows j will stay at 3.
for(j = 3; j > 0; j--)
You are setting j=3. j-- is not run until the next j loop, that never occurs, so it cannot be 2.
else break X2;
and
j--
are never being reached.
'i' can never be 3 within the loop since the outer loop's condition is i < 3, and therefor the inner loop can only perform
if(i < j) continue X1;
since 'j' always starts at 3 and i <= 2. is always true. So 'j' never changes value, and the outer loop breaks when i = 3, resulting in, "3 3".
i j
0 3
1 3
2 3
break occurs;
print i + j;
Initially the value of j is 0, when we enter in the loop is 3, but in the last iteration we do not enter really in the X2 loop, since i<3 evaluate false. So the question is why the compiler "save" the value of k ?
j is declared at the first line in main. This means that it will remain in scope and retain any modifications until main ends and the variable is destroyed.
And even if the compiler save the value of j from the previous iteration should be 2.
As you said above, the value of j from the last iteration of the loop was 3 not 2. When you continue X1 the j-- was never executed.
It is because of the dead code as others mentioned. You should debug your program by going step by step I don't know which IDE you are using but it probably provides this feature.
However, I want to advice you to not use continue and break statements. It is highly discouraged by the instructors. They cause spaghetti programming and confusions like you have.
This question already has answers here:
How do the post increment (i++) and pre increment (++i) operators work in Java?
(14 answers)
Closed 4 years ago.
class Test {
public static void main(String[] args) {
for (int i= 1; i < 2; i++) {
System.out.println(i);
System.out.println(++i);
int a = 1;
System.out.println(a++);
System.out.println(++a);
}
}
}
The output here is 1,2 and 1,3. We are doing post-increment and pre-increment in both the cases why I am getting different results?
Because post increment happens at the end of the iteration.
Hence the below code :
for (int i= 1; i < 2; i++) {
System.out.println(i);
System.out.println(++i);
Will work something like this:
int i = 1;
System.out.println(i); // i is still 1
System.out.println(++i); // pre increment making i to 2 and then print
i++;
if(i<2)
// iterate again
However, in second case:
int a = 1;
System.out.println(a++); // post increment first print 1 and then change a to 2
System.out.println(++a); // pre increment a now changed to 3
System.out.println(i); // 1 (initial value)
System.out.println(++i); // 2 (pre increment returns the value after increment)
int a = 1;
System.out.println(a++); // 1 (initial value prior to increment, since post increment
// returns the value prior to increment)
System.out.println(++a); // 3 (pre increment returns the value after increment)
The i++ in the loop's definition only takes place at the end of each iteration. You never print the value of i after i++ is executed, since the loop terminates after the first iteration.
BTW, if i++ was executed prior to System.out.println(i);, you'd still get a different output (compared to the last two println statements) - 2 followed by 3.
The general structure of a for loop (more precisely: this type of basic for statement) is:
for ([ForInit]; [Expression]; [ForUpdate]) Statement
The equivalent while loop is:
[ForInit];
while ([Expression]) {
Statement;
[ForUpdate];
}
In other words, the update is executed after the loop body.
So your code is equivalent to:
// ForInit
int i = 1;
while (/* Expression */ i < 2) {
// Statement
System.out.println(i);
System.out.println(++i);
int a = 1;
System.out.println(a++);
System.out.println(++a);
// ForUpdate
i++;
}
Hopefully it is then easy to see why there is a difference in the output.
In the first case, the post-increment is not called. If you understand how a for loop works, you will know that the increment section is not executed the very first time. The initialization section, here int i = 1, and the condition checking - i < 2 is validated. The increment section is invoked only after each iteration.
In the second case, the post-increment is performed and hence the difference in values. You should focus more on the basics of looping.
System.out.println(i);
i isn't postincremented here. The answers would be the same if it were:
System.out.println(i++);
System.out.println(++i);
int a = 1;
System.out.println(a++);
System.out.println(++a);
for (int i= 1; i < 2; **i++)**
doesn't do anything until a pass through loop is done.
I want to make a for loop that adds by 1 every other iteration, as long as it doesn't reach a value higher than 5.
I've tried with nested forloops but it's still nothing like it.
E.g.
Given a value x=10 or x=3.
For i<x && i<=5; i++
and this is where i want a value y, to be added with +1 every other (2th) time it runs the loop.
Thanks in advance.
You can do this for example by adding a second variable s that is 0 on every first and 1 on every second iteration.
for(int i=0, s=0; i<5; i+=s, s=-s+1)
You can use the % (module) operator in a condition inside the loop with the index variable, like this:
// code where you initialize x and y variables
for (int i=0; i<x && i<=5; i++) {
if (i % 2 == 0) { // even values for i
y++;
}
}
In this case the loop increments y in the first, third, fifth (.. and so on) iterations. If you want to increment it on the second, fourth, sixth (... and so on), then invert the condition with i % 2 != 0
I am new at java, so there is some piece of code in nested loop I don't understand...
for(int i=0; i<3; i++){
for(int j=1; j<3; j++){
System.out.println(i + "" + j);
}
}
it will run: 01,02,11,12,21,22
but when I changed into this:
int j=1;
for(int i=0; i<3; i++){
for(; j<3; j++){
System.out.println(i + "" + j);
}
}
it become like this: 01,02
can anyone explain it to me?
The difference between the loops is that j is being reset each time in the top example but in the second example it is keeping its value.
In the top example, each time the inner for loop starts j is being reinitalized to 1 so it will go through the 1,2,3 values. When j gets to 3 it will exit the loop which is why you see the j value as 1 then 2. This is run each time the outer loop runs giving you the 0, 1 and 2 for your i values.
In the bottom example j is never reset so it will only increase. The first time through the loop it goes through the 1, 2, 3 values and exits the loop giving you the 01, 02 values you have seen. Since it does not get reset it stays as 3 so as i increases the inner loop will always exit without printing, giving you the output you are seeing.
To get the same output for the bottom example you need to reset the value to 1, which is basically what the first element of the for loop is doing.
int j = 1;
for(int i = 0; i < 3; i++) {
j = 1; //reset the value each time through the outer loop
for(; j < 3; j++) {
System.out.println(i + "" + j);
}
}
In your first code
At case i=0
The inner loop starts with condition j=1
j=1 initialized **Condition satisfies** continue
j=2 incremented **Condition satisfies** continue
j=3 incremented **Condition Failed** loop ends
The inner first executes it complete cycle and tend to increment of i
Now i=1
Again
j=1 initialized **Condition satisfies** continue
j=2 incremented **Condition satisfies** continue
j=3 incremented **Condition Failed** loop ends
But in your second code, j is declared outside and once j is set to 3, it remains same.
So condition failed for second loop.
At case i=0
j=1 declared **Condition satisfies** continue
j=2 incremented **Condition satisfies** continue
j=3 incremented **Condition Failed** loop ends
At case i=1
j=3 Already set**Condition Failed** loop ends
loop fails
It will print 01, 02. The reason is because you don't re-initialize j. So after the second iteration of your inner loop (when i is still 0, j is 3, so it fails the condition on each of your next iterations for the outer loop.
Variables defined inside of a for-loop declaration have extremely narrow scope. This means that they die (and will need to be re-initialized) as soon as the loop finishes all of its iterations. A variable defined in the method body, as you did in the second example, will persist until the method itself concludes.
Code 1:
i values are: 0,1, 2
j: 1, 2
hence output:
01
02
11
12
21
22
But in Code 2:
J is initially set to 1
so in i's first iteration i.e
For i=0 -> j=1, 2
but then for next iteration. j's value is not set back to 1. so j = 3. And code cant enter j's loop.
Hope thats clear enough explanation.
j is not initialized in the for of the second coded block. Then the loop will start with j's current value. The first time this for is entered, j is 1, and it loops until j is 3. The second time the for is reached, j is still 3, so it doesn't satisfy the looping condition and the loop body is not executed. Following times it's the same.
I need some help with this enhanced for loop. I want to understand the coding for a standard loop and while loop, please. Thanks.
public static int average(int...numbers) {
int total=0;
for(int x:numbers)
total+=x;
return total/numbers.length;
}
In your example int...numbers is the same as "int[] numbers"
So the for loop would have to iterate over that array.
for(int i=0; i < numbers.length ; i++)
{
int x=numbers[i]
...
}
Would be a direct replacement.
Your for loop is equivalent to:
for(int i=0;i<numbers.length;i++){
int x = numbers[i];
total+=x;
}
Each element is retrieved in order, and the code within the loop is executed for each element.
The first operation, int i=0; is executed upon entering the for loop, and only once.
The second operation, i<numbers.length is the condition which must be true for the for loop to continue. This can actually be any boolean expression. I do not advise making your boolean expression overly complicated, but be aware its possible. An example:
boolean continueSumming = true;
for(int i=0;i<numbers.length && continueSumming;i++){
if(i>9)
continueSumming=false;
}
This loop would only iterate for a maximum of 10 elements for example, as the continueSumming variable would be set to false at the 9th element (remember arrays are 0 indexed.)
The last operation, i++ is also executed each iteration. Here it increments i.
i could be called the sentinel variable here as it controls when the loops execution ends. More bonus trivia for you.
A while loop is simpler, it repeats until some condition is no longer true. This while loop is equivalent to your for loop.
int index = 0;
while(index < numbers.length) {
total += numbers[index];
index += 1;
}
Each element would be added to the total, and the loop would exit when index was greater than or equal to the length of the array. As each iteration of the while loop is incrementing the index by 1, it will be executed for each element.
While loops aren't normally used to iterate over arrays as for loop syntax is less verbose, and allows the sentinel variable i to fall out of scope, while the for loop syntax does not.
Assuming your question is "What would be the difference between using a for loop or a while loop to find the average of an array of numbers?", here you go.
for (x : y) is a loop which allows you to operate on every object in the array y by using the reference x.
In your example, int total=0; is the total for the average calculation.
for(int x:numbers) allows you to run code on every integer in numbers through the reference variable of x
total+=x; adds the current number the loop is processing to the total, as an average calculator should
total/numbers.length divides the total by the amount of numbers (objects in the array numbers) to be returned; gives the average.
A while loop loops through until a boolean value, statement, or condition is false.
William Morrison shows you how it's done, by using an integer to show which object the loop is processing, and making a condition which checks whether the next-to-be-processed object even exists - whether its index, or the integer, is out of bounds of numbers.length.
numbers[index] is the same as x in the for loop's case.
A standard loop would take the same sort of conditions the while loop does.
for (int index = 0; index < numbers.length; index = index + 1) {
total += x;
}
Hope this helps you understand looping more clearly!