Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


7.9. Algunas funciones útiles

7.9.1. Números aleatorios

En un programa de gestión o una utilidad que nos ayuda a administrar un sistema, no es habitual que podamos permitir que las cosas ocurran al azar. Pero los juegos se encuentran muchas veces entre los ejercicios de programación más completos, y para un juego sí suele ser conveniente que haya algo de azar, para que una partida no sea exactamente igual a la anterior.

Generar números al azar ("números aleatorios") usando C no es difícil. Si nos ceñimos al estándar ANSI C, tenemos una función llamada "rand()", que nos devuelve un número entero entre 0 y el valor más alto que pueda tener un número entero en nuestro sistema. Generalmente, nos interesarán números mucho más pequeños (por ejemplo, del 1 al 100), por lo que "recortaremos" usando la operación módulo ("%", el resto de la división).

Vamos a verlo con algún ejemplo:

Para obtener un número del 0 al 9 haríamos x = rand() % 10;
Para obtener un número del 0 al 29 haríamos x = rand() % 30;
Para obtener un número del 10 al 29 haríamos x = rand() % 20 + 10;
Para obtener un número del 1 al 100 haríamos x = rand() % 100 + 1;
Para obtener un número del 50 al 60 haríamos x = rand() % 11 + 50;
Para obtener un número del 101 al 199 haríamos x = rand() % 100 + 101;

Pero todavía nos queda un detalle para que los números aleatorios que obtengamos sean "razonables": los números que genera un ordenador no son realmente al azar, sino "pseudo-aleatorios", cada uno calculado a partir del siguiente. Podemos elegir cual queremos que sea el primer número de esa serie (la "semilla"), pero si usamos uno prefijado, los números que se generarán serán siempre los mismos. Por eso, será conveniente que el primer número se base en el reloj interno del ordenador: como es casi imposible que el programa se ponga en marcha dos días exactamente a la misma hora (incluyendo milésimas de segundo), la serie de números al azar que obtengamos será distinta cada vez.

La "semilla" la indicamos con "srand", y si queremos basarnos en el reloj interno del ordenador, lo que haremos será srand(time(0)); antes de hacer ninguna llamada a "rand()".

Para usar "rand()" y "srand()", deberíamos añadir otro fichero a nuestra lista de "includes", el llamado "stdlib":

#include 

Si además queremos que la semilla se tome a partir del reloj interno del ordenador (que es lo más razonable), deberemos incluir también "time":

#include 

Vamos a ver un ejemplo, que muestre en pantalla un número al azar entre 1 y 10:

/*---------------------------*/
/*  Ejemplo en C nº 69:      */
/*  C069.C                   */
/*                           */
/*  Obtener un número al     */
/*  azar                     */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/

#include 
#include 
#include 

int main() {
    int n;
    srand(time(0));
    n = rand() % 10 + 1;
    printf("Un número entre 1 y 10: %d\n", n);
   
    return 0;
}

Ejercicios propuestos:

7.9.2. Funciones matemáticas

Dentro del fichero de cabecera "math.h" tenemos acceso a muchas funciones matemáticas predefinidas en C, como:

La raiz cuadrada de 4 se calcularía haciendo x = sqrt(4);
La potencia: para elevar 2 al cubo haríamos y = pow(2, 3);
El valor absoluto: si queremos trabajar sólo con números positivos usaríamos n = fabs(x);

Ejercicios propuestos:

7.9.3. Pero casi todo son funciones…

Pero en C hay muchas más funciones de lo que parece. De hecho, casi todo lo que hasta ahora hemos llamado "órdenes", son realmente "funciones", y la mayoría de ellas incluso devuelven algún valor, que hasta ahora habíamos despreciado en muchos casos.

Vamos a hacer un repaso rápido a las funciones que ya conocemos y el valor que devuelven:

Función

Valor devuelto

Significado

main

int

Programa terminado correctamente (0) o no (otro)

printf

int

Número de caracteres escritos

scanf

int

Número de datos leídos, o EOF si hay error

putchar

int

El carácter escrito, o EOF si hay algún error

getchar

int

Siguiente carácter de la entrada, o EOF en caso de error

gets

char*

Cadena si todo va bien o NULL si hay error

puts

int

EOF si hay algún error, otro número (un entero positivo) si no lo hay

strcpy, strncpy

char*

Cadena resultado de la asignación

strcat

char*

Cadena resultado

strcmp

int

0 si las cadenas son iguales, <0 si la primera “es menor” o >0 si la primera “es mayor”

sprintf

int

Número de caracteres almacenados en la cadena (en alguna versión, como BSD, devuelve la cadena creada)

sscanf

int

Número de datos leídos, o EOF si hay error

fopen

FILE*

NULL si hay error

fclose

int

0 si todo va bien o EOF si hay error

fputs

int

EOF si hay algún error, otro número (no especificado) si no lo hay

fgets

char*

NULL si hay error o fin de fichero

feof

int

0 si no es final de fichero, otro valor si lo es

fprintf

int

Número de bytes escritos (puede no ser fiable si se está escribiendo a un buffer antes de mandar a disco).

fscanf

int

Número de datos leídos, o EOF si hay error

fgetc

int

El carácter leido, o EOF si hay algún error

fputc

int

El carácter escrito, o EOF si hay algún error

fread

int

Número de bytes leidos (0 o menor de lo previsto si hay error)

fwrite

int

Número de bytes escritos (0 o menor de lo previsto si hay error)

fseek

int

0 si se ha saltado correctamente; otro valor si el fichero no está abierto o no se ha podido saltar

ftell

long (size_t)

Posición actual en el fichero (en bytes) o -1L en caso de error

 

 

(Nota: expresiones como "FILE*" ya las conocemos, aunque todavía no entendemos bien a qué se refieren: otras como "char*" son nuevas para nosotros, pero las veremos con detalle en el próximo tema).

Por el contrario, las siguientes "órdenes" no son funciones, sino "palabras reservadas" del lenguaje C: if, else, do, while, for, switch, case, default, break, int, char, float, double, struct.

Ejercicios propuestos: