Parte 1

Anuncio
Apuntes FPR
IES Infiesto
TEMA 5:
ESTRUCTURAS ESTÁTICAS
Estructuras estáticas: definición, características y tipos
Cadenas
de caracteres: declaración, operaciones y
funciones para su manejo.
Arrays: tipos (vectores y matrices), declaración y
operaciones.Números Aleatorios.
Estructuras: creación y operaciones
Uniones: creación y operaciones
Punteros. Uso de punteros con arrays, estructuras y
uniones
Arrays de punteros
Profesora: Mª Alejandra Tomás Fdez
1
Apuntes FPR
IES Infiesto
1.- Estructuras estáticas: definición, características y
tipos
1.1.– RESUMEN DE LOS TIPOS DE VARIABLES
SEGÚN EL TIPO DE DATOS QUE
ALMACENAN
Una variable es un elemento del lenguaje que REPRESENTA UNA
ZONA DE MEMORIA donde se almacenarán datos.
Las variables SÓLO PUEDEN almacenar valores del TIPO DE
DATOS DEL QUE SE HAN DEFINIDO.
Los tipos de datos en C los dividimos en:
1)
Simples (char, int, long int, float, ...)
2)
Compuestos
o
estructuras
de datos
dinámicas
estáticas
matrices
o arrays
o tablas
vectores o
matrices
unidimensionales
estructuras
matrices
multidimensionales
Profesora: Mª Alejandra Tomás Fdez
uniones
Punteros:
listas, pilas,
colas,
árboles,...
cadenas
de
caracteres
2
Apuntes FPR
IES Infiesto
1.2.– ESTRUCTURAS ESTÁTICAS: Definición,
Características y Tipos
DEFINICIÓN:
Una estructura de datos COMPUESTA se contruye a partir de otros
tipos de datos.
ESTÁTICA: se refiere a que a estas variables se les asigna una zona de
memoria en tiempo de compilación y NO SE PUEDE CAMBIAR
DURANTE su ejecución.
TIPOS:
1) Matrices
1.1.- Matrices unidimensionales o vectores.
1.2.- Matrices multidimensionales
1.3.- Cadenas de caracteres
2) Estructuras
3) Uniones
Profesora: Mª Alejandra Tomás Fdez
3
Apuntes FPR
IES Infiesto
2.- Cadenas de caracteres: declaración, operaciones y
funciones para su manejo
2.1.– DECLARACIÓN
Una cadena de caracteres es un tipo especial de ARRAY, por tanto, veremos
primero la definición de array:
Una tabla o matriz o array es un conjunto finito de variables simples del
mismo tipo y agrupadas bajo un mismo nombre.
Los componentes individuales de un array se llaman elementos y se
distinguen entre ellos especificando el nombre del array seguido por uno o
más índices, con cada índice encerrado entre corchetes. Cada índice debe ser
expresado como un entero no negativo. El valor de cada índice puede ser
expresado como una constante entera, una variable entera o una expresión
entera más compleja. Los
en 1.
índices en C empiezan siempre en 0. no
Ejemplo de un array unidimensional de n elementos:
Posición determinada por el número que hay dentro del corchete
X[0]
x[1]
6
3
x[2]
x[3]
5
1
.........................................
x[n]
7
Contenido de la posición
Los elementos de un array se almacenan en memoria en posiciones
adyacentes. Se pueden procesar individualmente todas las veces que se desee,
o bien todo el array completo.
Antes de utilizar un array hay que declararlo al principio del programa para
reservar una zona de memoria y se hace mediante el nombre, el número de
índices y el tipo de datos que va a contener.
Profesora: Mª Alejandra Tomás Fdez
4
Apuntes FPR
IES Infiesto
Las cadenas son un tipo especial de arrays que se utiliza para almacenar varios
caracteres seguidos(por ejemplo: el nombre de una persona, la dirección de
una persona, una frase, una contraseña,…). Por tanto, una cadena se puede
definir como una estructura de datos formada por una cantidad fija y
conocida de caracteres.
A cada carácter de la cadena se le hace referencia indicado la posición que éste
ocupa dentro de la cadena.
TODAS LAS CADENAS TERMINAN EN UN CARÁCTER ESPECIAL
LLAMADO NULO “\0”.
Aunque C no tiene un tipo de dato tipo cadena, permite utilizar constantes de
cadena. Una constante de cadena es una lista de caracteres delimitados por
comillas dobles. No es necesario añadir de forma manual el carácter nulo al
final de las constantes de cadena, el compilador C lo hace de forma automática.
2.2.– OPERACIONES
DECLARACIÓN:
Se debe indicar el tamaño o longitud de la cadena (cuántos caracteres va a
tener). Tener en cuenta que el carácter “\0” ocupa una posición más. Es decir,
si queremos una cadena para guardar 4 caracteres , declararemos una cadena
de 5 caracteres.
char nombrecadena [numerocaracteres];
Ejemplo:
Para almacenar la palabra “Hola” declararé:
char palabra[5];
Profesora: Mª Alejandra Tomás Fdez
5
Apuntes FPR
IES Infiesto
INICIALIZACIÓN:
Consiste en darle valor a la cadena. Se puede hacer con una sola orden o bien
carácter a carácter (letra a letra).
Se puede hacer de varias formas:
A) Al declarar la cadena:
FORMATO 1:
char nombreCadena [ ] = “valor de la cadena”;
El carácter nulo es añadido al final automáticamente.
Por ejemplo:
char nombre[ ]=”Maria”;
FORMATO 2:
char nombreCadena [ tamaño] = {‘car1’, ‘car2’, ......... ‘carN’, ‘\0’};
Tenemos que añadir nosotros el carácter nulo al final.
Por ejemplo:
char nombre[ ]= {’M’, ‘a’, ‘r’, ‘i’, ‘a’, ‘\0’};
El carácter nulo ‘\0’ no debe ocupar obligatoriamente el último elemento o
componente del array, sino el último elemento o componente después del
último valor añadido a la cadena de caracteres. En el ejemplo anterior
tendríamos:
M a
r
Profesora: Mª Alejandra Tomás Fdez
i
a
\0
6
Apuntes FPR
IES Infiesto
Siempre es conveniente inicializar una cadena antes de utilizarla y limpiarla
antes de volver a utilizarla. Para realizar dicha operación podemos hacerlo de
la manera siguiente:
nombre-cadena [0]= ‘\0’ ;
Es decir poniendo el carácter nulo en el primer elemento de la cadena de
caracteres.
B) En cualquier parte del programa:
FORMATO 1:
Consiste en introducir los datos en la cadena con una sola orden,
mediante el uso de una de la funciones estándar de entrada vistas (gets,
scanf).
Por ejemplo:
char nombre[9];
…
printf (“dime tu nombre: “);
gets(nombre);
FORMATO 2:
Consiste en introducir los datos en la cadena de uno en uno, es decir,
carácter a carácter. Para eso necesitamos un bucle FOR que recorra todas
las casillas de la cadena desde la 0 a la última.
Tenemos que añadir nosotros el carácter nulo al final.
Sería:
for (i=0;i<tamaño;i++)
nombreCadena [i]=’carácter’;
nombreCadena[i]=’\0’;
Profesora: Mª Alejandra Tomás Fdez
7
Apuntes FPR
IES Infiesto
Por ejemplo:
char nombre[9], letra;
…
printf (“dime tu nombre letra a letra: “);
for (i=0;i<9;i++)
{
letra=getchar( );
nombre[i]=letra;
}
nombre[i]=’\0’;
ASIGNACIÓN:
Esta operación consiste en asignar de manera individual a cada elemento de la
cadena un carácter delimitado por comillas simples y una vez que asignemos
todos aquellos caracteres que queremos que formen parte de la cadena, asignamos
el carácter nulo ‘\0’ para determinar el fin de la cadena.
Por ejemplo:
char vocales[6];
vocal[0] = ‘a’;
vocal[1] = ‘e’;
vocal[2] = ‘i’;
vocal[3] = ‘o’;
vocal[4] = ‘u’;
vocal[5] = ‘\0’;
Profesora: Mª Alejandra Tomás Fdez
8
Apuntes FPR
IES Infiesto
2.3.– FUNCIONES
CADENAS
PARA
EL
MANEJO
DE
Las funciones para el manejo de cadenas están en el fichero cabecera: “string.h”.
Por tanto, para usarlas, se debe añadir en nuestro programa:
#include <string.h>
FUNCIONES DE ENTRADA/SALIDA PARA CADENAS:
Para LEER UNA CADENA: scanf y gets (ya vistas en tema anterior).
Su formato es:
scanf (“%s”, nombre-cadena);
También podemos introducir una cadena de caracteres, carácter a carácter
mediante un bucle con los siguientes formatos:
scanf(“%c”, &nombre-cadena[indice]);
nombre-cadena[indice]= getchar();
En cuyo caso al final debemos ser nosotros quien pongamos el carácter nulo
‘\0’ en la ultima posición para poder utilizar ese array como cadena.
Ejemplo
#include <stdio.h>
/*Programa ejemplo sobre el uso de scanf mediante un bucle.
Admite espacios en blanco.
Tendremos que añadir \0 en la ultima posicion */
void main(void)
{
int i;
char cadena[11];
Profesora: Mª Alejandra Tomás Fdez
9
Apuntes FPR
IES Infiesto
printf("\nIntroduce una cadena de caracteres ");
for (i=0; i<10; i++)
scanf("%c", &cadena[i]);
cadena[10]= '\0';
printf("\nLa cadena introducida es %s", cadena);
}
Ejemplo
#include <stdio.h>
/*Programa ejemplo sobre el uso de getchar() mediante un bucle.
Admite espacios en blanco.
Tendremos que añadir \0 en la ultima posicion */
void main(void)
{
int i=0;
char cadena[11];
printf("\nIntroduce una cadena de caracteres ");
while (((cadena[i]= getchar()) != '\n') && (i<=10))
i++;
cadena[i]= '\0';
printf("\nLa cadena introducida es %s", cadena);
}
El formato de gets es:
gets(nombre-cadena);
Ejemplo
#include <stdio.h>
//Programa ejemplo sobre el uso de gets().
void main(void)
{
char cadena[10];
printf("\nIntroduce una cadena de caracteres ");
gets(cadena);
printf("\nLa cadena introducida es: %s", cadena);
}
Profesora: Mª Alejandra Tomás Fdez
10
Apuntes FPR
IES Infiesto
Para ESCRIBIR
anterior).
Printf:
UNA CADENA: printf y puts (ya vistas en tema
Su formato es:
printf (“%s”, nombre-cadena);
Puts:
Su formato es el siguiente:
puts(nombre-cadena);
El carácter nulo que marca el final de la cadena de caracteres es convertido al
carácter de nueva línea.
Ejemplo
#include <stdio.h>
//Programa ejemplo sobre el uso de puts().
void main(void)
{
char cadena[10];
printf("\nIntroduce una cadena de caracteres ");
gets(cadena);
puts(cadena);
}
FUNCIONES ESPECIALES PARA CADENAS:
strlen(): devuelve la longitud de una cadena. Su formato es:
longitud=strlen( cadena);
Devuelve la longitud de la cadena.
strcpy() : copia una cadena en otra. Su formato es:
strcpy( cadena1,cadena2);
Profesora: Mª Alejandra Tomás Fdez
Copia la cadena2 en cadena1.
11
Apuntes FPR
IES Infiesto
strcat (): concatena cadenas. Su formato es:
strcat( cadena1, cadena2);
Concatena cadena2 al final de cadena1.
strcmp(): compara dos cadenas. Su formato es:
strcmp(cadena1,cadena2);
Devuelve: 0 si cadena1 y cadena2 son iguales. Un número negativo si
cadena 1 menor que cadena2. Y un número positivo si cadena1 mayor que
cadena2. Mayor o menor no se refiere al número de letras, sino al orden de
sus letras en el alfabeto. Por ejemplo: barra es > que babas porque la r es
posterior a la b de babas.
3.- Arrays: Tipos (vectores y matrices), declaración y
operaciones. Números Aleatorios.
3.1.–
DEFINICIÓN DE
OPERACIONES
ARRAYS,
TIPOS
Y
DEFINICIÓN:
-
Un array es una estructura de datos formada por una cantidad fija y conocida
de datos de un mismo tipo.
-
El array se identifica por un nombre único.
-
A cada elemento del array se le hace referencia indicando la posición que este
ocupa dentro del array mediante un número llamado ÍNDICE.
-
Cada índice debe ser expresado como un entero no negativo. El valor de cada
índice puede ser expresado como una constante entera, una variable entera o
una expresión entera más compleja.
Profesora: Mª Alejandra Tomás Fdez
12
Apuntes FPR
IES Infiesto
Ejemplo de un array unidimensional de n elementos:
Posición determinada por el número que hay dentro del corchete
X[0]
6
x[1]
3
x[2]
x[3]
5
1
.........................................
x[n]
7
Contenido de la posición
-
Los elementos de un array se almacenan en memoria en posiciones
adyacentes. Se pueden procesar individualmente todas las veces que se desee,
o bien todo el array completo.
-
Antes de utilizar un array hay que declararlo
TIPOS:
-
Según el número de índices necesarios para dimensionar un array se pueden
clasifican en:
Unidimensionales (son los VECTORES y CADENAS)
Son matrices o arrays de una sola dimension (una fila o una columna)
Bidimensionales (son las MATRICES o ARRAYS)
Son arrays de dos dimensiones: tienen filas y columnas (la típica tabla
del 3 en raya o de jugar a los barcos)
Multidimensionales (son los ARRAYS)
Son matrices o arrays de más de 2 dimensiones: filas, columnas y
fondo,…
Profesora: Mª Alejandra Tomás Fdez
13
Apuntes FPR
IES Infiesto
OPERACIONES:
-
Declaración y definición
-
Inicialización
-
Recorrido
-
Insertar y Borrar elementos en un array
-
Búsqueda de un elemento en un array
-
Ordenación del array.
3.2.– VECTORES: Declaración y operaciones
DEFINICIÓN:
-
Es una secuencia de objetos del mismo tipo. Internamente es un conjunto de
posiciones contiguas de memoria.
-
Su tamaño es fijo y debe conocerse a priori
-
Para acceder a cada objeto se usa un INDICE que indica lo posición que
ocupa ese objeto en el vector: el 4º, el 1º,...
-
Las posiciones en C SIEMPRE SE NUMERAN EMPEZANDO POR LA
0,1,2,3,...
-
EJEMPLOS DE VECTORES:
o Para guardar la edad de los 30 alumnos de una clase
o Para guardar las temperaturas de cada día de un mes.
Profesora: Mª Alejandra Tomás Fdez
14
Apuntes FPR
IES Infiesto
Ejemplo de un array unidimensional de n elementos:
Posición determinada por el número que hay dentro del corchete
X[0]
6
x[1]
3
x[2]
x[3]
5
1
.........................................
x[n]
7
Contenido de la posición
OPERACIONES:
1) DECLARACIÓN:
Se debe indicar el tamaño o longitud del vector (número de celdas o casillas).
tipo_dato nombre_vector [numelementos];
donde:
Tipo_dato: es el tipo de dato del vector común a todos los elementos,
puede ser cualquiera, int, float, char, ....
Nombre_vector: es el nombre que damos al vector, tiene que ser un
identificador válido.
Numelementos: es el número de elementos del array.
Ejemplo: para almacenar la edad de 30 alumnos:
int edades [30];
A veces es conveniente definir el tamaño de un array en términos de una
constante simbólica en vez de una cantidad entera fija. Esto hace más fácil
Profesora: Mª Alejandra Tomás Fdez
15
Apuntes FPR
IES Infiesto
modificar un programa que utiliza un array, ya que todas las referencias al
tamaño máximo del array puede ser alterado cambiando simplemente el valor
de la constante simbólica.
Ejemplo:
#include <stdio.h>
#define TAM 80
void main(void)
{
int notas[TAM];
.
.
}
Al declarar una variable tipo ARRAY, estamos indicando al compilador que
reserve una cantidad de espacio en memoria, esta cantidad dependerá del tipo
de dato del ARRAY y del tamaño del mismo. Para un VECTOR el tamaño
total en bytes que ocupa en memoria, se calcula:
Total de bytes = sizeof(tipo)*longitud del vector
El lenguaje C no comprueba los límites de los ARRAYS, con
lo cual si no tenemos cuidado al programar, podemos pasarnos de
los extremos del array y escribir o manipular otra variable de datos
o incluso código del programa.
En todos los arrays el índice del primer elemento es el 0. Por tanto
cuando se escribe por ejemplo int nume[10]; se está declarando un array de
números enteros que contiene 10 elementos desde el nume[0] hasta nume[9].
2) INICIALIZACIÓN:
Profesora: Mª Alejandra Tomás Fdez
16
Apuntes FPR
IES Infiesto
Consiste en dar valores a cada elemento del array.
Si el array tiene 100 elementos se da valores a los 100 elementos
Básicamente hay 3 formas de inicializar:
A) Al declarar el array:
Su formato es:
tipo_dato nombre_vector[tamaño] = {valor-1, valor-2,........... valor-n}
donde:
valor-1: se refiere al valor del 1er elemento.
valor-2: al valor del 2º elemento.
..........
valor-n: al valor del último elemento.
Ejemplo:
int digitos[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
float notas[5]= {2.3, 8.5, 5, 7, 9.5};
float x[6]= {0, 0.5, 4.3, 0, 0, 8.5} ;
El resultado de la asignación será:
Digitos[0]= 1
notas[0]= 2.3
x[0]= 0
Digitos[1]= 2
notas[1]= 8.5
x[1]= 0.5
Digitos[2]= 3
notas[2]= 5
x[2]= 4.3
Digitos[3]= 4
notas[3]= 7
x[3]= 0
Digitos[4]= 5
notas[4]= 9.5
x[4]= 0
Profesora: Mª Alejandra Tomás Fdez
17
Apuntes FPR
IES Infiesto
Digitos[5]= 6
x[5]= 8.5
Digitos[6]= 7
Digitos[7]= 8
Digitos[8]= 9
Digitos[9]= 10
Todos los elementos de un array que no tienen asignados valores
iniciales explícitos tendrán valores “basura (suelen ser números
negativos muy grandes”.
El tamaño de un vector no es necesario especificarlo cuando se
incluyen valores iniciales como una parte de la definición del vector.
Por ejemplo:
int digito[ ] = {1, 2, 3, 4, 5, 6};
float x[ ]= {0, 0.25, 0, 0.50};
El resultado de estas asignaciones será:
Digito[0]= 1
x[0]= 0
Digito[1]= 2
x[1]= 0.25
Digito[2]= 3
x[2]= 0
Digito[3]= 4
x[3]= 0.50
Digito[4]= 5
Digito[5]= 6
B) En cualquier parte del programa:
Por ejemplo si queremos inicializar un vector a 0:
#define TAM 4
Profesora: Mª Alejandra Tomás Fdez
18
Apuntes FPR
IES Infiesto
int i, precios[ 4 ];
for (i=0; i <TAM; i++)
precios[ i ] = 0;
C) Para dar valor sólo a algún elemento del vector:
El lenguaje C no permite manipular vectores completos, ni arrays
completos, sino que hay que hacerlo elemento a elemento. Para hacer
referencia al elemento que se quiere manipular hay que seguir el
formato siguiente:
nombre-array [posición]
donde posición es el lugar que ocupa en el array el elemento que se
quiere manipular.
#define TAM 4
int precios[ 4 ];
precios[ 0 ] = 10;
precios[ 3 ] = -5;
3) RECORRIDO:
Consiste en recorrer cada casilla del vector de la primera a la última o
viceversa.
La forma de hacerlo es con un bucle de la forma:
int vector[tam], i;
for (i=0; i<tam;i++)
Profesora: Mª Alejandra Tomás Fdez
19
Apuntes FPR
IES Infiesto
tratar (vector[i]);
EJEMPLO: Dado un vector de 100 enteros, contar los números positivos:
#include <stdio.h>
#define TAM 100
void inicializar (int [ ], int);
void main(void)
{
int i, cont, vect[TAM];
cont=0;
inicializar (vect, TAM);
for (i=0; i<TAM; i++)
if (vect[ i ] >0)
cont++;
printf(“ El número de positivos es %d\n”,cont);
}
void inicializar (int v[ ], int max)
{
int i;
for (i=0; i<max; i++)
scanf(“%d”, &v[ i ]);
}
4) INSERCIÓN DE UN ELEMENTO EN UN VECTOR:
Consiste en añadir un nuevo elemento al vector
Siempre antes de insertar debemos mirar que quede sitio en el vector.
Profesora: Mª Alejandra Tomás Fdez
20
Apuntes FPR
IES Infiesto
Se puede hacer una inserción de varias formas:
a) Insertar en la primera posición libre que haya:
i=0;
seguir=1;
MIENTRAS (i<TAM) y (seguir) HACER:
SI (vector[ i] ==ocupado)
i++;
SINO
seguir=0;
SI (! seguir)
vector[ i] = elemento;
SINO
escribir que no hay sitio para añadir elementos;
b) Insertar en un vector ordenado de N elementos ocupados, en la posición
que le toque:
if (haysitio(vector,TAM))
{
posicion = buscarpos(vector,TAM, elemento);
moverelementos(posicion,N, vector);
vector[posicion]=elemento;
}
else
escribir que no hay sitio en el vector
c) Insertar un elemento ELEM en la posicion POS del vector VECTOR
de tamaño TAM y que tiene N elementos ocupados:
if (haysitio(vector,TAM))
{
LEER posicion y elemento;
moverelementos(posicion,N, vector);
vector[posicion]=elemento;
Profesora: Mª Alejandra Tomás Fdez
21
Apuntes FPR
IES Infiesto
}
else
escribir que no hay sitio en el vector
5) BORRADO DE UN ELEMENTO EN UN VECTOR:
Consiste en eliminar un elemento del vector. El elemento se debe buscar y
puede ser que no exista.
Se haría:
LEER elemento a borrar;
posicion = buscarpos(vector,TAM, elemento);
if (posición != no_existe)
{
vector[posición]=valor_vector_vacio;
moverelementos(posicion,TAM, vector);
}
else
escribir que ese elemento no existe en el vector.
3.3.– NÚMEROS ALEATORIOS
Profesora: Mª Alejandra Tomás Fdez
22
Apuntes FPR
IES Infiesto
Obtención de números aleatorios en C
A veces queremos que nuestro programa obtenga números de forma aleatoria, por
ejemplo, para simular una tirada de dados o el reparto de cartas en un juego. En C de
linux tenemos varias funciones que nos permiten obtener estos valores aleatorios.
En esta explicación vamos a ver un uso básico de estas funciones. Algunas de las cosas
que contamos aquí no son útiles para aplicaciones más serias, en las que se requiere que
la secuencia de números aleatorios sea muy aleatoria, impredecible, que no se repita
hasta pasado muchos números, etc, etc. Sin embargo, las explicaciones aquí presentadas
servirán para la mayoría de nuestros programas.
LA FUNCIÓN rand()
En C, para obtener números aleatorios, tenemos la función rand(). Esta función, cada
vez que la llamamos, nos devuelve un número entero aleatorio entre 0 y el
RAND_MAX (un número enorme, como de 2 mil millones).
El primer problema que se nos presenta es que no solemos querer un número aleatorio
en ese rango, sería un dado muy curioso el que tenga tantas caras. Podemos querer, por
ejemplo, un número aleatorio entre 0 y 10. O de forma más general, entre 0 y N. La
cuenta
que
debemos
echar
para
eso
es
esta
#include <stdlib.h>
...
numero = rand() % 11;
numero = rand() % (N+1);
La operación módulo (%) nos da el resto de dividir rand() entre 11. Este resto puede ir
de 0 a 10. De la misma forma, el módulo de rand() entre N+1 va de 0 a N.
¿Y si queremos un rango que no empiece en 0?. Por ejemplo, queremos un rango entre
20 y 30 (de forma más general, entre M y N con N mayor que M). Pues es fácil,
obtenemos un número entre 0 y 10 y le sumamos 20 (un número entre 0 y N-M y le
sumamos
M)
numero = rand () % 11 + 20; // Este está
numero = rand () % (N-M+1) + M; // Este está entre M y N
entreo
20
y
30
LA FUNCIÓN srand()
Se nos presenta un nuevo problema. Si ejecutamos varias veces nuestro programa, la
secuencia de números aleatorios se repite. Imaginemos que tenemos un programa que
escribe 3 número aleatorios entre 0 y 10. Lo ejecutamos una vez y sale, por ejemplo 4, 7
y 9. Lo ejecutamos por segunda vez y vuelve a salir 4, 7 y 9. La tercera vez sale lo
mismo y cuando ya nos hemos hartado de ejecutar, vuelve a salir lo mismo.
Profesora: Mª Alejandra Tomás Fdez
23
Apuntes FPR
IES Infiesto
El problema es que rand() "calcula" los números aleatorios. Parte de un número inicial
(llamado semilla), echa unas cuentas y saca un número aleatorio. Para el segundo
número, echa unas cuentas con el resultado anterior y saca un segundo número y así
sucesivamente.
Si volvemos a ejecutar el programa desde el principio, el número inicial (la semilla) que
usa rand() es el mismo, con lo que la secuencia de números aleatorios es la misma, ya
que las cuentas son las mismas.
Para evitar este problema tenemos la función srand(), a la que se le pasa de parámetro
un número que se utilizará como número inicial para las cuentas. A esta función sólo
debemos llamarla una vez en nuestro programa.
¿Qué número le ponemos a este srand()?. No podemos ponerle un número fijo, porque
entonces no hemos hecho nada. No podemos ponerle un número obtenido con rand(),
porque la primera vez siempre nos dará el mismo y el resultado será igual que si le
ponemos un número fijo. Debemos buscar la forma de obtener un número que sea
distinto en la ejecución de cada programa.
Hay dos números que se utilizan habitualmente para ello:
•
La fecha/hora del sistema. Este valor cambia si ejecutamos el programa en
distinto instante de tiempo. Tendriamos que arrancar el programa dos veces en el
mismo segundo para obtener la misma secuencia de números aleatorios. En C de
linux esta fecha/hora se obtiene con la función time()
srand (time(NULL));
•
El número de proceso del programa. El primer programa que se arranca cuando
se enciende el ordenador con el sistema operativo linux, tiene el número de
proceso 1, el segundo el 2, el tercero el 3 y así sucesivamente. Cuando
arrancamos nuestro programa, se le asignará el número que le toque, por
ejemplo, el 215. Cuando lo volvamos a arrancar, se le asignará el que le toque
(puede ser 216 si no hemos ejecutado nada entre medias o 345, si nos hemos
entretenido con otras cosas). Después de ejecutar nuestro programa varios miles
de veces, el número de proceso puede que se repita, pero ya no nos acordaremos
de la secuencia que se sacó la primera vez. El número de proceso se obtiene con
getpid()
srand (getpid());
A esta función sólo hay que llamarla una vez al principio de nuestro programa.
Cada vez que la llamemos, estaremos reiniciando los calculos de números aleatoriosd
desde el principio, con lo que se repetirá todo.
LAS FUNCIONES drand48() y srand48()
¿Y si queremos un número aleatorio con decimales?. Tenemos la función drand48()
que nos devuelve un número aleatorio con decimales entre 0.0 (incluido, puede salir el
0,0) y 1.0 (excluido, nunca saldrá 1.0). A partir de ahí es fácil transformarlo al rango
Profesora: Mª Alejandra Tomás Fdez
24
Apuntes FPR
IES Infiesto
que queramos. Si queremos un rango entre 10.0 y 20.0 (o entre M y N siendo N mayor
que M y ambos con decimales, aunque sean .0)
#include
...
numero
=
drand48()
numero = drand48() * (N-M) + N;
<stdlib.h>
*
(20.0-10.0)
+
10.0;
De la misma forma que antes, la secuencia de números aleatorios se repetirá cada vez
que ejecutemos nuestro programa y de igual manera, tenemos manera de cambiar la
"semilla" de esa secuencia. Hay que llamar a la función srand48() pasándole un entero
que sea disntinto en cada ejecución del programa. Nuevamente, tenemos las dos
opciones anteriores .
Profesora: Mª Alejandra Tomás Fdez
25
Descargar