sábado, 2 de julio de 2011

Generación de Números Aleatorios en C

La generación de números aleatorios es muy frecuente en una gran cantidad de programas. Sobre todo, programas que simulan juegos de azar. El siguiente código genera 100 números aleatorios entre 1 y 10.

/*********************************************************
* Este programa genera 100 numeros aleatorios entre 1 y  *
* 10                                                     *
**********************************************************/

# define Tamano 100
/* La variable Tamano determina el numero
   de numeros aleatorios que se generaran */
#include <stdio.h>
#include <time.h>
/* Este encabezado se incluye para usar time() */
 
int main()

{         /*Abre main*/
 
int numero;
int i;
 
srand(time(NULL));
/* Si se comenta srand() los numeros generados
   seran siempre los mismos */
 

for ( i = 1; i <= Tamano; i++ )
{     /* Abre for*/
numero = 1 + rand() % 10;
printf("\t%d", numero);
 
printf((0 == i % 10)?"\n" :"" );
/* cada 10  numeros se imprime un salto de linea */
}      /*Cierra for*/
 
return 0; 

}         /*Cierra main*/


Una ejecución de éste programa, genera la siguiente salida:

4 7 6 10 3 10 8 10 1 6
 10 6 9 3 10 3 10 10 7 1
 4 10 2 6 9 3 2 9 4 10
 8 7 7 4 8 1 3 6 10 5
 1 10 3 2 2 2 6 3 4 2
 3 7 1 6 4 1 1 7 2 4
 7 9 3 3 4 2 3 8 7 2
 3 10 3 7 3 6 8 10 9 3
 1 3 1 3 9 4 6 9 3 7
 4 9 7 8 3 3 10 7 10 8

_____________________________________________________________________________________
Ahora hagamos un análisis del programa línea por línea para revisar cada instrucción
Las líneas

/*********************************************************
* Este programa genera 100 numeros aleatorios entre 1 y  *
* 100                                                    *
**********************************************************/

son un comentario. Este comentario indica de manera general qué hace el programa, y es generar 100 números aleatorios entre 1 y 10. En C los comentarios inician con /* y terminan con los caracteres */

#define Tamano 100
/* La variable Tamano determina el numero
   de numeros aleatorios que se generaran */

Aquí se define la variable simbólica TAMANO y se le asigna el número 100. Si se quiere generar una cantidad distinta de números aleatorios, sólo hay que cambiar esta variable. La siguientes líneas son un comentario.

#include <stdio.h>

El encabezado stdio.h incluye las definiciones de las funciones printf, rand y srand, que serán usadas más adelante.

#include <time.h>
/* Este encabezado se incluye para usar time() */

El encabezado time.h indica que se usarán las funciones empaquetadas en la biblioteca estándar. En particular se usará la función time(), como lo indica el comentario a continuación.

int main()

{         /*Abre main*/

El cuerpo de la función main() se inicia con una llave izquierda. A partir de ésta llave, empieza la ejecución del programa.

int numero;
int i;

En el lenguaje de programación C, las variables deben definirse antes de ser usadas. Con éste par de líneas estamos declarando dos variables de tipo entero llamadas numero y i. La variable numero será la que almacenará los números aleatorios generados. i será utilizada como contador en el cuerpo del ciclo for a continuación.

srand(time(NULL));
/* Si se comenta srand() los numeros generados
   seran siempre los mismos */
 

Éstas líneas del programa se comentan un poco más adelante. Basta decir que la función srand() recibe un entero sin signo y no regresa un valor, sólo hace que los números que genera la función rand() no sean los mismos.

for ( i = 1; i <= Tamano; i++ )
 {     /* Abre for*/

Éste ciclo for itera desde 1 hasta Tamano (100) las instrucciones contenidas en el cuerpo que inicia a partir de la llave {. Como recomendación,para cada llave que se abre o cierra, debe de indicarse la instrucción a la que pertenece.

numero = 1 + rand() % 10;

rand() es la función que genera los números, es una función que no recibe argumentos y retorna un entero. Una instruccion como x = rand(); genera un numero entero pseudoaleatorio entre 0 y RAND_MAX, que es una constante definida por el encabezado y que es al menos 32767 (el tamaño de un entero de 2 bytes, 16 bits). Este número, sin embargo, es demasiado grande para la mayoría de los casos prácticos en programación, por ejemplo, si se quiere simular el lanzamiento de un dado se necesitan números entre 1 y 6, y no entre 0 y 32767.
Para poder acotar los números, se usa el operador de módulo %. Una instrucción como numero % 10 genera números entre 0 y 9. Sea por caso que la variable numero = 58, el residuo de la división 58/10 es 8. Si numero = 687, el residuo de la división 687/10 es 7. Puede verse que con cualquier número natural, la instrucción numero%10 produce números entre 0 y 9.
Para lograr que esos números estén en el rango 1 y 10, se suma un 1 a la expresión anterior.
Para generar números entre 1 y n, es necesario usar una expresión como:

numero = 1 + rand() % n;

¿Por qué se dice que rand() genera números pseudoaleatorios? Porque siempre que se ejecuta el programa se generan los mismos enteros, si usted comenta la instrucción srand(time(NULL)); entonces verá que cada vez que ejecute el programa saldrán los mismos valores. ¿Cómo se generan entonces números aleatorios? con void srand(unsigned int seed); que es una función que hace que los números generados por rand() sean distintos cada vez. Esta función, como se especifica en su prototipo, recibe un entero sin signo, llamado comunmente semilla; cada vez que srand() recibe una semilla distinta hace que rand() genere un número distinto. Se puede modificar el programa para que pida al usuario que introduzca una semilla cada vez, y así se generarán números aleatorios. Sin embargo, esto puede ser bastante inconveniente para la mayoría de los casos. Es por eso que se utiliza la función time() con el argumento NULL. time() está definida en el encabezado , y NULL en time(NULL) devuelve cada vez la hora de la computadora, por lo cual siempre se está utilizando una semilla distinta. Así es posible generar números aleatorios en C.

printf("\t%d", numero);

Después de generar el número aleatorio, se imprime dejando el espacio de un tabulador con el número anterior.

printf((0 == i % 10)?"\n" :"" );
/* cada 10  numeros se imprime un salto de linea */

Como lo indica el comentario, la función printf sólo imprime un salto de línea cada vez que el contador i es un múltiplo de 10. Ésto es sólo para imprimir la lista con algo de formato.

}      /*Cierra for*/
 

Una llave derecha indica el fin del cuerpo de instrucciones de for.

return 0; 

}         /*Cierra main*/
 

la instrucción return 0; indica el fin de la función main. El cuerpo de main debe cerrarse con una llave derecha: }.
_______________________________________________________________________________________________
Lo que aprendió:
La generación de números pseudoaleatorios con la función rand()
La generación de números aleatorios con la función srand()

_______________________________________________________________________________________________
Esta entrada forma parte del Curso de C con Programas Explicados Línea por Línea
Índice
Entrada Anterior

2 comentarios:

Related Posts Plugin for WordPress, Blogger...

¿Qué lenguaje de programación usas?