Standard library function scanf() expects a pointer corresponding to the data you want to read. So you are always required to pass a pointer.
In case of char[], the array name decays into a pointer to the first element of the array, which is why you don't use & for char arrays. In fact, using an ampersand (&) for a char array when passing to scanf(), is wrong as the type of &charArray is char (*)[N] whereas scanf() expects a char* for the format specifier %s.
In case if you have pointers, then you can simply pass them directly. E.g.
int *p;
char *c;
p = malloc(sizeof(int)); // one int
c = malloc(100); // 100 bytes
scanf("%d%99s", p, c);
As said above, you don't use & here as the arguments are already pointers and using & is wrong as that will make them pointer to pointers.
So you use & whenever the argument to scanf() is not a pointer to an object of the type you want to read in.