previo arriba siguiente contenido
Previo: 13. C, UNIX y las Arriba: Manual de C Siguiente: 15. Biblioteca <math.h>
Regresar

Subsecciones

14. Biblioteca <stdlib.h>

Para usar todas las funciones de ésta biblioteca se debe tener la siguiente directiva

#include <stdlib.h>

Las funciones de la biblioteca pueden ser agrupadas en tres categorías básicas:

El uso de todas las funciones es sencillo. Se consideran dentro del capítulo en forma breve.

14.1 Funciones aritméticas

Hay cuatro funciones enteras básicas:

int abs(int j);
long int labs(long int j);
div_t div(int numer, int denom);
ldiv_t ldiv(long int numer, long int denom);

Fundamentalmente hay dos funciones para enteros y para compatibilidad con enteros largos.

La estructura div_t esta definida en stdlib.h como sigue:

typedef struct {
        int quot;  /* cociente */
        int rem;   /* residuo  */
} div_t;

La estructura ldiv_t es definida de una forma similar.

Se muestra un ejemplo donde se hace uso de la función div_t:

#include <stdlib.h>

main()
{
	int num=8, den=3;
	div_t res;

	res = div(num,den);

	printf("Respuesta:\n\t Cociente = %d\n\t Residuo = %d\n",
       res.quot, res.rem);
}

que genera la siguiente salida:

Respuesta:
         Cociente = 2
         Residuo = 2

14.2 Números aleatorios

Los números aleatorios son útiles en programas que necesitan simular eventos aleatorios, tales como juegos, simulaciones y experimentos. En la práctica ninguna función produce datos aleatorios verdaderos -- las funciones producen números pseudo-aleatorios. Los números aleatorios son calculados a partir de una fórmula dada (los distintos generadores usan diferentes fórmulas) y las secuencias de números que son producidas se repiten. Una semilla (seed) es usualmente inicializada para que la secuencia sea generada. Por lo tanto, si la semilla es siempre inicializada con el mismo valor todo el tiempo, el mismo conjunto será siempre calculado.

Una técnica común para introducir más aleatoriedad en el generador de números aleatorios es usando el tiempo y la fecha para inicializar la semilla, ya que éste siempre estará cambiando.

Hay muchas funciones de números (pseudo) aleatorios en la biblioteca estándar. Todas ellas operan con la misma idea básica pero generan secuencias diferentes de números (basadas en funciones generadoras diferentes) sobre rangos diferentes de números.

El conjunto más simple de funciones es:

int rand(void);
void srand(unsigned int semilla);

Un ejemplo sencillo del uso del tiempo de la fecha es inicializando la semilla a través de una llamada:

srand( (unsigned int) time( NULL ) );

El siguiente programa tarjeta.c muestra el uso de estas funciones para simular un paquete de tarjetas que esta siendo revueltas.

/*
** Se usan numeros aleatorios para revolver las "tarjetas" de la baraja.
** El segundo argumento de la funcion indica el numero de tarjetas.
** La primera vez que esta funcion es llamada, srand es
** llamada para inicializar el generador de numeros aleatorios.
*/
#include <stdlib.h>
#include <time.h>
#define VERDADERO    1
#define FALSO   0

void intercambiar( int *baraja, int n_cartas )
{
    int     i;
    static  int     primera_vez = VERDADERO;

    /*
    ** Inicializar el generador de numeros con la fecha actual
    ** si aun no se ha hecho.
    */
    if( primera_vez ){
        primera_vez = FALSO;
        srand( (unsigned int)time( NULL ) );
    }

    /*
    ** "intercambiar" empleando pares de cartas.
    */
    for( i = n_cartas - 1; i > 0; i -= 1 ){
        int     alguno;
        int     temp;

        alguno = rand() % i;
        temp = baraja[ alguno ];
        baraja[ alguno ] = baraja[ i ];
        baraja[ i ] = temp;
    }
}

14.3 Conversión de cadenas

Existen unas cuantas funciones para convertir cadenas a enteros, enteros largos y valores flotantes. Estas son:

Varias de las funciones se pueden usar en forma directa, por ejemplo:

char *cad1 = "100";
char *cad2 = "55.444";
char *cad3 = "      1234";
char *cad4 = "123cuatro";
char *cad5 = "invalido123";
char *cad6 = "123E23Hola";
char *cad7;

int i;
float f:

i = atoi(cad1);    /* i = 100 */
f = atof(cad2);    /* f = 55.44 */
i = atoi(cad3);    /* i = 1234 */
i = atoi(cad4);    /* i = 123 */
i = atoi(cad5);    /* i = 0 */
f = strtod(cad6, &cad7);  /* f=1.230000E+25 y cad7=hola*/

Nota:

14.4 Búsqueda y ordenamiento

La biblioteca stdlib.h tiene dos funciones útiles para hacer búsqueda y ordenamiento de datos de cualquier tipo. La función qsort() ya fue vista previamente en la sección 10.3.

Para completar la lista se anota el prototipo, pero para ver un ejemplo pasar al capítulo indicado.

La función qsort de la biblioteca estándar es muy útil, ya que esta diseñada para ordenar un arreglo por un valor llave de cualquier tipo en orden ascendente, con tal de que los elementos del arreglo sean de un tipo fijo.

El prototipo de la función de acuerdo a stdlib.h es:

    void qsort(void *base, size_t nmiemb, size_t tam,
        int (*compar)(const void *, const void *));

Similarmente, hay una función para búsqueda binaria, bsearch() la cual tiene el siguiente prototipo en stdlib.h como:

       void *bsearch(const void *key, const void *base, size_t nmemb,
              size_t size, int (*compar)(const void *, const void *));

A continuación se muestra un ejemplo que hace uso de la función bsearch():

#define TAM 10 
#include <stdio.h> 
#include <stdlib.h> 

typedef struct {
	int llave;
	char informacion[30];
} Registro;

int compara_registro(void const *i, void const *j)
{
	int a, b;

	a = ((Registro *) i)->llave; 
	b = ((Registro *) j)->llave;
	return a - b;
}

main()
{
	Registro llave;
	Registro *resp;
	Registro arreglo[TAM];
	int long_arreglo = TAM;

	arreglo[0].llave = -43; arreglo[1].llave = -9; arreglo[2].llave = 0;
	arreglo[3].llave = 3; arreglo[4].llave = 4; arreglo[5].llave = 9;
	arreglo[6].llave = 10; arreglo[7].llave = 12; arreglo[8].llave = 30;
	arreglo[9].llave = 203;

	printf("Introduce el valor de la llave que se buscara en el arreglo: ");
	scanf("%d",&llave.llave); /* valor del indice que sera buscado */
	resp = (Registro *) bsearch(&llave, arreglo, long_arreglo, sizeof(Registro), 
                  compara_registro);
	if (resp != NULL )
		printf("Se localizo la llave %d\n",resp->llave);
	else
		printf("No se localizo ningun elemento con la llave %d\n", llave.llave);
}

La función bsearch() regresa un apuntador al registro que coincide con la llave dada, o bien, el valor NULL si no encuentra el registro.

Observar que el tipo del argumento de la llave debe ser del mismo tipo que la del arreglo de los elementos (en nuestro caso Registro).

14.5 Ejercicios

  1. Escribir un programa que simule el lanzamiento de un dado.
  2. Escribir un programa que simule el melate, en donde se seleccionan 6 números enteros en un rango de 1 al 44
  3. Escribir un programa que lea un número de la línea de entrada y genere un número flotante aleatorio en el rango de 0 a el número de entrada.


previo arriba siguiente contenido
Anterior: 13. C, UNIX y las Subir: Manual de C Siguiente: 15. Biblioteca <math.h>   Índice General
Última modificación : 2005-08-12
Héctor Tejeda V
<- htejeda@fismat.umich.mx