Realmente podrías haber resuelto esta función cómo si estuvieras en Java, no hay mucha diferencia. Pero debo decir que sí, tu algoritmo para es_primo es erróneo.
Una solución sería esta:
int es_primo ( int p ) {
int divisor;
/* Casos base */
/* Falta por decidir qué se hace con los números menores de 1 */
if( p == 1 ) return 0; /* El 1 no se considera primo. */
if( p == 2 ) return 1; /* El 2 se considera primo. */
if( p & 1 == 0) return 0; /* Ningún par, a excepción del 2 (controlado anteriormente) es primo. */
for(divisor = 3; divisor * divisor <= p; divisor += 2) { /* Se usará el divisor a partir del tres, con incremento de 2 (así se evita operar con pares) */
if ( p % divisor == 0) /* hasta que el producto del divisor supere al número p (así nos evitamos la raíz cuadrada). */
return 0; /* Si la división da un residuo 0 quiere decir que ese número no es primo. Se regresa con 0. */
}
return 1; /* Si el algoritmo llega hasta aquí significa que el número es primo. */
}
Como ya viste C supongo que estás familiarizada con C entiendo que el operador de bit & te suena.