I came across the following issue:
private void doStuff(int i) {
if(i>10) {
return;
}
doStuff(i++);
}
public void publicMethod() {
doStuff(i);
}
I would expect this to run doStuff 10 times and then return.
However i++ does not get executed before the doStuff is called again with 0.
Result is an infinite loop. I know how to fix it but I am wondering if this behaviour is correct or a bug.
Now I would expect this to run doStuff 10 times and then return, however i++ does not get execute before the doStuff is called again with 0.
Yes, the result of the post-increment operator is the original value... and then inside the next call to the method you've a new i. So in other words, this call:
doStuff(i++);
is equivalent to:
int original = i;
i = original + 1;
doStuff(original);
From JLS section 15.14.2:
The value of the postfix increment expression is the value of the variable before the new value is stored.
Given that you don't use i again afterwards (and thus any side-effect on it is pointless), why not just simplify your life?
doStuff(i + 1);
(As with all parameters in Java, you're seeing pass-by-value - changing the value of i in the method does not change the value of the caller's argument.)
It behaves as expected it should, you probably want to replace i++ with ++i.
Check the oracle documentation on how to use the prefix/postfix unary increment operator:
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
(excerpt from the linked page)
The ++ operator works just as expected. it first returns the value of the variable, and then increases the variable, hence you always pass 0.
This:
doStuff(i++);
is like:
int x = i;
i += 1;
doStuff(x);
i++ means that: "use value of i and then increment it". It will always be zero when passed down. It is a value type, not a reference type. If that would be an object, that would be no problem because it would be handled as reference.
Related
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 months ago.
import java.util.Scanner;
public class recursion_4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int a[] = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
printArray(a, 0);
sc.close();
}
static void printArray(int arr[], int i) {
if (i == arr.length) {
return;
}
printArray(arr, ++i);
System.out.println(arr[i]);
}
}
I am try to print array element using recursion.
But it give error of arrayIndex Out of bound.
Replace ++i with i+1
You are incrementing the value of local variable in function. Instead of incrementing, send next value to other function as you will use that local variable value while printing in your function.
++i increments the value - it actually changes it (and evaluates as the updated value.)
++i, i++ and the subtle distinction between them has been the cause of many and frustrating bugs. This is just my opinion, but I advise never using either one of them except as a single-line statement when you need to increment something. The brevity isn't worth the risk of bugs.
So if you enter printArray with i=arr.length-1, then you get past your i guard, increment i, make the recursive call (which returns), and then try to access `arr[arr.length - 1 + 1], which is out of bounds.
If you're just learning about recursion, you might be confused at how local variables and returns work in a method. Each time you call a method, that's a new stack frame (a section of memory) with completely different values for its local variables, and which returns independently. i is not "i in every usage of the method named printArray", it's only "i in the current application of the method printArray." Similarly when you return, you cease to run the current application of printArray, but not every application.
Sorry if that part's all stuff you know - I find it's one of those things that's completely mind boggling to people starting out, and then becomes completely obvious a week later.
Im supposed to write a method divideByTwo that takes an integer as a parameter and returns the number divided by 2. and i need to try to solve the problem with a single program statement in the method. I don't know how to fix the problem, i've used modulo, while loop, changed the return value but still don't know what i am doing wrong. Any kind of help appreciated!
this is what i've done so far:
public static int divideByTwo(int a){
int i = 0;
while(i < 1){
System.out.print(a/2);
i++;
}
return a;
}
expected output
The reason why you are getting 51 when you're entering 10 in the example is because it prints 10/2 = 5 and then it returns i which is 1. Then you are printing the method with parameter 10 which prints 5 in the method and then 1 as the return value. If you just want to divide the number by two, then all you need to write in the method is return a/2; and then just print the method divideByTwo(a);.
You are out-thinking yourself. The method has a simple purpose - divide the value provided by 2 and return that result.
remove the print statement - there is nothing to print
remove the loop and loop variable - there is nothing to loop over
That leaves you with...
public static int divideByTwo(int a) {
return a;
}
... but we don't want a - we want a divided by 2. You did the division in your print statement so do that division in the return statement and you are done.
public static int divideByTwo(int a) {
return a/2;
}
The answer was in you all along!
i am trying to print numbers from 1 to 10 without using loops in java. When n+1 is passed to recursivefun method call in line 6,it works fine. But when n++ is passed,the code throws an error :/
public class PrintWithoutUsingLoops {
public static void recursivefun(int n) {
if (n <= 10) {
System.out.println(n);
recursivefun(n++);//an exception is thrown at this line.
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
recursivefun(1);
}
}
recursivefun(n++);
passes the original value of n to the recursive call (since you are using the post-increment operator), making this recursion infinite (since each recursive call gets the same value of n, which never reaches 11) and leading to StackOverflowError.
Change it to
recursivefun(n+1);
or
recursivefun(++n);
recursivefun(n++);
is a call with post-increment. Post increment is a mechanism which enlarges the value after it is read. In this case, you always pass 1.
You can use pre-increment which is ++n which first: increments and then passes the value.
The exception you get is StackOverflowError which means, that the stack is full and JVM cannot store more calls on stack, so it won't be able to revert.
recursivefun(n++);
This line means : call recursivefun(n); and then increment n by 1 so you'll always call your fuction with n=1 and caused a stackOverflow sure
So you need to increment n BEFORE all the function, you have some options :
recursivefun(n+1);
//-----------------------------
n++;
recursivefun(n);
//-----------------------------
recursivefun(++n); //pre-cincrement
Indeed both post and pre increment operators increments the value of a variable. Their behavior changes based on the context of the usage. Assume the following code:
For loop 1:
for (i=0; i<10; i++)
...
For loop 2:
for (i=0; i<10; ++i)
...
In both of the above statements, the for loop iterates 10 times irrespective of the increment style used. However consider the following code:
int x = 10;
int y = 20;
int z = x++ + ++y; // z = 10 + 21
System.out.println("x = " + x); // prints 11
System.out.println("y = " + y); // prints 21
System.out.println("z = " + z); // prints 31
Hence from your code it is evident that
recursivefun(n++);
calls recursivefun with argument 1 infinitely. To avoid StackOverFlow error use either ++n or n+1.
I have a global variable that I modify in three different methods. It starts at 0, one method adds by 3, the next one by 2 and the last one by 1. They are all related to a button of their own.
When I click the "plus 1" button, the counter remains at 0 and I need another push to get it to 1. Interestingly, if I start with the other two buttons the counter acts accordingly but if I click my "plus 1" button again, it needs two pushes and acts weird like if it was holding the add...
public void addThreeForTeamB(View view) {
displayForTeamB(scoreTeamB += 3);
}
public void addTwoForTeamB(View view) {
displayForTeamB(scoreTeamB += 2);
}
public void addOneForTeamB(View view) {
displayForTeamB(scoreTeamB ++);
}
So that's the way it is managed, the cool thing is that when I change the last method to a "scoreTeamB += 1" it acts as it should, just adding without conflict.
My question is about the difference between this two operators to better understand the reason behind the slight discrepancy generated when using this 2 operators on the same variable.
scoreTeamB++ returns the previous value of the variable (before it was incremented). += returns the value that was assigned to the variable.
If you replace scoreTeamB++ with ++scoreTeamB or with scoreTeamB +=1 you'll get the new (incremented) value of the variable.
To make this code work as you expect, you should use prefix ++ operator instead of postfix one. Prefix ++ operator(as well as -- operator, apparently) returns incremented value, while postfix operator ++ returns value of variable before increment.
Those may be implemented like this:
public static Integer prefixIncrement(Integer value) {
value = value + 1;
return value;
}
public static Integer postfixIncrement(Integer value) {
Integer returnValue = new Integer(value);
value = value + 1;
return returnValue;
}
can anybody explain this why its happening
int i=0;
i=i++;
i=i++;
i=i++;
System.out.println(i);
it prints zero.
i++ is a postincrement (JLS 15.14.2). It increments i, but the result of the expression is the value of i before the increment. Assigning this value back to i in effect keeps the value of i unchanged.
Break it down like this:
int i = 0;
int j = i++;
It's easy to see why j == 0 in this case. Now, instead of j, we substitute the left hand side with i. The right hand side value is still 0, and that's why you get i == 0 in your snippet.
You meant to do this:
int i = 0;
i++;
i++;
i++;
System.out.println(i);
i++ actually does an assignment so if you add an = you just confuse things. These other fine responders can give you the nitty gritty, some details of it escape me. :)
First thing is you should not write this kind of code....
But if we consider for the questions sake then this simple: It has to do with the way the postfix operator "returns" the value. A postfix has precedence over the assignment operator, but the postfix operator after incrementing the value of i returns previous value of i. So i get again assigned to its previous value.
And once again don't use this construct in your code as the next programmer who sees this will come after you (with something big in his hands) :)
Let I=++, an increase, and A=i, an assignment. They are non-commutative: IA != AI.
Summary
IA = "first increase then assignment"
AI="first assignment then increase"
Counter-Example
$ javac Increment.java
$ java Increment
3
$ cat Increment.java
import java.util.*;
import java.io.*;
public class Increment {
public static void main(String[] args) {
int i=0;
i=++i;
i=++i;
i=++i;
System.out.println(i);
}
}
Related
Initialization, assignment and declaration