Why does this function print what it does?

If `f` and `g` are defined like this:

``````void f(int[] x, int[] y, int p, int q) {
for (int i = 0; i < x.length; ++i) {
x[i] = 2 * x[i];
}
x = new int[5];
for (int i = 0; i < 5; ++i) {
x[i] = 0;
}
y[3] = 5;
p = q + 1;
}

void g() {
int[] x = {1, 2, 3, 4};
int[] y = {9, 7, 6, 5};
f(y, x, y[0], x[0]);
for (int p : x) {
System.out.print("" + p + " ");
}
for (int q : y) {
System.out.print("" + q + " ");
}
System.out.println();
}
``````

then if you run `g()`, it prints `1 2 3 5 18 14 12 10`, and I don't know why.

How do `p` and `q` even come into the equation?

p and q are just variables which are used in for loop. Here the code uses "for each loop" which a variant of "for loop".

In **for each loop ** instead of declaring and initializing a loop counter variable, we declare a variable that is the same data type as the base type of the array or collection, followed by a semi-colon, which is then followed by the array or collection name.

to understand how for each loop work check out this answer-> How does the Java 'for each' loop work?

How do `p` and `q` even come into the equation?

Assuming you're asking about the parameters to method `f`:
`p = q + 1;` is a meaningless statement, since Java is "pass-by-value".

Also, the following code is meaningless for the same reason, since `x` is reassigned to a new array, the changes to `x` doesn't affect the values in the caller.

``````x = new int[5]; // caller is unaffected by this
for (int i = 0; i < 5; ++i) {
x[i] = 0; // meaningless, since new int[5] is pre-initialized to all zeroes
}
``````

Last part of confusion is caused by the swap of `x` and `y`. Method `f(x, y)` is called as `f(y, x)` in method `g`, so f's `x` is really g's `y`.

To help differentiate them, let's rename parameters of `f` to `a` and `b`. The new code (removing meaningless statements and parameters) is then:

``````void f(int[] a, int[] b) {
for (int i = 0; i < a.length; ++i) {
a[i] = 2 * a[i];
}
b[3] = 5;
}
``````

As you can see, it doubles the values of first argument, and changes 4th (index 3) value of second argument to `5`.

Which means that method call `f(y, x)` in method g will double values of `y` and change `x[3]` to `5`.

`x = {1, 2, 3, 4}` becomes `x = {1, 2, 3, 5}`
`y = {9, 7, 6, 5}` becomes `y = {18, 14, 12, 10}`

Which leads to printed output: `1 2 3 5 18 14 12 10`