Los punteros se utilizan para gestionar las direcciones de memoria de las variables que utilizas. Supongo que hablas de C (por lo de * y &), así que también sirven para pasar argumentos por referencia a las funciones (argumentos que van a ser modificados y quieres que prevalezca la modificación al acabar la función) y para declarar variables dinámicas, con el correspondiente "ahorro " de espacio en ciertos casos si el tamaño de la variable no es constante. Digo "en ciertos casos" porque si estamos hablando de vectores pequeños ( o si hay suficiente espacio), a veces es mejor declararlos de forma estática y no como punteros, por la forma de asignar memoria con malloc (función en C para reservar memoria para una variable declarada como puntero).
Una variable declarada como puntero no es más que una variable en la que vas a almacenar una dirección de memoria . Por ejemplo: int *puntero; puntero guardará una dirección de una variable entero. Para poder usarla, es necesario reservar un espacio de memoria (que después tendrás que liberar con free(puntero)) para almacenar la variable a la que apunta. Lo más habitual es usar malloc (te recomiendo que mires algún manual para ver cómo se usa) para la reserva de memoria. Otra forma de hacerlo sería, por ejemplo:
int *puntero;
int numero;
puntero = №
(es decir, puntero almacena la dirección de número, que ya tiene espacio reservado).
En cuanto a & y *.
En la declaración de una variable, por ejemplo int *puntero, el asteristo quiere decir que estás declarando la variable como un puntero (o apuntador).
En cambio, si en otro punto del programa haces *puntero, te estás refiriendo al contenido de la dirección a la que apunta puntero (se conoce como desreferenciar un puntero). Si haces &numero, estás refiriéndote a la dirección de memoria de número.
Un ejemplo:
int *puntero;
//declara puntero como un apuntador a un entero
int numero = 6;
int numero2;
Ahora mismo, puntero tiene un valor indefinido (no apunta a ninguna variable).
puntero = №
Ahora, puntero guarda la dirección en la que se almacena numero.
numero2 = *puntero;
Ahora, numero2 tiene el mismo valor que numero.
La aritmética de punteros requiere bastante práctica, así que te recomendaría que cogieras en alguna biblioteca algún manual de C y le echases un ojo a la parte de punteros y arrays (o apuntadores y arreglos), ya que seguro que los ejemplos y las explicaciones son mucho más claras.