Área de Servicios – Dpto. de Informática Programación (Prof. Elec. - TUM), Programación I (TUG, TUR ) - Electrónica Programable (TUE) - 2015 Práctico Nº 2 Tema: Punteros en C Notas: Los programas que involucren el uso de operaciones entre variables y arreglos deberán ser realizados únicamente mediante punteros y con al menos 2 funciones. Ejecutar TODOS LOS PROGRAMAS. En todos los ejercicios donde lea “secuencia de caracteres”, debe interpretar que es una secuencia formada por letras mayúsculas, minúsculas, números y/0 caracteres especiales („+‟, „?‟, „-„, ‟.‟, etc.). Cuando se menciona a un “número”, se hace referencia a los números enteros o reales, cuando se menciona a un “dígito” se hace referencia a los dígitos: 0, 1, 2, 3, …. , o 9. Ej. 1 - Dadas las siguientes definiciones y asignaciones: char a[10] = {`a´,`A´,`c´,`L´,`M´,`n´,`B´,`T´,`H´,`V´}; char *p, *q; /* declaración de variables puntero */ int i; p = &a[0]; q = &a[1]; Memoria: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] i a[9] … Ox500 Ox501 Ox502 Ox503 Ox504 Ox505 Ox506 Ox507 Ox508 Ox509 p … Ox700 q … Ox840 Ox970 a) Ejecutar el código completando el correspondiente gráfico. b) Indicar gráficamente el estado de la memoria luego de ejecutar cada una de las siguientes sentencias en forma secuencial: 1. i = *p - *q; 2. *p += (i-10); /* o lo que es lo mismo: *p = *p + (i-10); */ 3. *(p+1) = i+90; 4. i = *(q-1) - *(p+9); 5. *p = *(p+10-3); 6. q = p+5; c) ¿Qué diferencia hay entre el nombre de un arreglo y un puntero? d) ¿Cómo sabe el compilador el tamaño de un objeto al que apunta un puntero? Ej. 2 - Dado el siguiente programa. # include <stdio.h> int main ( ) { int arr[5], i; int *p_arr; for (i = 0; i < 5; i++) arr[i] = i; p_arr = &arr[0];/*p_arr pasa a apuntar a la primer posición del arreglo*/ for (i = 0; i < 5; i++) { printf (“%d -- %d \n”, *p_arr, *p_arr * *p_arr); p_arr++; } return (0); } Práctico Nº 2 2do Cuatrimestre 1/6 Área de Servicios – Dpto. de Informática Programación (Prof. Elec. - TUM), Programación I (TUG, TUR ) - Electrónica Programable (TUE) - 2015 a) En la siguiente grilla, ejecutar paso a paso el código e indicar cuál es la salida del programa. Direcciones de memoria Ox500 Ox501 Ox502 Ox503 Ox504 Acciones i arr[0] arr[1] arr[2] arr[3] arr[4] p_arr Pantalla ind ind ind ind ind ind ind … … … … … … … … … b) ¿Es necesario colocar paréntesis en el cálculo de la multiplicación? Justificar. c) Indicar otras formas de escribir sintácticamente correcto el printf del programa. Ej. 3 – Dado el siguiente programa: # include <stdio.h> int main ( ) { char palabras[7]; int i; char *p_arr; /* p_arr es un puntero a char */ char cartel[20]={'L','o','s',' ','d','a','t','o','s',' ','s','o','n',':', '\0'}; printf("%s \n", cartel); printf("%s \n", palabras); for (i = 0; i < 7; i++) palabras[i] = 'z'-i; printf("%s \n", palabras); *(palabras + 3) = '\0'; printf("%s \n", palabras); getchar(); p_arr= &palabras[7]; for (i = 7; i >0 ; i++) { printf ("Posicion:%d - %c \n",i-1, *(p_arr-1)); p_arr--; } getchar(); return (0); } a) Sabiendo que un algoritmo debe cumplir con las siguientes características: acciones perfectamente delimitadas. número finito de acciones. orden pre-establecido de las acciones. ¿El código dado cumple con lo anterior? En caso de no cumplirlo, modificarlo para que muestre los caracteres en orden inverso al ingresado. b) Justificar la salida de cada printf y corrija el código para que imprima correctamente. Ej. 4 – Dados los siguientes códigos de una función “leer_cadena”, que permite ingresar una cadena de caracteres: a) Corrija ambos códigos para que funcionen correctamente 1) void leer_cadena (char *cadena, int *cant, int max){ int i=0; printf("Ingrese la longitud de la secuencia a leer, no mayor a %d \n", max); scanf("%d", &cant); getchar(); while (*cant < 0 || *cant > max ){ printf("Ingrese la longitud de la secuencia a leer, no mayor a %d \n", max); scanf("%d", &cant); getchar(); } for(i=0; i< *cant ;i++){ printf("Ingrese un caracter \n"); Práctico Nº 2 2do Cuatrimestre 2/6 Área de Servicios – Dpto. de Informática Programación (Prof. Elec. - TUM), Programación I (TUG, TUR ) - Electrónica Programable (TUE) - 2015 scanf("%c",*cadena); *cadena++; getchar(); } return; } 2) void leer_cadena(char *cad) { printf("Ingrese cadena\n"); scanf("%s",&cad); getchar(); return; } b) ¿Cómo sería la invocación a la función “leer_cadena” en cada uno de los casos? c) ¿En qué situación usaría una u otra función? Justifique Ej. 5 - Dado el siguiente programa # include <stdio.h> void intercambio (int x, int y) { int temp; temp = x; x = y; y = temp; return; } int main ( ){ int a = 3, b = 5; printf (“El valor de a es %d y el valor de b es %d \n”, a, b); intercambio (a, b); printf (“El valor de a es %d y el valor de b es %d \n”, a, b); return (0); } a) b) c) d) Graficar todas las variables e identificar el ámbito de cada una de ellas. Ejecutar el código paso por paso. Se pretende que el código intercambie los valores de a y b. ¿Es esto cierto? Realizar los cambios necesarios para lograr este objetivo. Ej. 6 a) Dado el siguiente encabezado de una función: void reemplazar (char *cad, char nuevo, char viejo); Codifique dicha función para que todas las apariciones en “cad” del carácter „viejo‟ sean reemplazadas por el carácter indicado en „nuevo‟. Ejemplo: Si *cad=“muestre” - nuevo=“o” función debería quedar *cad=“muostro” - viejo= “e” cuando salga de la b) Codifique la función main que invoque dicha función. Ej. 7 – Escribir un programa que lea dos secuencias de caracteres alfabéticos y un número. El programa debe insertar la segunda secuencia en la primera, a partir del carácter de la primera secuencia que está en la posición indicada por el número. Luego deberá imprimir la primera secuencia. Ejemplo: Cad1: “marea” Cad2:”sol” Numero: 3. La salida Cad1:”masolrea” Nota: deberá realizar todos los controles necesarios para poder realizar dicha Práctico Nº 2 2do Cuatrimestre 3/6 Área de Servicios – Dpto. de Informática Programación (Prof. Elec. - TUM), Programación I (TUG, TUR ) - Electrónica Programable (TUE) - 2015 operación. Ej. 8 - Dado el siguiente código: a) Especificar el ámbito de las variables. b) Realizar una ejecución completa del mismo, indicando el estado de todas las variables en las diferentes etapas. #include <stdio.h> int ingreso(int *Arr, int tam) { Ejecutar con los siguientes valores para los arreglos: int i; for (i=0; i < tam; i++) { H {202, 202, 234, 210, 220} scanf("%d",(Arr+i)); getchar(); } V {212, 198, 198, 222,10} //imprimir(Arr, tam); return (0); } int chequeo (int *A, int *B; int tam) { int temp,i, paso = 0; for (i=0; i < tam; i++) { if(*(A+i) > *(B+i)){ temp = *(B+i); *(B+i) = *(A+i); *(A+i) = temp; paso = 1; } } if (paso == 1) return (1); else return (0); } int main() { int ret; int H[10],V[10]; ingreso(H, 5); ingreso(V, 5); ret = chequeo(H,V,5); if(ret=1) printf(“Se modificaron los números de los arreglos”); return(0); } c) Codificar una función “imprimir” que imprima UN arreglo. Coloque en el main las invocaciones necesarias para que muestre la información ingresada y modificada. Ej. 9 – Ingresar por teclado hasta 45 patentes de autos (cada patente consta de 3 caracteres alfabéticos seguidos de 3 dígitos ejemplo: MED345). Almacenar los caracteres alfabéticos a partir de la primera posición y los numéricos desde la última posición. Luego, mostrar por pantalla todas aquellas patentes impares. Finalmente, dada una patente ingresada por el usuario, detectar e informar si existe entre las patentes almacenadas. Ej. 10 – Codificar una función “nstrcmp” que reciba como parámetros dos cadenas de caracteres (s1 y s2) y un número natural n. La función deberá comparar hasta n caracteres de la cadena s1 con la cadena s2 y retornar un número menor que 0 si s1 es menor que s2, un número mayor que cero si s1 es mayor que s2, o 0 si son iguales. Nota: el orden establecido entre caracteres es el de la tabla ASCII. Ej. 11 - Escribir un programa que lea dos secuencias de caracteres denominadas "s1" y "s2" respectivamente, y verifique la existencia de la secuencia “s2” como subsecuencia integrante de la “s1”, imprimiendo como salida el cartel que corresponda. Práctico Nº 2 2do Cuatrimestre 4/6 Área de Servicios – Dpto. de Informática Programación (Prof. Elec. - TUM), Programación I (TUG, TUR ) - Electrónica Programable (TUE) - 2015 Ejemplo: Si s1 es “locomotora” y s2 es “motor”, entonces s2 ES subsecuencia de s1. En cambio, si s1 es “locomotora” y s2 es “locos”, entonces s2 NO ES subsecuencia de s1. Nota: Una subsecuencia es una secuencia parte de una secuencia mayor. Ej. 12– Dado el siguiente código: #include <stdio.h> #include <string.h> int main (){ char s1[50]; char s2[20]; strcpy(s1, "concateno"); strcpy(s2, " cadenas"); strcat (s1, s2); printf("%s\n",s1); return(0); } a) Ejecutar paso a paso, y en forma gráfica, la secuencia de instrucciones. La ejecución debe reflejar, cómo trabajan las funciones de strings de biblioteca strcpy y strcat para cada uno de los caracteres. b) Modificar el código, usando funciones de strings de biblioteca, para que muestre la longitud de la cadena resultante. c) Escribir una función nstrcat, que concatene hasta n caracteres de la segunda cadena. Modificar el código para permitir al usuario el uso de dicha función. Ejercicios Propuestos para la carrera Técnico en Geoinformática Ej. 1– Escribir un programa que calcule la función y=sen(x)+PI para 20 valores de ángulos distintos ingresados por el usuario. Imprimir en el programa principal los 20 valores de x e y. Ej. 2- Escribir un programa que ingrese un número entero positivo (no mayor a 9999) y luego, mediante una función, lo modifique invirtiendo sus dígitos. Ejercicios Propuestos para el resto de las carreras Ej. 1- Realizar un programa que permita almacenar para 5 usuarios los tiempos de ejecución (los tiempos de ejecución se miden en segundos) de sus respectivos programas. Cada usuario puede ejecutar HASTA 10 programas. Se pide calcular el tiempo promedio de uso de la computadora para cada usuario. Como salida deberá mostrar los tiempos y su promedio. Las variables a usar deberán ser locales a la función main. Tanto el ingreso de los datos como el cálculo del promedio e impresión de los datos y resultados deberán ser desarrollados en sus respectivas funciones. Ej. 2 – Realizar un programa que lea una palabra en minúsculas y ordene en forma alfabética los caracteres que la forman. El ordenamiento debe realizarse sobre la misma estructura de almacenamiento donde se encuentran la palabra original. Los caracteres repetidos deberán ser eliminados. Solo se pueden utilizar variables simples como auxilio de programación. La salida del programa deberá mostrar la palabra ingresada y luego los caracteres ordenados en minúsculas. Ejemplo: Entrada “programacion” – Salida “acgimnopr” Práctico Nº 2 2do Cuatrimestre 5/6 Área de Servicios – Dpto. de Informática Programación (Prof. Elec. - TUM), Programación I (TUG, TUR ) - Electrónica Programable (TUE) - 2015 Funciones de biblioteca matemáticas en “C” (<math.h>) Contiene la declaración de algunas funciones para realizar operaciones matemáticas comunes sobre valores de tipo reales (float o double). acos asin double acos (double x); double asin (double x); Angulo cuyo coseno es "x", en el rango [0,p] radianes. Angulo cuyo seno es "x", en el rango [-p/2, +p/2] radianes. atan double atan (double x); Angulo cuya tangente es "x", en el rango [-p/2, +p/2] radianes. cos double cos (double x); Coseno de "x" (en radianes). exp double exp (double x); Exponencial de "x", ex. log double log (double x); Devuelve el logaritmo natural de "x". log10 double log10 (double x); Devuelve el logaritmo en base 10 de "x". pow double pow (double x, double y); Devuelve "x" elevado a la potencia "y". sin double sin (double x); Devuelve el seno de "x" (en radianes). sqrt double sqrt (double x); Devuelve la raíz cuadrada de "x". tan double tan (double x); Devuelve la tangente de "x" (en radianes). Ejemplo del uso de estas funciones: float a,t; a=31.50; t=tan(a); printf ( “La tangente de %f, es: %f \n”,a,t); Práctico Nº 2 2do Cuatrimestre 6/6