Hi @DesmondLee,
Based on what I understand from this code, for Q2 I think it's this:
When you got p=20 and q=23, you attribute q=func(p, q);
This will make, inside the function, parameter p get the value of p (20), and y is 10 every time you call the function.
Since x%y in this case is 20%10 (which checks the if statement), p is incremented then returned (p=24), and q is the same value (23), because it was not a reference.
When you call it for p=func(q), it does this:
x=p (with reference, x=24)
y is an added variable inside the function (because func() was not called with 2 parameters) with the value 10 (y=10)
checking x%y means checking 24%10, which returns y--.
Since return ++y would have changed the value of y and THEN return it, return y++ means "return y then increment y's value". But since the function returns, then the value doesn't get to modify what p gets afterwards (only modifies a local variable in this case).
Therefore p=func(q) will result into p=10;
Now you have p=10 and q=23.
They are printed, and then it calls "q=func(p)".
Inside the function you have:
x=p (x=10)
y=10
the "x%y==0" statement checks, so the return is x++.
Since x here is p (passed as parameter with reference), it returns x's value (10) with increment (11), giving q the value 11.
Since x is a reference to p, then p is incremented once, making it 11.
So when they are printed, you have these values.
Hope this helps.