First, the most important difference between C pointers and Perl references is that there is no pointer arithmetic in Perl.
Second, in answer to your questions:
- The @_ array is special in Perl. On entry to a sub, it contains aliases to the arguments that were passed; $_[2] = 42; will set whatever variable was used as the third argument to 42. On line 28 of your code, $pointer_to_diff will itself be set to the difference; note that printing it emits an integer instead of a reference debugging value. On line 31, you pass a newly-constructed reference to $diff instead; that reference is itself an SV, so its value gets overwritten just before it is discarded. The $diff variable itself is never actually set. Devel::Peek is likely to be helpful here.
- As an lvalue, it means to assign to the variable to which the reference points. Since $res is itself a reference to the alias of the parameter that was passed in, this will replace the value that was passed in. On line 28, that is the $pointer_to_diff variable. On line 31, that is an anonymous temporary constructed to hold a reference to $diff.
- The earlier two answers answer this as well.
Lastly, read the documentation, particularly, perlreftut, perlref, and perldsc.