La idea es la siguiente.
Si los valores que querés devolver son solo para ser devueltos, podés devolver un registro o un arreglo definido anteriormente, del tipo.
struct resultado {tipo1 var1; ... ; tipon varn;};
resultado funcion(){ resultado aux; ... cargás el aux; ... return aux;};
Eso es devolver muchos valores, otra forma, es declarar las variables en las que querés almacenar los valores fuera de la función y pasarlas como referencia. La diferencia es que c cuando vos le pasás un parámetro, la función crea una variable y copia los valores de la variable que le pasaste, al ponerle un & antes de la variable, le avisás que tome no la variable sino la dirección de la misma. Pudiendo así acceder así de forma directa a las variables y modificarlas dentro de tu función y guardando esos cambios en las variables.
En un caso común, los cambios realizados en las variables quedarían obsoletos, ya que la variable creada en base al parámetro que le pasaste pierde ámbito cuando termina la llamada a la función.