Hola,
Antes que nada, me alegra saber que estás estudiando ciencia de la computación. Es un bonito camino, y te deseo la mejor de las suertes en tu estudio.
Pasando al tema del lenguaje C, también encuentro muy positivo el hecho de que en tu curso estén tratando éste lenguaje. Como ya te lo ha dicho nuestro amigo, puede que sea buena idea que comienzes consultando un poco en libros o material en línea sobre este lenguaje, al menos sobre las cosas básicas. Más adelante, cuando ya vayas sintiendo que vas captando la idea del asunto, puedes venir a foros como éste y pedir ayuda sobre temas más específicos.
En todo caso, pienso que es buena idea en muchos casos tomar un programa específico, y estudiarlo minuciosamente. Tras haber adquirido cierta teoría, el siguiente paso natural es dedicarse a escribir programas propios y probar... y probar... y seguir probando. Es una experiencia gratificante y agradable cuando uno siente entusiasmo por lo que está haciendo, cosa que en tu caso es muy posible que ocurra dado que estás estudiando ciencia de la computación.
Brian Kernighan y Dennis Ritchie, autores del que podría ser considerado el libro más famoso sobre el lenguaje C de todos los tiempos, han dicho alguna vez: "La única manera de aprender un nuevo lenguaje de programación es escribiendo programas en él".
Volviendo a tu programa... pienso que nos favorece que sea corto y resuelva un problema relativamente simple. Trataré de ofrecerte una explicación más o menos detallada de su funcionamiento, haciendo la salvedad de que he modificado (considerablemente) el código que escribiste, con el propósito de que sea un programa más legible y completo.
Una sugerencia, antes de comenzar. Aquellas cosas que te parecen exóticas y no terminas de entender muy bien para qué sirven, por ahora ignóralas y no dejes que te produzcan dolores de cabeza. Con el tiempo esos vacíos irán siendo llenados y todo empezará a tener mucho más sentido. Por ahora que apenas comienzas, no hay ninguna necesidad de tratar de entenderlo todo de un sólo golpe. Si en realidad sientes tanta curiosidad que no puedes dormir pensando en qué significan algunas cosas, ahí es cuando los libros y el material de referencia te puede resultar muy útil... :)
Código:
#include <stdio.h>
#define MAX 20 /* Maximo numero de elementos con los que opera el
* programa */
/* Prototipos de funciones */
void llenar (int *, int);
int es_primo (int);
/* Funcion principal */
int
main (void)
{
int a[MAX];
int n, i;
printf ("Ingrese la dimension del arreglo: ");
scanf ("%d", &n);
llenar (a, n);
printf ("\nA continuacion, se listaran los numeros primos.\n\n");
for (i = 0; i < n; i++)
if (es_primo (a[i]))
printf ("El numero %d es primo.\n", a[i]);
return 0;
}
/* llenar()
*
* Funcion que recibe un arreglo de valores enteros y el tamanyo de
* este, y pide al usuario los valores para llenar el arreglo. */
void
llenar (int a[], int n)
{
int i;
printf ("\nA continuacion ingrese por favor los siguientes numeros:\n");
for (i = 0; i < n; i++) {
printf (" #%d: ", i + 1);
scanf ("%d", &a[i]);
}
}
/* es_primo()
*
* Funcion que recibe un numero entero, y retorna un 1 si el numero es
* primo, o 0 de lo contrario. */
int
es_primo (int n)
{
/* Para saber si un numero es primo o no, existen muchos
* metodos. En esta ocasion, por razones de simplicidad, vamos a
* hacer lo siguiente: calcularemos el residuo resultante de
* dividir el numero `n' con cada uno de los de los numeros de la
* secuencia 2, 3, 4, ... hasta n/2 (es decir, la mitad de n). Si
* alguno de estos residuos es cero, quiere decir que el numero
* `n' es divisible por un numero diferente a el mismo o la
* unidad, lo cual quiere decir que no es primo. Si ninguno de los
* residuos fue cero, entonces se sabe con certeza que el numero
* efectivamente es primo. */
int i;
for (i = 2; i <= n / 2; i++)
if (n % i == 0)
return 0;
return 1;
}
Ahora, separándolo un poco por partes:
La primera línea lo que hace es incluir una librería estándar. La librería que incluye, stdio.h, es muy útil en programas simples como éste, y es la que trae funciones como printf() y scanf(), por ejemplo, que son usadas en este programa.
La directiva `define' sirve para definir macros. En su forma más básica, como la que tiene en este programa, sirve para definir ciertos nombres o alias que servirán de reemplazo para ciertas expresiones simples. En este programa, por ejemplo, cada vez que se use la macro `MAX', ésta será reemplazada por el valor 20.
Los prototipos de funciones, ubicados a continuación, sirven para declarar tempranamente al compilador de C el uso de ciertas funciones, indicando cómo se van a llamar esas funciones, cuántos y qué tipos de datos recibe, y qué tipo de datos retorna. Dependiendo del orden en que definas las funciones de tu programa, los prototipos pueden ser opcionales o no. Como este programa incluye dos funciones, llenar() y es_primo(), aquí decidimos declarar de una vez los prototipos de ambas funciones.
Luego viene el inicio de la función main(). Declaramos explícitamente que ésta retorna un valor entero (que le será entregado al sistema operativo) y que no recibe nada.
Al comienzo de la función main() se declaran las variables locales. Hay un arreglo de 20 enteros llamado `a', y dos variables enteras, `n' e `i'.
Las funciones printf() y scanf() son usadas para mostrar datos al usuario, y recibir datos del usuario, respectivamente. Le mostramos un mensaje al usuario, y a continuación decimos que el usuario debe ingresar un dato por teclado, y éste dato debe ser almacenado en la variable `n'. El simbolito raro, `&', sirve para hacer referencia a la dirección de memoria en donde está almacenada una variable. Por ahora no necesitas preocuparte mucho por esto, sólo ten en cuenta que cuando quieras recibir datos por el teclado mediante scanf() y almacenarlos en variables tipo `int' o `char', por ejemplo, vas a necesitar ese simbolito.
Luego se hace un llamado a una función, llenar(), y se le envia como parámetros el arreglo `a' y la variable `n'. Más adelante hablaremos de esta función.
Se despliega un nuevo mensaje, y luego se ejecuta un ciclo que por cada elemento del arreglo `n' que tiene valores ingresados por el usuario, determina si el elemento estudiado es primo o no. Para este efecto, hace llamados a la función es_primo(). Para cada elemento que resulta ser primo, imprime un mensaje.
Finalmente, la función main() se cierra retornando un valor de cero al sistema operativo, lo que quiere decir que la ejecución del programa fue exitosa y no hubo ningún error grave.
Luego están las dos funciones que usamos. En el caso de llenar(), esta función no retorna nada (lo cual se indica mediante la palabra clave `void'), y recibe un arreglo de enteros y un número entero que será usado como tamaño del arreglo. La función usa internamente printf() y scanf() para pedir, cíclicamente, tantos valores enteros como el valor de `n' lo indique.
Dos cosas para tener en cuenta aquí: cuando se reciben arreglos como parámetros de funciones, no se necesita (no tiene sentido) especificar el tamaño del arreglo explícitamente. Es por eso que dentro de los corchetes cuadrados no se escribió ningún número. Además, es importante saber que las variables `a' y `n' en la función llenar() son locales; es decir, no son las mismas que se encuentran en main().
Finalmente está la función es_primo(). El algoritmo usado está descrito de forma general en los comentarios. Lo único que se me ocurre que vale la pena señalar aquí es que el símbolo `%' en C actúa como operador matemático que calcula el residuo de una división.
Bien, eso es todo, por ahora. Nuevamente te reitero que siempre es buena idea buscar la ayuda de libros o guías para entender cosas como la sintaxis básica de un lenguaje de programación, por ejemplo. Por lo demás, muy buena suerte y que estés muy bien.