Problemario PDF

Algorítmica y programación Trayecto I, Fase I Los estudiantes deben responder las secciones 1 y 2, del dígito final de s

Views 88 Downloads 0 File size 308KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Algorítmica y programación Trayecto I, Fase I Los estudiantes deben responder las secciones 1 y 2, del dígito final de su número de cédula suma 1, si el resultado es número de dos dígitos vuelva a sumarlos y responda los problemas del resto de las secciones identificados por ese dígito. Ejemplo: mi número de cédula termina en 9, 9 + 1 = 10, luego 1 + 0 = 1, debo responder los problemas identificados por un número 1 en el resto de las secciones.

Nombre y sección: Profesor: Fecha:

1.

Teorema del programa estructurado

El teorema del programa estructurado es un resultado de la teoría de lenguajes de programación. Establece que toda función computable puede ser implementada en un lenguaje de programación que combine sólo tres estructuras lógicas. Esas tres formas (llamadas estructuras de control) son: 1. Secuencia: ejecución de una instrucción tras otra. 2. Selección: ejecución de una de dos instrucciones (o conjuntos), según el valor de una variable booleana. 3. Iteración: ejecución de una instrucción (o conjunto) mientras una variable booleana sea ’verdadera’. Esta estructura lógica se conoce como ciclo o bucle. Este teorema demuestra que la instrucción GOTO no es estrictamente necesaria y que para todo programa que la utilice existe otro equivalente que no hace uso de dicha instrucción. Los científicos de la computación acreditan el teorema a un artículo de 1966 escrito por Corrado Böhm y Giuseppe Jacopini. Sin embargo, David Harel rastreó sus orígenes hasta la descripción de 1946 de la arquitectura de von Neumann y el teorema de la forma normal de Kleene. 1

Describa en 50 palabras la arquitectura de von Neumann y en otras 50 palabras el teorema de la forma normal de Kleene .

Algorítmica y programación

Segundo Examen (Continua)

La demostración de Böhm-Jacopini describe cómo construir diagramas de flujo estructurados a partir de cualquier diagrama de flujo, usando los bits de una variable entera extra para dar seguimiento a la información que el programa original representa mediante puntos de entrada en el código. Esta construcción estuvo basada en el lenguaje de programación P de Böhm. La demostración de Böhm-Jacopini no esclareció la cuestión sobre cuándo convendría usar programación estructurada para el desarrollo de software, en parte porque la construcción ofuscaba el código del programa en lugar de mejorarlo. Por otro lado, fue el punto de partida para iniciar el debate. Edsger Dijkstra escribió una importante carta titulada ”La sentencia Go To considerada dañina” en el año 1968. Posteriores estudios agregaron aproximaciones más prácticas a la demostración de Böhm-Jacopini, que mantenían o mejoraban la claridad del programa original.

2.

Ejercicios selectos (el proceso) 1. Busque y lea la historia que existe atrás del lenguaje de programación C, y conteste al menos las siguientes preguntas: a) ¿Quién o quiénes fueron sus creadores? b) ¿Cómo fue su evolución? c) ¿En qué año surge? d ) ¿Cuántas versiones han habido? e) ¿A qué se refiere el ANSI C? f ) Investigue el concepto de código espagueti y compárelo con el concepto de programación estructurada. En base a lo anterior, ¿cuáles considera que serían las ventajas de tener una estructura dentro de un código fuente? g) Investigue qué lenguajes de programación además de C, soportan el paradigma estructurado. h) Investigue el concepto de Ingeniería de Software. i) Investigue el concepto de Proceso de Desarrollo de Software.

3.

Ejercicios selectos (bienvenido) 1. Investigue qué secuencias de escape existen y para qué sirven. Escriba un programa que las incluya, y pruebe cada una de ellas. 2. Escriba un programa en C que imprima su nombre completo en la pantalla en una sola línea. 3. Escriba un programa en C que imprima su nombre completo en la pantalla pero dividido en tres líneas: a) En la primera línea su(s) nombre(s). b) En la segunda línea su primer apellido. c) En la tercera línea su segundo apellido.

Page 2

Algorítmica y programación

Segundo Examen (Continua)

4. Diferentes culturas y pueblos tienen distintos tipos de leyendas y la disciplina de la computación no escapa a ellas. Se dice que todo aquel que se inicie en las maravillosas artes de la programación estructurada usando al lenguaje de programación C debe, si no quiere recibir la maldición de ser un mal programador toda su vida, escribir un programa que imprima, en la salida estándar el mensaje: Hola Mundo! Independientemente de sus creencias, evite el riesgo de la maldición y colabore con la perpetuidad de esta tradicional leyenda realizando este simple pero gratificante ejercicio de tal manera que, si el augurio se cumple, se dé por descartada al menos, la maldición... 5. Investigue qué otros tipos de datos, aparte de int, float, char existen en C, qué representación tienen, cuál es el rango de números que pueden almacenar, y cuál es el especificador de formato que utilizan para las funciones printf y scanf respectivamente. Nota: no siempre es el mismo. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

/* Programa 2.5 de uso del operador sizeof para determinar el numero de bytes requeridos para representar al operando asociado . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { int i ; double d ; printf ( ' ' sizeof ( i ) = %ld \ n ' ' , sizeof ( i ) ) ; printf ( ' ' sizeof ( int ) = %ld \ n ' ' , sizeof ( int ) ) ; printf ( ' ' \ nsizeof ( d ) = %ld \ n ' ' , sizeof ( d ) ) ; printf ( ' ' sizeof ( double ) = %ld \ n ' ' , sizeof ( double ) ) ; return 0; }

6. Extienda el Programa 2.5 para que considere todos los tipos de datos en C que investigó en el ejercicio anterior. El Programa 2.5 muestra el uso del operador unario (un operador unario se refiere a que el operador sólo necesita un operando para realizar su función; el operador + es un operador binario porque necesita dos operandos para realizar su función) sizeof para determinar el tamaño en bytes que ocupa el operando asociado. Observe también que el operador sizeof trabaja no sólo sobre tipos de datos (líneas 12 y 14), sino también sobre variables (líneas 11 y 13). El rango de los números representados por un tipo de dato depende del tamaño en bits del tipo de dato; para determinar el tamaño en bits multiplique el tamaño en bytes del tipo de dato y multiplíquelo por ocho. 1 2 3 4 5 6 7 8 9

/* Programa 2.3 para sumar dos enteros . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { int operando1 , operando2 , suma ;

Page 3

/* declaracion de variables */

Algorítmica y programación

printf ( " Operando1 ?: " ) ; scanf ( " %d " , & operando1 ) ; printf ( " Operando2 ?: " ) ; scanf ( " %d " , & operando2 ) ; suma = operando1 + operando2 ; asignacion */ printf ( " La suma es %d \ n " , suma ) ;

10 11 12 13 14 15 16 17 18

Segundo Examen (Continua)

}

/* /* /* /* /*

Solicitud ( prompt ) */ lee el primer operando */ Solicitud ( prompt ) */ lee el segundo operando */ Operacion de suma y

/* Imprime suma */

return 0;

7. Omita el uso del operador ”&” (ampersand) en la lectura de una variable como la que se hace en el Programa 2.3. ¿Qué sucede cuando compila? ¿Qué pasa cuando se ejecuta?, si el programa es ejecutado, ¿qué valor se guarda en la variable? 8. Escriba una programa que basándose en el Programa 2.3, realice la resta de dos números enteros decimales. 9. Escriba una programa que basándose en el Programa 2.3, realice la multiplicación de dos números enteros decimales. 10. Escriba una programa que basándose en el Programa 2.3, realice el módulo de dos números enteros decimales. ¿Qué podría pasar en este caso? 11. Escriba una programa que basándose en el Programa 2.3, realice la división de dos números enteros decimales ¿Qué podría pasar en este caso? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

/* Programa 2.4 para sumar dos enteros ( segunda version ) . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { int operando1 , operando2 , suma ;

/* declaracion de variables */

printf ( ' ' Operando1 ?: ' ' ) ; /* Solicitud ( prompt ) */ scanf ( ' ' %d ' ' , & operando1 ) ; /* lee el primer operando */ printf ( ' ' Operando2 ?: ' ' ) ; /* Solicitud ( prompt ) */ scanf ( ' ' %d ' ' , & operando2 ) ; /* lee el segundo operando */ suma = operando1 + operando2 ; /* Operacion de suma y asignacion */ printf ( ' ' %d + %d = %d \ n ' ' , operando1 , operando2 , suma ) ; return 0; }

12. Repita los ejercicios 8-11 con las consideraciones implementadas en el Programa 2.4. 13. Basándose en el Programa 2.4, modifíquelo para que ahora trabaje con números con punto decimal (float). Haga lo propio para los ejercicios 8, 9 y 11; tome en cuenta que el especificador de formato a utilizar es ahora ” %f”. Page 4

Algorítmica y programación

Segundo Examen (Continua)

14. Dependiendo del IDE que esté utilizando, investigue y documéntese acerca de la depuración de programas. Si está compilando en línea, busque un tutorial del programa gdb; en cualquier caso, debe saber que la depuración no sólo le será de suma utilidad, sino que es una tarea fundamental de la programación.

4.

Ejercicios selectos (estructuras de control)

4.1.

Primera Parte 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

/* Programa 3.1 que ilustra el uso de operadores relacionales , de comparacion y la estructura de control de seleccion if . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { int num1 , num2 ; printf ( ' ' Proporcione dos numeros enteros : ' ' ) ; scanf ( ' ' %d %d ' ' , & num1 , & num2 ) ; if ( num1 == num2 ) printf ( ' ' Los numeros son iguales %d == %d \ n ' ' , num1 , num2 ) ; if ( num1 != num2 ) printf ( ' ' Los numeros son distintos %d != %d \ n ' ' , num1 , num2 ) ; if ( num1 < num2 ) printf ( ' ' %d es menor estricto que %d \ n ' ' , num1 , num2 ) ; if ( num1 > num2 ) printf ( ' ' %d es mayor estricto que %d \ n ' ' , num1 , num2 ) ; if ( num1 = num2 ) printf ( ' ' %d es mayor o igual que %d \ n ' ' , num1 , num2 ) ; return 0; }

1. Escriba el Programa 3.1 eliminando los delimitadores de bloque para cada una de las estructuras de selección if, y compruebe que que sigue funcionando igual. Tome en cuenta que ésto es cierto cuando la estructura de control se compone únicamente de una única sentencia. 2. Escriba un programa que determine si un número entero positivo es par o impar. Un número par es aquel que es divisible por dos. 3. Escriba un programa que utilice una estructura de selección if-else y los operadores relacionales Page 5

Algorítmica y programación

Segundo Examen (Continua)

para determinar el menor de tres números enteros (asuma que los números son distintos). Para este ejercicio, no debe utilizar operadores lógicos, si no sabe qué son, mucho mejor, en su momento se presentarán en el blog. 4. Escriba un programa que utilice una estructura de selección if-else y los operadores relacionales para determinar el mayor de tres números enteros (asuma que los números son distintos). Para este ejercicio, no debe utilizar operadores lógicos, si no sabe qué son, mucho mejor, en su momento se presentarán en el blog. 5. Escriba un programa que utilice una estructura de selección if-else y los operadores relacionales para determinar el número central (en función de su ordinalidad) de tres números enteros (asuma que los números son distintos). Para este ejercicio, no debe utilizar operadores lógicos, si no sabe qué son, mucho mejor, en su momento se presentarán en el blog. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

/* Programa 3.6 mostrar el uso del operador ternario ' ' ? : ' ' . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { int num1 , num2 , mayor ; printf ( ' ' Introduzca dos numeros distintos : ' ' ) ; scanf ( ' ' %d %d ' ' , & num1 , & num2 ) ; mayor = num1 > num2 ? num1 : num2 ; printf ( ' ' El mayor es : %d \ n ' ' , mayor ) ; return 0; }

6. Reescriba el Programa 3.6 usando la simplificación de líneas descrita para el operador ternario (vea el penúltimo párrafo de la entrada El operador ternario ? :) y compruebe su equivalencia, ¿cuál es mejor y por qué?, ¿en qué casos convendría utilizar una u otra? 7. Reescriba el Programa 3.6 utilizando una estructura de selección if-else en lugar del operador ternario. 8. Escriba un programa que utilice el operador ternario para determinar el menor de dos números enteros. Este programa es similar al del Programa 3.6. 1 2 3 4 5 6 7 8 9 10 11

/* Programa 3.7 para traducir numeros a palabras . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { int num ; printf ( ' ' Numero (1 -3) ? ' ' ) ; scanf ( ' ' %d ' ' , & num ) ;

Page 6

Algorítmica y programación 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

Segundo Examen (Continua)

switch ( num ) { case 1: printf ( ' ' El numero es UNO \ n ' ' ) ; break ; case 2: printf ( ' ' El numero es DOS \ n ' ' ) ; break ; case 3: printf ( ' ' El numero es TRES \ n ' ' ) ; break ; default : printf ( ' ' Indescifrable ...\ n ' ' ) ; } return 0; }

9. Extienda el Programa 3.7 para que el rango de conversión de números a palabras sea más amplio: agregue las sentencias necesarias de tal forma que el programa considere al menos números del uno al diez, ¿qué sucede si al ejecutar el programa en lugar de un número escribe una letra? 10. Escriba un programa que convierta lo siguientes números a su correspondiente número romano: 1, 5, 9, 14, 20, 26, 40, 50, 90, 99, 100, 500 y 1000. Para cualquier otro número se deberá reportar: ”No existe traducción disponible”. 11. Convierta el Programa 3.7 y el ejercicio anterior a su correspondiente representación con una estructura de selección if-else anidada. Para este ejercicio, asuma que no existe la estructura de control switch; la idea es obtener la misma funcionalidad cambiando la estructura switch por una estructura if-else. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5

/* Programa 3.8 de la estructura de control de repeticion while . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { int i ;

/* variable de control */

i = 1; /* inicializacion de la variable de control */ while ( i

Page 7

Algorítmica y programación 6 7 8 9 10 11 12 13 14 15 16 17 18

Segundo Examen (Continua)

# define NUM 10 int main () { int i ;

/* variable de control */

i = 1; /* inicializacion de la variable de control */ while ( i int main () { int m , n ; n = 5; m = n ++; printf ( ' ' m = %d y n = %d \ n ' ' , m , n ) ; n = 5; m = ++ n ; printf ( ' ' m = %d y n = %d \ n ' ' , m , n ) ; return 0; }

14. Para el Programa 3.10 sustituya el operador de incremento (++) por el operador de decremento (–), analice lo que sucederá, determine su respuesta y compruébela con la ejecución correspondiente. 15. Escriba un programa que imprima en la salida estándar los números del uno al diez, uno por renglón pero en orden inverso; es decir: 10, 9, 8, 7, . . . , 1. No utilice el operador de decremento. 16. Escriba un programa que imprima los números del uno al diez uno por renglón pero en orden inverso; es decir: 10, 9, 8, 7, . . . , 1. Utilice el operador de decremento. 17. Reescriba el Programa 3.9 utilizando la estructura de repetición do-while. 1 2 3

/* Programa 3.12 para dividir dos enteros ( cuarta version ) . @autor Jorge Dominguez Chavez */

Page 8

Algorítmica y programación 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Segundo Examen (Continua)

# include < stdio .h > int main () { int num , den , div ; printf ( ' ' Numerador ?: ' ' ) ; scanf ( ' ' %d ' ' , & num ) ; do { printf ( ' ' Denominador (!=0) ?: ' ' ) ; scanf ( ' ' %d ' ' , & den ) ; } while ( den == 0) ; div = num / den ; printf ( ' ' %d / %d = %d \ n ' ' , num , den , div ) ; return 0; }

18. Reescriba el Programa 3.12 utilizando la estructura de repetición while. 19. Repita el Ejercicio 16 utilizando ahora la estructura de repetición do-while. 20. Escriba un programa que imprima en la salida estándar los números del 1 a n, donde n es un valor proporcionado por el usuario de su programa. Así por ejemplo, si n es 6, su programa imprimirá los números del 1 al 6. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

/* Programa 3.13 de la estructura de repeticion for . @autor Jorge Dominguez Chavez */ # include < stdio .h > # define NUM 10 int main () { int i ; /* inicializacion , expresion , y modificacion */ for ( i = 1; i int main () { int sum , n , i ; printf ( ' ' Programa para calcular la sumatoria \ n ' ' ) ; printf ( ' ' de i , con i = 1 hasta n .\ n ' ' ) ; do { printf ( ' ' n ( > 0) ?: ' ' ) ; scanf ( ' ' %d ' ' , & n ) ; } while ( n < 1) ; /* verifica que n sea valido */ for ( i = 1 , sum = 0; i # include < stdlib .h > # include < time .h > # define M 15 int main () { int i ; srand ( time ( NULL ) ) ; /* Inicializa la semilla */ for ( i = 1; i # define NUM 10 # define CENTINELA 5 int main () { int i ; for ( i = 1; i

1 2 3

/* Que hace este programa 3.23? @autor Jorge Dominguez Chavez */

# define M 10 int main () { int i ; for ( i = 1; i # define M 10 int main () { int i , j ; for ( i = 1; i # include < time .h > # define M 50 int main () { int i ; srand ( time ( NULL ) ) ; for ( i = 1; i int main () { int simbolo ; int as = 0 , es = 0 , is = 0 , os = 0 , us = 0; printf ( ' ' Introduza un texto ( EOF para terminar ) :\ n ' ' ) ; while (( simbolo = getchar () ) != EOF ) { /* EOF = End Of File */ switch ( simbolo ) { /* switch anidado dentro de while */ case ' A ' : case ' a ' : /* Cuenta las a ' s */ as ++; break ; case ' E ' : case ' e ' : /* Cuenta las e ' s */ es ++; break ; case ' I ' : case ' i ' : /* Cuenta las i ' s */ is ++; break ; case ' O ' : case ' o ' : /* Cuenta las o ' s */ os ++; break ; case ' U ' : case ' u ' : /* Cuenta las u ' s */ us ++; break ; default : /* ignora todos los otros caracteres */ break ; } } printf ( ' ' \ nTotal de vocales :\ n ' ' ) ; printf ( ' ' a ' s : %d \ te ' s : %d \ ti ' s : %d \ to ' s : %d \ tu ' s : %d \ n ' ' , as , es , is , os , us ) ; return 0; }

8. Pruebe con más datos el Programa 3.17, proporcionados tanto del teclado como de un archivo siguiendo los mecanismos de re direccionamiento. Page 13

Algorítmica y programación

Segundo Examen (Continua)

9. Escriba un programa que, siguiendo la idea del Programa 3.17 y considerando un esquema de calificaciones basado en letras (A, B, C, D y F), procese un conjunto de dichas calificaciones desde la entrada estándar y determine cuántas calificaciones hay de cada una. Si se procesa una calificación no considerada, se deberá indicar dicha irregularidad (no existe la calificación E por ejemplo). 10. Escriba un programa que lea dos números enteros: a) Si los números son iguales, su programa reporta dicha situación y termina. b) Si el primer número (num1) es menor que el segundo (num2), su programa deberá imprimir en la salida estándar la sucesión ascendente de números de num1 a num2; es decir: num1, num1+1, num1+2, . . . num2. c) Si el primer número (num1) es mayor que el segundo (num2), su programa deberá imprimir en la salida estándar la sucesión descendente de números de num1 a num2; es decir: num1, num1-1, num1-2, . . . num2. 11. Escriba un programa que determine si un número entero positivo n es o no un número primo. Un número primo es aquel que sólo es divisible por sí mismo y la unidad. Sugerencia: intente con un ciclo todos los posibles divisores de n, si tiene más de dos, no es primo. Otro enfoque es descartar los divisores obvios (1 y n) y buscar algún divisor entre 2 y n/2 (para n >2), si existe alguno, no es primo. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

/* Programa 3.18 que calcula el promedio de unas calificaciones usando repeticion controlada por contador . @autor Jorge Dominguez Chavez */ # include < stdio .h > # define N 10 int main () { int contador ; float calificacion , total ; total = 0.0; contador = 1; while ( contador ++ # define CENTINELA -1 int main () { int contador ; float calificacion , total ; total = 0; contador = 0; printf ( ' ' Calificacion ? ( -1 para terminar ) : ' ' ) ; scanf ( ' ' %f ' ' , & calificacion ) ; while ( calificacion != CENTINELA ) { total += calificacion ; contador ++; printf ( ' ' Calificacion ? ( -1 para terminar ) : ' ' ) ; scanf ( ' ' %f ' ' , & calificacion ) ; } if ( contador != 0) printf ( ' ' Promedio de las calificaciones : %.1 f \ n ' ' , total / contador ); else printf ( ' ' No se proporcionaron calificaciones \ n ' ' ) ; return 0; }

17. Reescriba el Programa 3.19 con una estructura de repetición do-while y asegúrese de que sea lógica y funcionalmente equivalente. Reescriba el Programa 3.19 con una estructura de repetición for y asegúrese de que sea lógica y funcionalmente equivalente.

Page 15

Algorítmica y programación

Segundo Examen (Continua)

18. Modifique el Programa 3.19 para que las calificaciones sean validadas (que estén entre cero y diez). Utilice la estructura de repetición while para la repetición controlada por centinela. 19. Repita el ejercicio anterior pero utilice la estructura de repetición do-while para la repetición controlada por centinela. 20. Repita el ejercicio anterior pero utilice la estructura de repetición for para la repetición controlada por centinela. 21. Escriba un programa que realice la suma de los números del uno al diez: a) Utilice la estructura de repetición while. b) Utilice la estructura de repetición do-while. 22. Escriba una programa que realice la suma de números enteros procesados desde la entrada estándar. La suma se detiene cuando el número leído sea igual a cero. a) Utilice la estructura de repetición while. b) Utilice la estructura de repetición do-while. 23. Escriba un programa que permita determinar el mayor de n números proporcionados desde el teclado, donde n >1. 24. Escriba un programa que permita determinar la suma de los primeros n números enteros positivos proporcionados desde el teclado, donde n >1. Para este programa, si el usuario introduce números negativos se deberán ignorar, y el programa deberá considerar únicamente la suma de números positivos. 25. Escriba un programa que permita determinar por selección la suma de los primeros n números pares (n >1). Su programa no debe generar los números pares, debe seleccionarlos. 26. Escriba un programa que permita determinar por selección la suma de números pares contenidos entre 1 y n, donde n >1. Su programa no debe generar los números pares, debe seleccionarlos. 27. Escriba un programa que permita determinar por selección la suma de números pares contenidos entre m y n, donde m >1 y n >m. Su programa no debe generar los números pares, debe seleccionarlos. 28. Escriba un programa que permita identificar los números primos entre 1 y n, donde n >1. 29. Escriba un programa que permita determinar los números primos contenidos entre m y n, donde m >1 y n >m. 30. Dada una lista de números enteros positivos proporcionados desde la entrada estándar, determine el mayor y el menor de ellos. La lista termina al proporcionar cualquier número negativo o cero. 31. ¿Qué conclusiones puede determinar de la realización de los seis ejercicios anteriores?, ¿qué tipo de estructura de repetición es más natural, desde su perspectiva, para una repetición controlada por contador y por qué? En este mismo sentido, ¿qué tipo de estructura de repetición es más natural para una repetición controlada por centinela? Page 16

Algorítmica y programación 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Segundo Examen (Continua)

/* Programa 3.20 que muestra el uso de la sentencia continue . @autor Jorge Dominguez Chavez */ # include < stdio .h > # define NUM 10 # define CENTINELA 5 int main () { int i ; for ( i = 1; i # define NUM 10 # define CENTINELA 5 int main () { int i ; for ( i = 1; i # include < math .h > int main () { int a , b , c , d ; float x1 , x2 , r1 , r2 ; printf ( ' ' Programa para determinar las raices reales de una ecuacion \ n ' ' ) ; printf ( ' ' de la forma Ax ^2 + Bx + C = 0\ n \ n ' ' ) ; do { printf ( ' ' A (!=0) ?: ' ' ) ; scanf ( ' ' %d ' ' , & a ) ; } while ( a == 0) ; printf ( ' ' B ?: ' ' ) ; scanf ( ' ' %d ' ' , & b ) ; printf ( ' ' C ?: ' ' ) ; scanf ( ' ' %d ' ' , & c ) ; d = ( b * b ) - (4 * a * c ) ; if ( d < 0) { printf ( ' ' La ecuacion no tiene solucion en R \ n ' ' ) ; } else { x1 = ( - b + sqrt ( d ) ) / (2* a ) ; x2 = ( - b - sqrt ( d ) ) / (2* a ) ; printf ( ' ' \ nX1 = %.1 f \ t == > ' ' , x1 ) ; r1 = a *( x1 * x1 ) + b * x1 + c ; printf ( ' ' %d ( %.1 f ) ^2 + %d ( %.1 f ) + %d = %f \ n ' ' , a , x1 , b , x1 , c , r1 ); printf ( ' ' X2 = %.1 f \ t == > ' ' , x2 ) ; r2 = a *( x2 * x2 ) + b * x2 + c ; printf ( ' ' %d ( %.1 f ) ^2 + %d ( %.1 f ) + %d = %f \ n ' ' , a , x2 , b , x2 , c , r2 ); } return 0; }

1. Modifique el Programa 4.1 para que considere el caso cuando la ecuación cuadrática sólo tiene una raíz, i.e. cuando el discriminante es igual a cero; de tal forma que sólo se calcule y presente Page 18

Algorítmica y programación

Segundo Examen (Continua)

un resultado en la salida estándar. 2. Modifique el ejercicio anterior para que tantos los coeficientes de la ecuación como las raíces, sean ahora tipos de dato double. No olvide hacer los ajustes correspondientes para los especificadores de formato. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

/* Programa 4.2 que determina , utilizando funciones , el mayor y menor de tres numeros enteros distintos . @autor Jorge Dominguez Chavez */ # include < stdio .h > int mayor ( int , int , int ) ; int menor ( int , int , int ) ; int main () { int a , b , c ; do { printf ( ' ' Proporcione tres numeros enteros distintos : ' ' ) ; scanf ( ' ' %d %d %d ' ' , &a , &b , & c ) ; } while (( a == b ) || ( a == c ) || ( b == c ) ) ; printf ( ' ' El mayor es : %d \ n ' ' , mayor ( a , b , c ) ) ; printf ( ' ' El menor es : %d \ n ' ' , menor ( a , b , c ) ) ; return 0; } int mayor ( int x , int y , int z ) { int max = x ; if ( y > max ) max = y ; if ( z > max ) max = z ; return max ; } int menor ( int x , int y , int z ) { int min = x ; if ( y < min ) min = y ; if ( z < min ) min = z ; return min ; }

Page 19

Algorítmica y programación

Segundo Examen (Continua)

3. Modifique el Programa 4.2 para que las variables de la función main sean x ,y y z ¿Compila?, ¿por qué? Suponiendo que compila, ¿cambia en algo el funcionamiento del programa?, ¿por qué? ¿Y si ahora se cambia el nombre de los parámetros de las funciones por a, b y c? 4. Complete el Programa 4.2 con la función medio, la cual devuelve el número de en medio en base a su valor ordinal. Utilice lo resuelto en el Ejercicio 5 (Primera Parte) de la entrada Ejercicios selectos para las estructuras de control. 5. Escriba un programa que, a través de una función, calcule el cuadrado de un número double. 6. Utilice la función desarrollada en el ejercicio anterior para resolver el problema del Ejemplo 4.1. Observe que en la línea 22 el discriminante lleva el cálculo de b al cuadrado (b²); utilice su función para calcular dicho valor. 7. Escriba una función que convierta de millas a kilómetros. Una milla es aproximadamente igual a 1.61 kilómetros. Escriba un programa que pruebe su función. 8. Escriba una función que convertir de kilómetros a millas. Escriba un programa que pruebe su función. 9. El factorial de un número n (n >= 0) denotado por n! se obtiene según lo definido en la siguiente expresión: n! = n * (n - 1) * (n - 2) * . . . * 1; es decir, se multiplica el número, por su antecesor y éste por su respectivo antecesor y así sucesivamente hasta llegar al neutro multiplicativo. Escriba una función que calcule el factorial de un número. 10. Escriba un programa que a través de una función, calcule el producto de dos números enteros a y b por medio de sumas sucesivas, esto es: a * b = a + a + . . . + a, donde a se suma tantas veces como lo indique b. Para ello: a) Resuelvalo primero con dos números enteros positivos. b) ¿Qué pasa si alguno de los números es negativo? ¿Cómo se comporta su algoritmo, representado en la función, ante dicha situación? Tome en cuenta que el resultado es un número negativo. c) ¿Qué pasa si ambos números son negativos? ¿Cómo se comporta su algoritmo, representado en la función, ante dicha situación? Tome en cuenta que para este caso el resultado es un número positivo. 11. Escriba un programa que a través de una función, calcule el cociente entero de dos números enteros positivos a y b por medio de restas sucesivas, esto es a / b ==> a - b = c1, si c1 >= b, entonces c1 - b = c2, si c2 >= b, entonces c2 - b = c3, si c3 >= b, entonces ... donde el cociente estará dado por el número de veces que se haya podido repetir el procedimiento descrito. 12. Escriba un programa que a través de una función, calcule la potencia de dos números a y b por medio de productos sucesivos, esto es:

Page 20

Algorítmica y programación

Segundo Examen (Continua)

ab = a ∗ a ∗ ... ∗ a donde a se multiplica tantas veces como lo indique b. Para ello: a) b) c) d)

Resuélvalo primero con dos números enteros positivos. ¿Qué pasa si a es negativo? ¿Qué aspectos debe tomar en consideración si b es negativo? ¿Qué pasa si a o b son cero? ¿Qué pasa si ambos lo son?

13. Repita el ejercicio anterior, pero en lugar de usar el operador de multiplicación (*), utilice la función que desarrolló en el Ejercicio 10. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

/* Programa 4.4 para ilustrar los ambitos de definicion y existencia de varibales automaticas y estaticas ( version compacta ) . @autor Jorge Dominguez Chavez */ # include < stdio .h > void funcion1 ( void ) ; void funcion2 ( void ) ; void funcion3 ( void ) ; int x = 1; int main () { int x = 10;

/* variable global : mala practica */ /* variable local de main */

printf ( ' ' Valor de x = { /* nuevo int x = 50; printf ( ' ' Valor de x } /* nuevo printf ( ' ' Valor de x

%d ( main ) \ n ' ' , x ) ; ambito interno ( inicio ) */ = %d ( main - > ambito interno ) \ n ' ' , x ) ; ambito interno ( fin ) */ = %d ( main ) \ n ' ' , x ) ;

funcion1 () ; funcion2 () ; funcion3 () ; funcion1 () ; funcion2 () ; funcion3 () ; printf ( ' ' \ nValor de x = %d ( main ) \ n ' ' , x ) ; }

return 0;

void funcion1 ( void ) { int x = 100; /* la varible se crea e inicializa en cada llamado */ printf ( ' ' \ nValor de x = %d al entrar ( funcion1 ) \ n ' ' , x ++) ; printf ( ' ' Valor de x = %d al salir ( funcion1 ) \ n ' ' , x ) ; } void funcion2 ( void ) { static int x = 1000; /* la varible se crea e inicializa una sola vez */

Page 21

Algorítmica y programación 39 40 41 42 43 44 45 46

}

Segundo Examen (Continua)

printf ( ' ' \ nValor de x = %d al entrar ( funcion2 ) \ n ' ' , x ++) ; printf ( ' ' Valor de x = %d al salir ( funcion2 ) \ n ' ' , x ) ;

void funcion3 ( void ) { printf ( ' ' \ nValor de x = %d al entrar ( funcion3 ) \ n ' ' , x ++) ; printf ( ' ' Valor de x = %d al salir ( funcion3 ) \ n ' ' , x ) ; }

14. Si para el Programa 4.4 se realizara una nueva ronda de llamados consecutivos a cada una de las tres funciones involucradas, ¿cuáles serían los valores que se visualizarían en la salida estándar? 15. Para el Ejemplo 4.6 elimine la línea 7, guarde el archivo, y compile. ¿Qué sucede?, ¿a qué se debe y por qué? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

/* Programa 4.5 con Funciones que determinan el mayor y menor de tres numeros enteros distintos que forman parte de la primera biblioteca personalizada de funciones . @autor Jorge Dominguez Chavez */ int mayor ( int x , int y , int z ) { int max = x ; if ( y > max ) max = y ; if ( z > max ) max = z ; return max ; } int menor ( int x , int y , int z ) { int min = x ; if ( y < min ) min = y ; if ( z < min ) min = z ; return min ; }

16. Incorpore a la biblioteca personalizada de funciones del Programa 4.5 la función medio realizada en el Ejercicio 4 y pruebe su funcionamiento. 17. Escriba una función que determine si un número entero positivo es o no un número primo. Un número primo es aquél que es divisible únicamente por la unidad y sí mismo. Su función deberá regresar un 1 si el número enviado como argumento es primo y 0 si no lo es. Page 22

Algorítmica y programación

Segundo Examen (Continua)

18. Escriba una función que determine si un número es perfecto o no. Un número perfecto es un entero positivo que es igual a la suma de sus divisores positivos sin considerarse él mismo como divisor. Escriba un programa que, dado un número de hasta cinco cifras, exprese el valor de dicho número en palabras. Así por ejemplo, para el número 99 999, el programa dará como salida: ”99 999: noventa y nueve mil novecientos noventa y nueve”. El castellano (español) es un idioma complejo, así que si la salida de su programa es ”99 999: noventa y nueve mil nueve cientos noventa y nueve”, o genera expresiones por el estilo, considérelo correcto. El número debe ser leído como tal, y su análisis consiste en ”desmenuzarlo” en unidades, centenas, millares, etcétera e identificar los patrones convenientes para expresarlo en palabras. 19. Pruebe creando otras bibliotecas personalizadas de funciones con los ejemplos y ejercicios realizados hasta ahora. No importa por ahora que las funciones de dichas bibliotecas no tengan mucha relación, lo que importa por ahora es practicar la creación de bibliotecas personalizadas de funciones.

6.

Ejercicios selectos (apuntadores) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

/* Programa 7.1 que muestra la declaracion de un apuntador a entero , el uso del operador de direccion (&) y de desreferencia (*) . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { int a ; int * aPtr , * bPtr ; a = 40178; aPtr = & a ; /* aPtr apunta a la variable a */ bPtr = & a ; /* bPtr guarda la direccion de la variable a */ printf ( ' ' Direccion de a : %p \ n ' ' , & a ) ; printf ( ' ' Valor de aPtr : %p \ n ' ' , aPtr ) ; printf ( ' ' \ nValor de a : %d \ n ' ' , a ) ; printf ( ' ' Valor de * aPtr ( desreferencia ) : %d \ n ' ' , * aPtr ) ; * bPtr = 2018; printf ( ' ' \ nValor de a : %d \ n ' ' , a ) ; return 0; }

1. Ajuste el Programa 7.1 para que: a) Imprima el contenido del apuntador bPtr, es decir, la dirección en memoria de a que almacena bPtr. b) Modifique el valor de la variable a a través de aPtr.

Page 23

Algorítmica y programación

Segundo Examen (Continua)

c) Declare una nueva variable de tipo entero b, asígnele un valor, haga que bPtr apunte a ella, y cambie el valor de b a través de bPtr. d ) Trate de asignar un valor directamente (no use el operador de dirección) a cualquiera de los apuntadores ¿Qué sucede y por qué? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

/* Programa 7.2 que muestra la diferencia entre un parametro por valor y uno por referencia ( apuntador ) . @autor Jorge Dominguez Chavez */ # include < stdio .h > void llamadaValor ( int ) ; void llamad aReferen cia ( int *) ; int main () { int argumento = 40178; printf ( ' ' Valor de argumento ( main () ) : %d \ n ' ' , argumento ) ; llamadaValor ( argumento ) ; /* parametro = argumento */ printf ( ' ' \ nValor de argumento ( main () ) : %d \ n ' ' , argumento ) ; llama daRefere ncia (& argumento ) ; /* parametro = & argumento */ printf ( ' ' \ nValor de argumento ( main () ) : %d \ n ' ' , argumento ) ; }

return 0;

void llamadaValor ( int parametro ) { printf ( ' ' \ nValor de argumento ( llamadaValor () ) : %d \ n ' ' , parametro ) ; parametro *= 2; printf ( ' ' Valor de argumento ( llamadaValor () ) : %d \ n ' ' , parametro ); } void llamad aReferen cia ( int * parametro ) { printf ( ' ' \ nValor de argumento ( ll amadaRef erencia () ) : %d \ n ' ' , * parametro ) ; * parametro *= 2; /* * parametro = * parametro * 2; */ printf ( ' ' Valor de argumento ( l lamadaRe ferencia () ) : %d \ n ' ' , * parametro ) ; }

2. Reescriba desde cero el Programa 7.2. El objetivo de este ejercicio es replicar dicho ejemplo desde su perspectiva y compresión de los conceptos explicados en el blog. 1 2 3 4 5 6

/* Programa 7.3 que muestra el uso del modificador const con apuntadores , y el recorrido de cadenas por medio de apuntadores . @autor Jorge Dominguez Chavez */ # include < stdio .h > # define ESP ACI0_EN_ BLANCO ' '

Page 24

Algorítmica y programación 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

Segundo Examen (Continua)

void i mpr im eS inE sp ac ios ( const char *) ; void imprimeAlReves ( const char *) ; int main () { char cadena [] = ' ' Dabale arroz a la zorra el abad ' ' ; printf ( ' ' Cadena original : %s \ n ' ' , cadena ) ; imprimeAlReves ( cadena ) ; /* cPtr = & cadena [0] */ im pr im eSi nE sp aci os ( cadena ) ; /* cPtr = cadena */ printf ( ' ' Cadena original : %s \ n ' ' , cadena ) ; }

return 0;

void i mpr im eS inE sp ac ios ( const char * cPtr ) { while (* cPtr != ' \0 ' ) { /* Mientras no hagas referencia a fin de cadena */ if (* cPtr != E SPACI0_E N_BLANCO ) putchar (* cPtr ) ; cPtr ++; /* Avanza a la siguiente posicion de la cadena */ } putchar ( ' \ n ' ) ; } void imprimeAlReves ( const char * cPtr ) { const char * inicioPtr = cPtr ; /* Respalda la direccion de inicio */ while (* cPtr != ' \0 ' ) /* Mientras no hagas referencia a fin de cadena */ cPtr ++; /* Avanza a la siguiente posicion de la cadena */ while ( cPtr -- != inicioPtr ) /* Mientras no llegues al inicio ( linea 32) */ putchar (* cPtr ) ; putchar ( ' \ n ' ) ; }

3. Modifique el Programa 7.3 para que lea una cadena de la entrada estándar, y la envíe a las funciones imprimeAlReves e imprimeSinEspacios. 4. Determine lo que realiza la siguiente función sin ejecutarla. Posteriormente, corrobore su respuesta con un programa que pruebe la función. 5. Escriba un programa que pruebe cada una de las funciones de la biblioteca ctype. Su programa deberá probar al menos las funciones descritas en la entrada Aritmética de apuntadores, pero recuerde que dicha biblioteca contiene más funciones. 1 2 3 4

/* Programa 7.4 de uso de las funciones islower y toupper de la biblioteca estandar de funciones ctype . h . @autor Jorge Dominguez Chavez */

Page 25

Algorítmica y programación 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

Segundo Examen (Continua)

# include < stdio .h > # include < ctype .h > # define TAM 100 # define FIN_DE_CADENA ' \0 ' void c o n v ie r t e A M a y u s c u l a s ( char *) ; int main () { char cadena [ TAM ]; printf ( ' ' Introduzca una cadena : ' ' ) ; gets ( cadena ) ; c o n v i e r t e A M ay u s c u l a s ( cadena ) ; printf ( ' ' Su cadena en mayusculas es : %s \ n ' ' , cadena ) ; return 0; } void c o n v ie r t e A M a y u s c u l a s ( char * cPtr ) { for ( ; * cPtr != FIN_DE_CADENA ; cPtr ++) if ( islower (* cPtr ) ) * cPtr = toupper (* cPtr ) ; }

6. Con base en el programa del Programa 7.4, escriba una función análoga a la que convierteAMayusculas que convierta la cadena referida por cPtr a minúsculas; utilice las funciones de la biblioteca ctype descritas en la entrada Aritmética de apuntadores. 7. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void rellenaArreglo(int *a, int n, int rango). La función deberá inicializar los n elementos referidos por a con números aleatorios definidos entre 0 y rango - 1. 8. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void inicializaArreglo(int *a, int n, int valor). La función deberá inicializar los n elementos referidos por a, con el valor valor. 9. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void imprimeArreglo(const int *a, int n, int c). La función deberá imprimir en la salida estándar, los n elementos referidos por a, con c elementos por renglón. 1 2 3 4 5 6 7 8 9 10

/* Programa 7.5 de un arreglo de apuntadores a caracteres para convertir alfabeto ingles a codigo Morse . @autor Jorge Dominguez Chavez */ # include < stdio .h > int main () { char letra ; const char * codigoMorse [] = { ' ' . - ' ' , ' ' -... ' ' , ' ' -. -. ' ' , ' ' -.. ' ' , ' ' . ' ' , ' ' .. -. ' ' , ' ' --. ' ' , ' ' .... ' ' ,

Page 26

Algorítmica y programación 11 12 13 14 15 16 17 18 19 20

Segundo Examen (Continua)

' ' .. ' ' , ' ' . -- -' ' , ' ' -. - ' ' , ' ' . -.. ' ' , ' ' --' ' , ' ' -. ' ' , ' ' ---' ' , ' ' . - -. ' ' , ' ' --. - ' ' , ' ' . -. ' ' , ' ' ... ' ' , ' ' -' ' , ' ' .. - ' ' , ' ' ... - ' ' , ' ' . - - ' ' , ' ' -.. - ' ' , ' ' -. --' ' , ' ' - -.. ' ' }; for ( letra = ' a ' ; letra # include < stdlib .h > # include < time .h > # define N 5 int int int int

main () { estatico [ N ]; * dinamico ; i, j;

srand ( time ( NULL ) ) ; for ( i = 0; i < N ; i ++) estatico [ i ] = rand () ; dinamico = ( int *) malloc ( N * sizeof ( int ) ) ; if ( dinamico != NULL ) { for ( i = 0 , j = N -1; i < N ; i ++ , j --) dinamico [ j ] = estatico [ i ]; /* *( dinamico + j ) = estatico [ i ]; */ for ( i = 0; i < N ; i ++) { printf ( ' ' estatico [ %d ] = %d \ t ' ' , i , estatico [ i ]) ; /* printf ( ' ' *( estatico + %d ) = %d \ t ' ' , i , *( estatico + i ) ) ; */ printf ( ' ' *( dinamico + %d ) = %d \ n ' ' , i , *( dinamico + i ) ) ; /* printf ( ' ' dinamico [ %d ] = %d \ n ' ' , i , dinamico [ i ]) ; */ } free ( dinamico ) ; } else

Page 27

Algorítmica y programación 33 34 35 36 37

Segundo Examen (Continua)

printf ( ' ' No hubo memoria \ n \ a ' ' ) ; putchar ( ' \ n ' ) ; return 0; }

11. Con base en el Programa 7.6 y a la notación de aritmética de apuntadores, substituya la línea 24 por el comentario correspondiente de la misma línea, y compruebe la equivalencia de la notación. Realice lo mismo intercambiando las líneas 26 y 27, y las líneas 28 y 29 respectivamente. 12. Escriba un programa que defina y pruebe una función con el siguiente prototipo: int *copiaArreglo(const int *original, int n). La función deberá copiar los n elementos referidos por original en un arreglo que haya sido creado utilizando memoria dinámica dentro de la función, mismo que será utilizado como valor de retorno para la función. 13. Escriba un programa que defina y pruebe una función con el siguiente prototipo: char *copiaCadena(const char *original). La función deberá copiar los elementos referidos por original, en un arreglo de caracteres que haya sido creado utilizando memoria dinámica dentro de la función, mismo que será utilizado como su valor de retorno. 14. Escriba un programa que defina y pruebe una función con el siguiente prototipo: int compara(const char *c1, const char *c2 ). La función deberá determinar si los elementos referidos por c1 son iguales (regresa 1) o no (regresa 0) a los elementos referidos por c2. 15. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void imprimeAlReves(const char *original). La función deberá imprimir invertidos los elementos referidos por original. La función deberá usar recursividad para imprimir al revés los elementos referidos por original. 16. Escriba un programa que defina y pruebe una función con el siguiente prototipo: char *invierteCadena(const char *original). La función deberá copiar invertidos los elementos referidos por original, en un arreglo de caracteres que haya sido creado utilizando memoria dinámica dentro de la función, mismo que será utilizado como su valor de retorno. 17. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void quitaEspacios(char *c). La función deberá eliminar (si los hubiera) cualquiera de los tipos de espacios de la cadena referida por c. Note que la función modifica la cadena original, por lo que deberá 0 asegurarse de terminar adecuadamente la cadena con el fin de cadena 0 . 18. Escriba un programa que defina y pruebe una función con el siguiente prototipo: int esPalindromo(const char *c). La función deberá determinar si los elementos referidos por c constituyen (regresa 1) o no (regresa 0) un palíndromo. Tome en cuenta que la función deberá ignorar espacios, signos de puntuación, signos de admiración e interrogación, comillas, etcétera, y que no hará distinción entre mayúsculas y minúsculas; puede auxiliarse de las funciones desarrolladas hasta el momento en los ejercicios y en los ejemplos del blog.

Page 28