librerías y más funciones
En la lección anterior aprendimos a usar dos funciones importantísimas, fprintf y fscanf, que servían respectivamente para usar la salidas y entradas estándar y con ello poder hablar y escuchar a nuestra máquina. Estas dos funciones, como ya se comentó, se encuentran dentro de stdio.h, la librería que incluiamos siempre en nuestros programas. Si quitamos esa linea de #include e intentamos usar fprintf o fscanf el compilador nos devolverá un error diciendo que "no tiene ni idea de que es eso de fprintf que hemos puesto en la linea X".
Asimismo también se habló de fflush, función para limpiar los buffers de entrada. fflush también pertenece a stdio.h, y junto a estas tres hay exactamente cuarenta funciones más dentro de la libreria stdio. Os iré presentando algunas de ellas a lo largo del curso cuando sea necesario su uso. Si teneis curiosidad por saber como se llaman y qué hacen podeis echarlas un ojo aquí.
La librería math.h
Nuestro programa puede llevar incluido el número de librerias que queramos y una de las más versátiles se encarga de realizar operaciones matemáticas más allá de las típicas que podíamos calcular con los operadores +-*/. Esta librería es math.h. Puesto que esta librería se encarga de operar matemáticamente con la máxima precisión posible, sólo usa numeros con decimales, pero no los float que ya conocemos, sino otro tipo, llamado de doble precisión: double.
float num1 = 232.5431;
double num2 = 232.5431;
// ambas variables guardan el mismo valor, pero num2 ocupa el doble de memoria, siendo más preciso al operar
Por cierto, si usabamos %d para los enteros y %f para floats, double usa también %f. De este modo podemos imprimir números double.
math.h tiene las siguientes utilidades:
- Operaciones con Potencias y raices:
// sqrt -> square root, calcula la raiz cuadrada del numero de entrada
var1 = sqrt(64);
// pow ->power, calcula e; resultado de elevar el primer numero de entrada al segundo
var2 = pow(2, var1);
//que resultados almacenan ahora var1 y var2?
Probablemente con esta notación ententais perfectamente estods dos ejemplos, pero por ser algo más ortodoxos a partir de ahora usaré el prototipo para explicar nuevas funciones. Qué es el prototipo de una función? El prototipo define en una sola linea los parametros de entrada, de salida y el nombre de la función, y nos será muy útil cuando las funciones de las librerías no nos basten y tengamos que definir las nuestras propias.
Los prototipos de las dos funciones anteriores son los siguientes:
double sqrt(double x);
double pow(double x, double y);
En el caso de sqrt, su parámetro de entrada es un número, cosa que ya sabiamos, en concreto un double, devolviendo a su salida a la izquierda otro double con el resultado de la operación. Del mismo modo pow recibe dos numeros y devuelve otro.
Procurad no liaros con todo lo que he dicho ahora, el prototipo es una manera de resumir la función en una linea, pero no tendreis que escribir double pow(double x, double y); en ningun sitio en vuestro codigo nunca. Limitaos a usar estas funciones como se hizo la primera vez, devuelven un valor y con el operador = lo metes dentro de una variable.
Otras operaciones dentro de math.h son las trigonométricas:
// seno, coseno, tangente
double sin(double x);
double cos(double x);
double tan(double x);
// arcoseno, arcocoseno, arcotangente
double asin(double x);
double acos(double x);
double atan(double x);
Logaritmos
//logaritmo en base e (logaritmo neperiano)
double log(double x);
//logaritmo en base 10
double log10(double x);
Operaciones de redondeo
//redondeo al entero más cercano
double round(double x);
//redondeo al entero menor
double floor(double x);
//redondeo al entero mayor
double ceil(double x);
math.h contiene alguna función más pero no las veo vitales a estas alturas, de todos modos la técnica a seguir no es aprenderse de memoria todas estas funciones, sino saber buscarlas cuando las necesitas. Para ello podeis ir por ejemplo aqui, que como vereis, también se usa la notación de prototipos para presentaros cada función.
La librería stdlib.h
Además de stdio y math, otra de las librerías clásicas de ANSI C es la llamada librería estándar, stdlib.h.
stdlib contiene muchas funciones interesantes, pero de momento voy a limitarme unicamente a tres. La mas importante ya la habéis usado algunos en los deberes, y es system.
system("color 37");
system("tree");
//... etc
system se usa para correr comandos de la consola de windows. Exactamente los mismos con los que se navegan por los directorios y cualquier cosa del cmd.
Esta función puede tener muchas ultilidades para vuestros programas, por ejemplo:
Borrar la pantalla de la consola
system("cls");
Apagar la máquina en una hora (3600 segundos)
system("shutdown -s -t 3600");
Pausar el programa hasta el siguiente keystroke
system("pause");
A continuación una función util para cuando estéis poco inspirados dando valores.
int rand(void);
Por partes. rand se usa para obtener numeros aleatorios (random), su parámetro de entradas es void, es decir nada, por lo que su uso sería así:
int numeroMisterioso;
numeroMisterioso = rand();
rand es capar de devolver numeros enteros que siempre se encuentran entre 0 y 32767. Porque ese numero? porque es el mayor numero entero positivo que caben en 16 bits. Concretamente 32767 es en binario 0111 1111 1111 1111. Si no quereis acordaros del número concreto podeis usar la constante RAND_MAX. Las constantes son otra de las cosas que contienen las librerias. En el caso de stdlib, además de sus funciones, una de sus constantes es RAND_MAX, con el valor 32767. Podeis usar RAND_MAX libremente como si fuese una de vuestras variables por vuestro programa, pero nunca cambiar su valor.
rand por si sola es una funcion coja. Si os compilais un programa de ejemplo con rand() os va a salir siempre el mismo resultado en distintas ejecuciones. Menuda mierda de aleatoriedad no? Eso ocurre porque no estamos cambiando la semilla y está usando siempre la misma. Para cambiar la semilla se usa la siguiente función, tambien perteneciente a stdlib:
void srand(int semilla);
Como veis, recibe un numero entero como semilla (tiene que ser un numero positivo, por cierto) y no devuelve nada, void. Necesitamos pasarle un numero, y que cada vez que se ejecute el programa ese numero sea distinto, y para ello hay algo en vuestro ordenador que es perfecto para estas cosa: la hora.
La librería time.h
Esta librería es, como su propio nombre indica un paquete que contiene funciones relacionadas con el tiempo, hora del ordenador y los tiempos de ciclo de reloj de la máquina. Para no abrumar con el contenido de toda la librería de momento sólo usaremos una función, y la usaremos siempre igual, por lo que no voy a daros el prototipo (hay otra razón oculta, pero ya lo desvelaré).
time(NULL);
Esta sentencia devuelve un número que simboliza la hora del día que es. Para usar esto como semilla además recomiendo multiplicarlo por un número grande, de este modo los números aleatorios resultantes quedarán más esparcidos. Aquí presento un programa completo que imprime por pantalla 3 números aleatorios, distintos en cada ejecución.
spoiler#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void){
int x;
int hora;
hora = time(NULL);
srand(242374 * hora);
x = rand();
printf("%d, ", x);
x = rand();
printf("%d, ", x);
x = rand();
printf("%d, ", x);
return 0;
}
Deberes - Lección 3
Mucha información nueva y con ello muchas posibilidades. Las cosas que quiero que me entregueis son:
1 - Crear un programa que pregunte por los dos catetos de un triángulo rectángulo y calcule la hipotenusa. Posteriormente debe calcular los dos ángulos restantes terinando de resolver el triángulo e imprimir todos los resultados por pantalla.
2 - Crear un programa que pregunte un número entero de tres cifras y desglose en numero en centenas unidades y decenas, es posible hacerlo tan solo con int. Ejemplo de resultado: http://puu.sh/6PI58.png
3 - Otro programa parecido al anterior pero que separe parte entera de parte decimal. Hacedlo todo con doubles para evitar lios.
4 - Hacer un conversor de gradios celsius a fahrenheit, sabiendo que http://puu.sh/6PIci.png
5 - Crear un generador de numeros aleatorios que siempre de numeros exactamente entre 10 y 100
6 - Modificar los programas 1, 2 y 4 para que en vez de procesar números introducidos por el usuario lo haga con números aleatorios que genere él mismo
De momento no tenemos ningún mecanismo para comprobar que los números que se introducen son válidos. Por ejemplo en el problema 2-, que tenga tres cifras. En la siguiente lección rellenaremos el hueco de saber necesario para ello.
Procurad pensar bien los problemas, probablemente las soluciones estén por internet, pero creo que sería más constructivo que comentaseis vuestras dudas y los problemas que vais teniendo aquí