Está en la página 1de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

GUIN DE PRCTICAS 4: ESTRUCTURAS CCLICAS Y TIPOS DE DATOS COMPLEJOS

Introduccin.
En este guin vamos a introducir aquellas estructuras en C que nos permiten ejecutar partes de un cdigo varias veces. A este tipo de estructuras se les denomina estructuras cclicas o repetitivas. Adems explicaremos cmo declarar y utilizar una estructura de datos algo ms compleja que las vistas hasta el momento, llamada array.

Un ejemplo de bucle mientras.


Como en los dems guiones vamos a comenzar con un ejemplo que explicaremos paso a paso.
#include <stdio.h> #include <stdlib.h> #include <time.h> int main( void ){ /*ENTRADAS*/ int valor=0; /*SALIDAS*/ int intentos=0; /*VARIABLES*/ int aleatorio=0; /* Inicializar y asignar un numero aleatorio.*/ srand(time(NULL)); aleatorio = rand() % 101; /* Encontrar el numero*/ printf("Acierte el numero que he pensado (0-100): "); scanf("%i", &valor); intentos = intentos + 1; /* Intentarlo mientras no acierte*/ while( valor != aleatorio ){ /* Comprobar si es mayor o menor.*/ if( valor < aleatorio ){ printf ("Mi numero es mayor\n"); } else { printf ("Mi numero es menor\n"); } /* Pedir un nuevo intento*/ printf("Intentalo de nuevo: "); scanf("%i", &valor); intentos = intentos + 1; } /*Mostrar mensaje de acierto*/ printf("CORRECTO !!! Has acertado tras %i intentos\n", intentos);

Pgina 1 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

system("PAUSE"); }

Este programa es un simple juego, donde el ordenador selecciona un nmero secreto y el usuario debe acertarlo. Para dar ayuda, el ordenador avisa si el nmero elegido es mayor o menor que el que el usuario va introduciendo. Vamos a empezar con aquellas partes del cdigo que son nuevas, pero que no necesitan ser explicadas con profundidad, para despus continuar con la parte que ms interesa en este guin: el bucle while.

Los nmeros aleatorios.


En primer lugar vamos a ver cmo el ordenador selecciona un nmero al azar:
/* Inicializar y asignar un numero aleatorio.*/ srand(time(NULL)); aleatorio = rand() % 101;

En la librera stdlib.h hay un par de funciones que se utilizan para generar nmeros pseudo-aleatorios. Una de ellas es:
rand();

Esta funcin obtiene un valor entero al azar del generador de nmeros aleatorios. Para que dicho valor quede entre 0 y 100 lo que hacemos es obtener el resto (%) de dividir dicho valor entre 101. La otra funcin es:
srand( semilla );

Esta funcin inicializa el generador de nmeros aleatorios. Los valores generados son en realidad pseudo-aleatorios, ya que, para una misma semilla, los nmeros que generan son los mismos. Por ese motivo utilizamos la funcin:
time(NULL)

Que nos devuelve el tiempo del sistema en segundos. De esta manera la semilla cambia en cada ejecucin. Esta funcin pertenece a la librera time.h.

Ejercicio:
Modifica el cdigo para que el nmero que selecciona el sistema est entre 1 y 100, en lugar de entre 0 y 100.

El bucle mientras.
Un bucle es la estructura que nos permite repetir partes de cdigo un nmero de veces. La estructura es la siguiente:
while( condicin ) bloque_de_sentencias

donde:

Pgina 2 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

condicin: es cualquier expresin que genere un valor lgico (verdadero o falso). bloque_de_sentencias: puede ser: Una nica sentencia terminada en punto y coma. Una o ms sentencias encerradas entre llaves ({}). El bucle mientras (while) ejecutar el bloque de sentencias mientras la condicin dada se cumpla, es decir, mientras su valor sea verdadero. En el caso de nuestra aplicacin, el bucle mientras se ejecuta mientras el usuario no acierte el nmero elegido al azar. NOTA: La condicin del bucle mientras SIEMPRE debe ir entre parntesis.

El bucle repetir...mientras.
El cdigo el ejemplo anterior puede ser mejorable. Observa que antes de entrar en el bucle tenemos que leer el valor del usuario, y que esa misma accin se vuelve a realizar en la parte final del bloque de sentencias del bucle. Existe una estructura que nos permite hacer la comparacin al final del bucle, en lugar de realizarla al principio (como ocurre en el bucle mientras). Vamos a reescribir el cdigo con esta nueva estructura:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main( void ){ /*ENTRADAS*/ int valor=0; /*SALIDAS*/ int intentos=0; /*VARIABLES*/ int aleatorio=0; /* Inicializar y asignar un numero aleatorio.*/ srand(time(NULL)); aleatorio = (rand() % 100) + 1; /* Encontrar el numero*/ printf("Acierte el numero que he pensado (1-100).\n"); /* Intentarlo mientras no acierte*/ do{ /* Pedir un nuevo intento*/ printf("Deme un valor: "); scanf("%i", &valor); intentos = intentos + 1; /* Comprobar si es mayor o menor.*/ if( valor < aleatorio ){ printf ("Mi numero es mayor\n"); } else { printf ("Mi numero es menor\n"); } }while( valor != aleatorio ); /*Mostrar mensaje de acierto*/ printf("CORRECTO !!! Has acertado tras %i intentos\n", intentos); system("PAUSE");

Pgina 3 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

Esta estructura ejecutar como mnimo una vez el cdigo que hay dentro del bucle, ya que la condicin se analiza al final. La estructura de este tipo de bucles es:
do bloque_de_sentencias while( condicin );

donde: condicin: es cualquier expresin que genere un valor lgico (verdadero o falso). bloque_de_sentencias: puede ser: Una nica sentencia terminada en punto y coma. Una o ms sentencias encerradas entre llaves ({}). NOTA: Toda la condicin del bucle SIEMPRE debe ir entre parntesis. Ejercicio: Crea un programa que vaya pidiendo valores reales al usuario y los sume, mostrando en cada iteracin la suma parcial. El programa acabar cuando el usuario introduzca un 0.

El bucle repetir...hasta.
El bucle repetir...hasta NO existe en C. Para realizar dicho bucle en C hay que utilizar el bucle repetir...mientras cambiando la condicin de parada. La forma ms rpida es negar la condicin original del repetir...hasta. La conversin sera de esta forma: Pseudocdigo
REPETIR sentencias HASTA condicin do{ sentencias; }while( !(condicin) );

Ejemplo: Pseudocdigo
REPETIR sentencias HASTA a>b do{

C
sentencias; }while( !(a>b) );

Otra forma de resolver el ejemplo anterior sera cambiando por completo el condicional para que signifique lo contrario, lo cual no siempre est claro. Pseudocdigo
REPETIR sentencias HASTA a>b do{ sentencias; }while( a<=b );

Pgina 4 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

El bucle fijo.
Recordemos el ejemplo que vimos en sesiones anteriores, que nos peda un programa para mostrar la tabla de multiplicar de un nmero introducido por teclado. El cdigo sera algo parecido a lo siguiente.
#include <stdio.h> #include <stdlib.h> int main( void ){ /*ENTRADAS*/ int valor=0; /*VARIABLES*/ int i=0; /* Leer el valor de entrada*/ printf("Introduzca un numero entero: "); scanf("%i", &valor); /* Mostrar la tabla del 1 al 10*/ for( i=1; i<=10; i=i+1){ printf("%3i x %2i = %6i\n", valor, i, valor*i); } system("PAUSE"); }

Este ejemplo realiza la misma secuencia de instrucciones 10 veces, cambiando el valor de la variable i desde el valor inicial 1, hasta el valor final 10. La estructura de una instruccin de este tipo es:
for( inicializacin ; condicin ; incremento )bloque_de_sentencias

donde: inicializacin: asigna el primer valor que tomar la variable que se utiliza como contador. condicin: es una expresin que genera un valor lgico, si dicho valor es verdadero el bucle continua ejecutndose. Se utiliza para comprobar si la variable contador ha alcanzado el valor de fin. incremento: se utiliza para aumentar/decrementar el valor de la variable contador en cada iteracin. bloque_de_sentencias: puede ser: Una nica sentencia terminada en punto y coma. Una o ms sentencias encerradas entre llaves ({}). En realidad, este bucle funciona como un bucle mientras, ya que tiene una condicin para ejecutarse. NOTA: En este tipo de bucle, el incremento hay que indicarlo SIEMPRE, aunque sea de uno en uno. Existen mtodos abreviados para indicar el incremento de la variable utilizada como contador: i=i+1 es igual que i+=1 que es igual que i++

Pgina 5 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

i=i-1 es igual que i-=1 es igual que i-Ejercicios: Modifica el cdigo para que muestre la tabla de multiplicar desde el 2 hasta el 20, pero slo de los nmeros pares. Modifica el cdigo para que muestre la tabla de multiplicar al contrario (desde el 10 hasta el 1). Modifica el cdigo para que muestre la tabla de multiplicar de los nmeros impares desde el 19 hasta el 1. Modifica el cdigo para que muestre la tabla de dividir del 1 al 9 en orden ascendente. Debe realizarse una divisin real. Modifica el cdigo para que muestre la divisin entera y el resto, adems de la divisin real.

Los arrays.
Un array es un medio de guardar un conjunto de objetos de la misma clase. Se accede a cada elemento individual del array mediante un nmero entero denominado ndice. Veamos un ejemplo.
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void){ /*ENTRADAS*/ int posx, posy; //coordenadas del usuario /*SALIDAS*/ int tablero[10][10]; //todos los disparos del usuario /*VARIABLES*/ int i, j; int x, y; int distancia; /* Inicializar y asignar numeros aleatorio.*/ srand(time(NULL)); x = rand() % 10; y = rand() % 10; /*Inicializar tablero.*/ for(i=0; i<10; i++){ for(j=0; j<10; j++){ tablero[i][j]=-1; } } /*Pedir coordenadas mientras no encuentre el barco*/ do{ /*Mostrar disparos realizados.*/ for(i=0; i<10; i++){ for(j=0; j<10; j++){ printf("%2i ", tablero[i][j]); } printf("\n"); } /*Pedir datos.*/

Pgina 6 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

printf("Coordenada x:"); scanf("%i", &posx); printf("Coordenada y:"); scanf("%i", &posy); /*Calcular distancia y guardarla en el tablero*/ distancia = abs(x-posx) + abs(y-posy); tablero[posx][posy]=distancia; }while( distancia!=0); printf("CORRECTO !!! Has acertado.\n"); system("PAUSE"); }

Este programa es un juego donde el ordenador esconde un barco en un tablero de 10x10 (las casillas van de 0 a 9) y el usuario debe hundirlo realizando varias tiradas. Cada vez que el usuario realiza una tirada el ordenador muestra la distancia a la que ha quedado. Para que sea ms fcil para el usuario, en cada tirada se muestra un tablero con las tiradas realizadas y las distancias de cada tirada. Como podrs observar en el cdigo hay varias secciones. Algunas de ellas ya han sido explicadas, como por ejemplo: la parte de asignar e inicializar nmeros aleatorios, el bucle do...while, .... A continuacin vamos a ver las partes que hacen referencia al manejo de arrays.

Declaracin.
En primer lugar hemos declarado un array de 2 dimensiones, para guardar en qu casillas ha disparado el usuario. En cada casilla guardaremos la distancia al barco. La declaracin es la siguiente manera:
int tablero[10][10]; //todos los disparos del usuario

Para declarar un array de cualquier tipo y tamao tenemos que indicar varios elementos: Tipo bsico de todos los elementos del array (en este caso es int). Identificador del array (en este caso es tablero). Dimensiones y el tamao de cada una de ellas. Por cada dimensin indicaremos entre corchetes el tamao de cada una de ellas (en este caso tenemos 2 dimensiones de 10 elementos: [10][10]). El tamao de las dimensiones de un array est definido por una constante o valor constante de tipo entero. NOTA: Todos los arrays en C empiezan en la posicin 0, por lo tanto, si tienes un array de una dimensin de tamao 3, tendrs las posiciones: 0, 1 y 2. Ejercicio: Modifica el algoritmo anterior para que el tamao del array tablero est definido en una constante llamada TAMA. Para ello define la nueva constante y cambia la declaracin del array para que utilice dicha constante.

Pgina 7 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

Uso de un array.
Un array no podemos inicializarlo en la declaracin, por lo que para ello tenemos que utilizar un doble bucle para asignar un valor inicial (en este caso -1) a todas las posiciones del array. De esta forma, todas las casillas donde no se han realizado disparos tendr el valor -1. Las instrucciones son las siguientes:
for(i=0; i<10; i++){ for(j=0; j<10; j++){ tablero[i][j]=-1; } }

Con este doble bucle accedemos, una por una, a todas las posiciones del array. Para indicar a qu posicin se accede, se pone el identificador de la variable array (en este caso tablero) y a continuacin cada una de las posiciones encerradas entre corchetes (en este caso [i][j]). NOTA: Para indicar una posicin de un array se puede utilizar cualquier expresin de tipo entero (variables, expresiones aritmticas, constantes, valores constantes, ...). Ejercicios: Modifica todos los bucles for del cdigo para que utilicen la constante TAMA en lugar del valor 10 como condicin de parada. Crea una la constante VACIO con el valor -1 y sustituye la asignacin para que el array quede inicializado con el valor VACIO. Todo el conjunto de identificador ms posicin (en este caso tablero[i][j]) representa una nica variable del tipo de elemento almacenado (en este caso int). Por lo tanto, una expresin de este tipo puede realizar la mismas funciones que cualquier variable, es decir, ser utilizada en expresiones aritmticas y lgicas o asignaciones. Para utilizar el contenido de una posicin del array se realiza exactamente igual. Por ejemplo, en nuestro cdigo visualizamos el contenido completo del array con las siguiente sentencias:
for(i=0; i<10; i++){ for(j=0; j<10; j++){ printf("%2i ", tablero[i][j]); } printf("\n"); }

El valor mostrado es un entero (formateado para ocupar 2 espacios) que est en la posicion i,j del array. Ejercicio: Incluye una condicin dentro del segundo bucle for, para que escriba un espacio en blanco y un punto (.) cuando el valor de la posicin i, j sea igual al valor de la constante VACIO.

Pgina 8 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

Recuerda.

La condicin de cualquier estructura cclica en C (while o for) SIEMPRE debe ir entre parntesis. El bucle REPETIRHASTA no existe en C, pero se puede simular con un bucle REPETIRMIENTRAS teniendo en cuenta las condiciones. La condicin de ejecucin de un bucle for funciona como la de un bucle

while.
En el bucle for el incremento hay que indicarlo SIEMPRE. Todos los arrays en C empiezan en la posicin 0. Para indicar una posicin de un array se puede utilizar cualquier expresin de tipo entero (variables, expresiones aritmticas, constantes, valores constantes, ...).

Ejercicios finales.
1. Escribir un programa que muestre por pantalla los cuadrados de los 100 primeros nmeros enteros. Modificarlo para que muestre tambin la suma de dichos valores. 2. Realizar un programa que calcule el factorial de un nmero entero positivo. Si el nmero introducido no est en el rango 120, el algoritmo deber indicarlo y volver a pedir otro nmero hasta que sea vlido para realizar el clculo. 3. Necesitamos un programa que imprima una pirmide de dgitos como la de la figura, tomando como entrada el nmero de filas de la misma:
1 1 2 1 1 2 3 2 1 1 2 3 4 3 2 1 1 2 3 4 5 4 3 2 1

4. Existen muchos mtodos capaces de proporcionar aproximaciones numricas de . Uno de ellos es el siguiente:

i=1

6 i2

Crea un programa que lea el grado de aproximacin (nmero de trminos de la sumatoria) y devuelva un valor aproximado de . 5. Escribe un programa que calcule el valor de S para un nmero real X dado, utilizando la siguiente serie:

S = 1+ X +

X2 X3 X4 + + + 2! 3! 4!

Pgina 9 de 10

Guin de prcticas

Estructuras cclicas y tipos de datos complejos.

El valor de S se calcular de tal manera que el error del trmino debe ser menor que 0.0001 6. Realizar un programa para convertir nmeros enteros decimales (en base 10) a sus respectivas representaciones octales (en base 8), por medio de sucesivas divisiones. Por ejemplo, para calcular la representacin octal de 150, se divide sucesivamente por 8 y los restos que van quedando se almacenan ordenadamente. Paso 1 2 3 Dividendo 150 18 2 Divisor 8 8 8 Cociente 18 2 0 Resto 6 2 2

226(8 = 2*82+2*81+6*80=150(10 7. Escribe un programa que dado un nmero entero lo descomponga dgito a dgito, lo vuelva a componer al revs y lo muestre. Por ejemplo: si le damos el nmero 187365, el programa mostrar 563781. 8. Crea un programa que lea de teclado una secuencia de nmeros enteros positivos entre 0 y 100, ambos inclusive. La secuencia de nmeros introducidos terminar cuando se introduzca un nmero que no cumpla la condicin (que no est entre 0 y 100). Al finalizar de introducir los nmeros, mostrar cuantas veces se ha introducido cada nmero. 9. Realizar un programa que lea del teclado y ordene de mayor a menor 20 nmeros reales. 10. Necesitamos un programa que nos calcule la matriz transpuesta de una matriz bidimensional cuadrada de tamao M. El tamao de la matriz y su contenido se leer por teclado. 11. Crea un programa que determine si una matriz es simtrica. 12. Realizar un programa que calcule el resto de una divisin entera entre dos nmeros y que no utilice el operador del mdulo (%). 13. Necesitamos un programa que lea en un array N nmeros reales y determine el mayor, el menor y la media de los nmeros ledos. 14. Realizar un programa que indique si los dos arrays dados como entrada son iguales o no. 15. Escribir un programa al que se le de como entrada dos arrays de enteros ordenados de forma creciente, y devuelva como salida un array ordenado de forma creciente formado por los elementos de las entradas y sin incluir los elementos repetidos. 16. Dada una matriz de dos dimensiones, realizar un programa que obtenga cul es la columna que tiene la mayor media. 17. Dado un tablero de 3x3 relleno con nmeros enteros, crear un programa que compruebe si todos los nmeros estn entre 1 y 9 (ambos inclusive) y que ninguno se repite.

Pgina 10 de 10

También podría gustarte