funcbeing some arbitrary user defined function
It couldn’t be “arbitrary” – it must take a pointer to int or a void* in order for the call to be legal.
This ampersand is the “take address” operator. It passes func the address of a, so that the func could, for example, modify it:
void func(int *pa) {
*pa = 4; // Note the asterisk - it "undoes" the effect of the ampersand
}
If your main prints a after the call to func, it prints 4 instead of 3.
Note that if you pass a instead of a pointer to a to a function that takes an int, not an int*, then modifications done to that int inside the function will have no effect on the parameter that you pass, because in C parameters are passed by value.
the variable a in the actual code is probably global or extern or something
It is probably not global, because there is no point in passing globals around: by virtue of being global, they are already accessible from everywhere.