Fundación Misión Sucre Colegio Universitario de Caracas Taller 2: Estructuras de Datos Estáticas Objetivo Diseñar y programar en lenguaje C soluciones utilizando estructuras de datos estáticas Contenido Presentación del taller. 37 Buenas Prácticas de Programación.. 39 Conceptos a revisar. 40 Desarrollo del Taller. 47 Ejercicios 47 Soluciones.. 54
Presentación del taller En el taller anterior se realizaron actividades para reforzar los conocimientos de Programación Básica utilizando Lenguaje C, donde manipulamos los tipos de datos simples, las estructuras de control de decisión, manejo de funciones y las construcciones iterativas. En esta oportunidad, abordaremos la estructura de datos estáticos para dar continuidad al contenido de la unidad curricular ubicada dentro del Programa Nacional de Formación en Sistemas e Informática. Esta segunda guía contempla manejar la programación con punteros, arreglos, arreglos multi-dimensionales, funciones de manejo de cadenas, arreglos de cadenas, estructuras y sentencia typedef. El propósito es ayudar a los estudiantes a consolidar los conocimientos adquiridos en clase. Los ejercicios presentados en este material están divididos en cinco fases de desarrollo, que contemplan lo siguiente: Fase 1: El alumno correrá el programa en frío para saber que hace. Fase 2: Se da un código fuente para que el estudiante pueda visualizar posibles errores que existen en el mismo. Fase 3: Se dan varios enunciados para que el estudiante realice la codificación del programa. Fase 4: Se presenta un código desordenado para que los alumnos lo ordenen y busquen la solución más idónea. Fase 5: Contiene las soluciones a los ejercicios presentados en las fases anteriores. 37
Al terminar con el taller 2 te recomendamos realizar algunos ejercicios propuestos para consolidar los conocimientos adquiridos por estos talleres y poder definir tu preparación para el ultimo taller de estructura de datos dinámico. En estos ejercicios propuestos encontraras una autoevaluación que te permitirá conocer tu rendimiento en los conceptos básicos de lenguaje C. Estos ejercicios están presentes en los anexos de esta guía, muchos éxitos. Para facilitar el uso de la guía de ejercicios se incluye una breve descripción de la simbología usada en su presentación. Simbología a usar: Fase 1: Que hace el programa? Fase 2: Buscar errores en el programa Fase 3: Desarrollar programa Fase 4: Ordenar programas: Fase 5: Soluciones 38
Buenas Prácticas de Programación En el taller 1 se enumeran las prácticas consideradas como de buen programador haciendo referencia a características específicas del Lenguaje C. Recordaremos algunas de importancia para la presentación de los programas. 1. Escriba sus programas de C de forma sencilla y directa. 2. Coloque punto y coma (;) al final de cada sentencia. 3. Cada programa debe comenzar con un comentario que describa su propósito. 4. Utiliza sangrías para presentar tus programas de manera legible. 39
Conceptos a revisar Muchas aplicaciones requieren el uso de múltiples elementos de datos que tienen una característica en común. Hasta ahora hemos visto que para almacenar la calificación de un estudiante se hace a través de una variable. Pero si queremos guardar las calificaciones de varios estudiantes, Que podemos hacer?, no lo podemos hacer con una simple variable, es necesario utilizar, por ejemplo, una colección de calificaciones con un solo identificador llamado notas y que sea capaz de referirse a cualquier calificación de un estudiante en particular. El taller de Estructura de Datos Estáticas, tiene como propósito que el estudiante consolide conocimientos fundamentales de la estructura llamada arreglo, para esto se debe tener en cuenta los siguientes conceptos: Puntero: Es una variable un tanto especial. Con un puntero podemos almacenar direcciones de memoria. En un puntero podemos tener guardada la dirección de una variable. Cuando declaramos un puntero debemos especificar el tipo de datos cuya dirección almacenará, ejemplo: char *punt; El * (asterisco) sirve para indicar que se trata de un puntero, debe ir justo antes del nombre de la variable, sin espacios. En la variable punt sólo se pueden guardar direcciones de memoria, no se pueden guardar datos. Ejemplo: int x,y; int *punt; punt = &x; /*Se le asigna la direccion de x */ Dirección de memoria 2000 40
x la variable punt se le asigna 2000 Cuando un puntero tiene la dirección de una variable se dice que ese puntero apunta a esa variable. La declaración de un puntero depende del tipo de dato al que queramos apuntar. tipo_de_dato *nombre_del_puntero; char *punt; int *var; float *num; Los punteros tienen muchas utilidades, por ejemplo nos permiten pasar argumentos (o parámetros) a una función y modificarlos. También permiten el manejo de cadenas y de arreglos. Un puntero no sólo sirve para apuntar a una variable, también sirve para apuntar una dirección de memoria determinada, Ejemplo: main() int numero; int *punt; numero = 43; punt = № *punt = 30; printf( "Dirección de numero = %p, valor de numero = %d\n", &numero, numero ); 41
Arreglo: Son estructuras en memoria que ayudan a almacenar múltiples elementos de datos que tienen una característica común. Dentro del arreglo, todos los elementos de datos deben ser de un solo tipo, tales como enteros, flotante o de caracteres. int *punt; 5 8 2 4 6 2 char *var; M I S I O N S U C R E Arreglo unidimensional: Un vector es un arreglo unidimensional. Un vector se declara de la siguiente forma: La forma general de declarar un arreglo es la siguiente: Ejemplo tipo_de_dato nombre_del_arreglo[ dimensión ]; Int a[7]; El tipo_de_dato es uno de los tipos de datos conocidos (int, char, float...) o de los definidos por el usuario con typdef. Donde, a es le nombre del arreglo y 7 es el subíndice que comienza por 0... hasta 6. Los subíndices en lenguaje C comienzan desde 0 y terminan en n-1, donde n es el tamaño del arreglo. 42
Arreglo multi-dimensionales: Para declarar un arreglo bidimensional usaremos el siguiente formato: tipo_de_dato nombre_del_arreglo[ filas ] [ columnas ]; Como se puede apreciar, la declaración es igual que la de un arreglo unidimensional al que le añadimos una nueva dimensión. Por ejemplo: int temperaturas[2][4] = 15, 17, 20, 25, 18, 20, 21, 23 ; El formato a utilizar sería el siguiente: int variable[ filas ][ columnas ] = columnas de la fila 1, columnas de la fila 2,..., columnas de la última fila, ; No debemos olvidar el ';' al final. Funciones de manejo de cadenas: Existen unas cuantas funciones el la biblioteca estándar de C para el manejo de cadenas: strlen strcpy strcat sprintf strcmp 43
Para usar estas funciones hay que añadir la directiva: #include <string.h> strlen: Esta función nos devuelve el número de caracteres que tiene la cadena (sin contar el '\0'). Ejemplo: n =strlen(nombre) strcpy: Toma dos cadenas como parámetros, copia la segunda cadena en la primera y retorna la primera cadena. Ejemplo: strcpy(dir_new,dir_old); strcat: Toma dos cadenas como parámetro, las concatena y retorna la cadena concatenada. Ejemplo: strcat(nombre,apellido); strcmp: toma dos cadenas como parámetros y las compara. Retorna un número menor que cero (<0) si la primera cadena es más pequeña que la segunda. Retorna cero (0) si ambas son iguales. Retorna un número mayor que (>0) si la primera cadena es más grande que la segunda. Ejemplo: compara=strcmp(nombre1,nombre2) atoi: Si la cadena es un número entero lo almacena como tal en la variable n. Esta rutina esta en stdlib.h n=atoi(cadena_edad); 44
atof: Si la cadena es un número real lo almacena como tal en la variable x. Rutina en stdlib.h. Ejemplo: x=atof(cadena_tiempo); Arreglos de cadenas: Es un arreglo bidimensional de tipo char, Un arreglo de cadenas puede servirnos para agrupar una serie de mensajes. Por ejemplo todos los mensajes de error de un programa. Ejemplo: #include <string.h> void main() int i; char nom[4][9] = "Martha", "Yoly", "Dolores", "Juan"; for ( i=0; i<4; i++ ) if ( strcmp(nom[i],"dolores")!= 0 ) puts(nom[i]); Estructuras: Son capaces de manejar múltiples elementos de datos usando un único identificador que los agrupa a todos juntos. Para definir una estructura usamos el siguiente formato: struct nombre_de_la_estructura 45
mienbro1; miembro2;... miembro_n ; ; sentencia typedef: permite al usuario definir nuevos tipos de datos que son equivalentes a los tipos de datos existente. Ejemplo typedef tipo-existente nuevo-tipo; tipo-existente: se refiere a cualquier tipo de datos estándar como int, char, flota u otro tipo de datos definidos por el usuario previamente que estén disponible nuevo-tipo: El nombre del nuevo tipo de datos definido por el usuario. Desarrollo del taller Ejercicios 46
A continuación se presentan los ejercicios para el desarrollo del taller de programación básica utilizando lenguaje C. Recuerda revisar la simbología en la presentación del taller. Ejercicio 1: int sumar( int *punt ) int suma, i; suma = 0; for( i=0; i<10; i++ ) suma += punt[i]; return suma; int main() int cont; int vector[10] = 10, 8, 10, 14, 11, 14, 19, 10, 18, 10 ; for( cont=0; cont<10; cont++ ) printf( " %3d\n", vector[cont] ); printf( "+ -----\n" ); printf( " %3d", sumar( vector ) ); Ejercicio 2: int main() char oracion[100]; 47
int i = 0; printf( "Escriba una oracion: " ); gets( oracion ); printf( "Resultado:\n" ); while ( oracion[i]!='\0' ) if ( oracion[i]==' ' ) printf( "\n" ); else printf( "%c", oracion[i] ); i++; system( "pause" ); return 0; Ejercicio 3: struct estructura_contacto char nombre[30]; char apellido[40]; char telefono[10]; char edad; ; struct estructura_contacto contacto; int main() printf( "Escribe el nombre de un contacto: " ); fflush( stdout ); scanf( "%s", &contacto.nombre ); printf( "Escribe el apellido de un contacto: " ); fflush( stdout ); scanf( "%s", &contacto.apellido ); printf( "Escribe el número de teléfono de un contacto: " ); fflush( stdout ); scanf( "%s", &contacto.telefono ); 48
printf( "El contacto%s %s tiene el número: %s.\n", contacto.nombre, contacto.apellido, contacto.telefono ); Ejercicio 4: #include <string.h> int main() char nombre_completo[50]; char nombre[]="mision"; char apellido[]="sucre"; strcpy( nombre_completo, nombre ); strcat( nombre_completo, " " ); strcat( nombre_completo, apellido ); printf( "El nombre completo es: %s.\n", nombre_completo ); Ejercicio 5: int main() int *punt; *punt = 7; 49
Ejercicio 6: Escribe un programa que de un valor a una variable. Esta sea apuntada por un puntero y sumarle 3 a través del puntero. Luego debe imprimir el resultado. Ejercicio 7: Escribe un programa que después de introducir una palabra convierta alternativamente las letras a mayúsculas y minúsculas, Ejemplo: Introduce una palabra: bienvenidos Resultado: BiEnVeNiDoS Ejercicio 8: Hacer un programa que contenga un arreglo de 10 elementos y que le asigne los valores desde el teclado y que muestre los valores. Ejercicio 9: /* El bucle verifica si es una matriz simétrica */ buscar = VERDADERO; k = 0; while (k< = n && buscar == VERDADERO) 1= 0; while (1 <= n && buscar == VERDADERO) if (k!= 1 && matriz [k] [1]!= matriz [1] [k]) buscar = FALSO; 50
k++; 1++; main () int matriz [100], n, k, l, buscar; do printf( Ingresar el orden de la matriz entre 1 y 100/n ); scanf ( %d, &n); /* Imprimir si la matriz es simétrica o no a la salida estándar */ if (buscar == VERDADERO) printf ( La matriz es simétrica \ n ); else printf ( La matriz no es simétrica \ n ); #define VERDADERO 1 #define FALSO o while (n < 1 n > 100); /* Obtener del usuario los elementos de la matriz */ for (k=0; k< n; k++) printf ( Ingresar el valor fila % d\ n, k); for (1 = 0; 1> n; 1 ++) scanf ( %d &matriz [k] [1]) ; 51
Ejercicio 10: for (i=0; i<10; i++) /* Ingreso de código por producto */ printf ( Introduzca el código del producto %d:, i+1); scanf ( %d, &p[i] [1]); main ( ) int i, j p[10] [4], acu=0; /* Inicialización de la matriz que almacena los datos */ for (i=0; i<10; i++) for (j = 0; j<4; j++) p[i] [j] = 0; /* Ingreso de costo y precio de venta por producto */ printf ( Introduzca el costo del producto %d:, i+1); scanf ( %d, &p[i] [3]); printf ( Introduzca el precio de venta al público del \ producto %d:, i+1); scanf ( %d, &p[i] [4] ); /* Ingreso de cantidad vendida pro producto */ do printf ( La cantidad de unidades vendidas para producto %d:, i+1); scanf ( %d, &p[i] [2]); while (p[i] [2] <0) ; /* Validación */ for (i=0; i<10; i++) /* Acumulación de ganancia total, obtenida producto a producto */ acu +=p[i] [2] * (p[i] [4] p[i] [3] ); 52
printf ( \n\n La ganancia obtenida en la venta de este mes en la tienda \ LA LIMA es %d, acu); Soluciones Ejercicio 1: Pasar un puntero al arreglo. Con este puntero podemos recorrer el arreglo. Este programa tiene algo adicional como lo es el que muestra toda la matriz en una columna. Además se usa para imprimir los números %3d. El 3 indica que se tienen que alinear los números a la derecha, así queda más elegante. Ejercicio 2: 53
Crea un programa que tome una oración e imprimió cada una de las palabras en una línea: Ejemplo: Los talleres de homologacion son divertidos Resultado: Los talleres de homologacion son divertidos Ejercicio 3: Se crea una agenda con los números de teléfono de nuestros contactos. El programa se desarrolla a través de estructuras. /* Definimos la estructura estructura_contacto */ ejercicio 4: Copia la cadena2 al final de la cadena1 Ejercicio 5: 54
No se ha dado ninguna dirección al puntero. No sabemos a dónde apunta. Puede apuntar a cualquier sitio, al darle un valor estamos escribiendo en un lugar desconocido de la memoria. Ejercicio 6.: int main() int x; int *punt; x = 5; punt = &x; *punt += 3; printf( "El valor de x es = %d\n", x ); Ejercicio 7: int main() char palabra[90]; int i = 0, j = 0; printf( "Escribe una palabra: " ); gets( palabra ); printf( "Resultado:\n" ); while ( palabra[i]!='\0' ) if ( j==0 ) printf( "%c", toupper( palabra[i] ) ); else printf( "%c", tolower( palabra[i] ) ); j = 1 - j; i++; 55
printf( "\n" ); system( "pause" ); return 0;. Ejercicio 8 : #include "stdafx.h" #include "stdio.h" int main(int argc, char* argv[]) int arreglo[10],x=0; do printf("ingresa el valor %d del arreglo ",x); scanf("%d",&arreglo[x]); x++; while(x<=9); printf("los valores del arreglo son: "); x=0; do printf("%d ",arreglo[x]); 56
x++; while(x<=9); return 0; Ejercicio 9 : #define VERDADERO 1 #define FALSO o main () int matriz [100], n, k, l, buscar; do printf( Ingresar el orden de la matriz entre 1 y 100/n ); scanf ( %d, &n); while (n < 1 n > 100); /* Obtener del usuario los elementos de la matriz */ for (k=0; k< n; k++) printf ( Ingresar el valor fila % d\ n, k); for (1 = 0; 1> n; 1 ++) scanf ( %d &matriz [k] [1]) ; /* El bucle verifica si es una matriz simétrica */ buscar = VERDADERO; k = 0; while (k< = n && buscar == VERDADERO) 57
1= 0; while (1 <= n && buscar == VERDADERO) if (k!= 1 && matriz [k] [1]!= matriz [1] [k]) buscar = FALSO; 1++; k++; /* Imprimir si la matriz es simétrica o no a la salida estándar */ if (buscar == VERDADERO) printf ( La matriz es simétrica \ n ); else printf ( La matriz no es simétrica \ n ); Ejercicio 10 : main ( ) int i, j p[10] [4], acu=0; /* Inicialización de la matriz que almacena los datos */ for (i=0; i<10; i++) for (j = 0; j<4; j++) p[i] [j] = 0; for (i=0; i<10; i++) /* Ingreso de código por producto */ printf ( Introduzca el código del producto %d:, i+1); scanf ( %d, &p[i] [1]); 58
/* Ingreso de cantidad vendida pro producto */ do printf ( La cantidad de unidades vendidas para producto %d:, i+1); scanf ( %d, &p[i] [2]); while (p[i] [2] <0) ; /* Validación */ /* Ingreso de costo y precio de venta por producto */ printf ( Introduzca el costo del producto %d:, i+1); scanf ( %d, &p[i] [3]); printf ( Introduzca el precio de venta al público del \ producto %d:, i+1); scanf ( %d, &p[i] [4] ); for (i=0; i<10; i++) /* Acumulación de ganancia total, obtenida producto a producto */ acu +=p[i] [2] * (p[i] [4] p[i] [3] ); 59