¡Descarga Programación en c Ejercicios resueltos y más Ejercicios en PDF de Programación C solo en Docsity!
ESCUELA SUPERIOR DE INGENIEROS INDUSTRIALES
UNIVERSIDAD DE NAVARRA
INDUSTRI INJINERUEN GOIMAiLAKO ESKOLA
NAFARROAKO UNIBERTSITATEA
Practique Lenguaje ANSI C
como si estuviera en Primero
Madrid, 31 mayo de 2003
Profesores:
Javier García de Jalón de la Fuente
José Ignacio Rodríguez Garrido
Rufino Goñi Lasheras
Alfonso Brazález Guerra
Patxi Funes Martínez
Rubén Rodríguez Tamayo
- INTRODUCCIÓN
- PRACTICA 1.
- Ejercicio 1.1: El primer programa..............................................................................................................................
- Solución comentada al Ejercicio 1.1.
- Ejercicio 1.2: Una conversación en C.
- Solución comentada al Ejercicio 1.2.
- Ejercicio 1.3: Una pequeña operación aritmética.......................................................................................................
- Solución comentada al Ejercicio 1.3.
- Ejercicio 1.4: Preguntas indiscretas.
- Solución comentada al Ejercicio 1.4.
- Ejercicio 1.5: Programa que suma los cinco primeros números naturales.
- Solución comentada al Ejercicio 1.5.
- Ejercicio 1.6: Modifica el programa mascota.c
- Solución comentada del Ejercicio 1.6.
- Ejercicio 1.7: Modifica el programa sumaInt.c
- Solución comentada del Ejercicio 1.7.
- Ejercicio 1.8: Solución de la ecuación de segundo grado.
- Solución comentada al Ejercicio 1.8.
- Ejercicio 1.9: Para expertos........................................................................................................................................
- Solución comentada al Ejercicio 1.9.
- PRÁCTICA 2.
- Ejercicio 2.1: Varias formas de utilizar el bucle for.................................................................................................
- Solución comentada al Ejercicio 2.1.
- Ejercicio 2.2: Máximo elemento de un conjunto de números.
- Solución comentada al Ejercicio 2.2.
- Ejercicio 2.3: Mínimo valor algebraico de un conjunto de números enteros.
- Solución comentada del Ejercicio 2.3.
- Ejercicio 2.4: Ordenar un conjunto de números enteros.
- Solución comentada al Ejercicio 2.4.
- Ejercicio 2.5: Programa electoral, que no electoralista.
- Solución comentada al Ejercicio 2.5.
- Ejercicio 2.6: Producto de matriz por vector............................................................................................................
- Solución comentada al Ejercicio 2.6.
- Ejercicio 2.7: Producto de matrices
- Solución comentada del Ejercicio 2.7.
- Ejercicio 2.8: Un programa para un primo...............................................................................................................
- Solución comentada al Ejercicio 2.8.
- Ejercicio 2.9: Un programa para muchos primos.....................................................................................................
- Solución comentada del Ejercicio 2.9.
- PRACTICA 3.
- Ejercicio 3.1: El operador de división (/).
- Solución comentada al Ejercicio 3.1.
- Ejercicio 3.2: Un repaso a la función printf( )
- Solución comentada al Ejercicio 3.2.
- Ejercicio 3.3: Y seguimos con los bucles for.
- Solución comentada al Ejercicio 3.3.
- Ejercicio 3.4: Volvamos a ordenar sin olvidar el desorden inicial.
- Solución comentada del Ejercicio 3.4.
- Ejercicio 3.5: Cálculo del determinante de una matriz 3x3......................................................................................
- Solución comentada al Ejercicio 3.5.
- Ejercicio 3.6: El sultán y el estudiante.
- Solución comentada al Ejercicio 3.6.
- Ejercicio 3.7: Introducción a la Estadística.
- Solución comentada al Ejercicio 3.7.
- Ejercicio 3.8: Operación con vectores......................................................................................................................
- Solución comentada al Ejercicio 3.8.
- Ejercicio 3.9: Ejercicio de vectores planos.
- Solución comentada al Ejercicio 3.9.
- Ejercicio 3.10: Repaso de la tabla de multiplicar.
- Solución comentada al Ejercicio 3.10.
- PRÁCTICA 4.
- Ejercicio 4.1: Leer una palabra y escribirla al revés.
- Solución comentada del Ejercicio 4.1.
- Ejercicio 4.2: Leer una frase (línea) y escribirla al revés.
- Solución comentada del Ejercicio 4.2.
- Ejercicio 4.3: Transformar un texto.
- Solución comentada del Ejercicio 4.3.
- Ejercicio 4.4: Modificar el Ejercicio 4.3.
- Solución comentada del Ejercicio 4.4.
- Ejercicio 4.5: Ordenar alfabéticamente.
- Solución comentada al Ejercicio 4.5.
- Ejercicio 4.6: Modificar el Ejercicio 4.5.
- Solución comentada del Ejercicio 4.6.
- Ejercicio 4.7: Recuento de caracteres de un fichero.................................................................................................
- Solución comentada al Ejercicio 4.7.
- Ejercicio 4.8: Modificar el Ejercicio 4.7 para contar las palabras de un fichero......................................................
- Solución comentada del Ejercicio 4.8.
- Ejercicio 4.9: Un fichero secreto..............................................................................................................................
- Solución comentada al Ejercicio 4.9.
- Ejercicio 4.10: Crear funciones análogas a strlen(), strcpy(), strcat() y strcmp().......................................................
- Solución comentada del Ejercicio 4.10.
- PRÁCTICA 5.
- Ejercicio 5.1: Evaluación de la función exp(x) por desarrollo en serie....................................................................
- Solución comentada al Ejercicio 5.1.
- Ejercicio 5.2: Otra forma de terminar un bucle........................................................................................................
- Solución comentada al Ejercicio 5.2.
- Ejercicio 5.3: Desarrollo en serie de sen(x)
- Solución comentada al Ejercicio 5.3.
- Ejercicio 5.4: Máximo de un conjunto de tres números...........................................................................................
- Solución comentada del Ejercicio 5.4.
- Ejercicio 5.5: Potencias............................................................................................................................................
- Solución comentada del Ejercicio 5.5.
- Ejercicio 5.6: Una función que no tiene argumentos.
- Solución comentada al Ejercicio 5.6.
- Ejercicio 5.7: Modificar el Ejercicio 5.6.
- Solución comentada al Ejercicio 5.7.
- Ejercicio 5.8: Giro de una barra extensible.
- Solución comentada del Ejercicio 5.8.
- Ejercicio 5.9: Modificar el Ejercicio 5.8.
- Solución comentada del Ejercicio 5.9
- Ejercicio 5.10: Máximo de un conjunto de tres números...........................................................................................
- Solución comentada del Ejercicio 5.10.
- Ejercicio 5.11: Operaciones con vectores (Ejercicio 9 de la Práctica 3)
- Solución comentada al Ejercicio 5.11.
- Ejercicio 5.12: Una función que se llama a sí misma (función recursiva): n!............................................................
- Solución comentada al Ejercicio 5.12.
- Ejercicio 5.13: Otra función recursiva: la suma de los n primeros números enteros
- Solución comentada al Ejercicio 5.13.
- PRÁCTICA 6.
- Ejercicio 6.1: Norma sub-infinito de una matriz.
- Solución comentada del Ejercicio 6.1.
- Ejercicio 6.2: Función para crear una matriz con reserva dinámica de memoria.
- Solución comentada de los Ejercicios 6.1 y 6.2.................................................................................
- Ejercicio 6.3: Resolución de un sistema de ecuaciones lineales
- Solución comentada del Ejercicio 6.3.
- Ejercicio 6.4: Modifica el programa anterior.
- Solución comentada del Ejercicio 6.4.
- Ejercicio 6.5: Resolución de sistemas de ecuaciones lineales con pivotamiento por columnas...............................
- Solución comentada de los Ejercicios 6.4 y 6.5.................................................................................
- Ejercicio 6.6: Cálculo del determinante de una matriz nxn
- Solución comentada del Ejercicio 6.6.
- Ejercicio 6.7: Resolución de sistemas de ecuaciones lineales por el método iterativo de Gauss-Seidel..................
- Solución comentada del Ejercicio 6.7.
- Ejercicio 6.8: Direcciona un vector de 1 a n (y no de 0 a n-1 ).
- Solución comentada del Ejercicio 6.8.
- Ejercicio 6.9: Direcciona una matriz de 1 a n , y de 1 a m (y no de 0 a n-1 , y de 0 a m-1 ).
- Solución comentada del Ejercicio 6.9.
- PRÁCTICA 7.
- Ejercicio 7.1: Contar las vocales acentuadas de un fichero......................................................................................
- Solución comentada del Ejercicio 7.1.
- Ejercicio 7.2: Evaluación de una forma cuadrática.
- Solución comentada del Ejercicio 7.2.
- Ejercicio 7.3: Encontrar un número en una lista e insertarlo si no está en ella.
- Solución comentada del Ejercicio 7.3.
- Ejercicio 7.4: Trasponer una matriz rectangular
- Solución comentada del Ejercicio 7.4.
- Ejercicio 7.5: Intersección de una recta con una circunferencia.
- Solución comentada del Ejercicio 7.5.
- Ejercicio 7.6: Dar la vuelta a cada una de las palabras de un texto..........................................................................
- Ejercicio 7.7: Escribir las palabras de un texto en orden inverso.............................................................................
- Solución comentada del Ejercicio 7.7.
- antisimétrica....................................................................................................................................... Ejercicio 7.8: Descomposición de una matriz cuadrada cualquiera en suma de una matriz simétrica y otra
- Solución comentada del Ejercicio 7.8.
- Ejercicio 7.9: Calcular sen(x) por interpolación a partir de una tabla
- Solución comentada del Ejercicio 7.9.
- Práctica 8: EXAMEN FINAL........................................................................................................................................
- Ejercicio 8.1: Programa que realiza la misma función que el comando copy de MS-DOS
- Solución comentada del Ejercicio 8.1.
- Ejercicio 8.2: Centro de masas de un sistema de masas puntuales...........................................................................
- Solución comentada del Ejercicio 8.2.
- Ejercicio 8.3: Cálculo de una raíz de una función por el método de bisección
- Solución comentada del Ejercicio 8.3.
- Ejercicio 8.4: Girar 90º una matriz rectangular........................................................................................................
- Solución comentada del Ejercicio 8.4.
- Ejercicio 8.5: Cambiar la forma de de una matriz, manteniendo el orden (por filas) de sus elementos...................
- Solución comentada del Ejercicio 8.5.
- Ejercicio 8.6: Cálculo de una raíz de una función por el método de Newton
- Solución comentada del Ejercicio 8.6.
- Ejercicio 8.7: Integración numérica de una función.................................................................................................
- Solución comentada del Ejercicio 8.7.
- Ejercicio 8.8: Crear el comando more
- Solución comentada del Ejercicio 8.8.
- Ejercicio 8.9: Diferenciación numérica....................................................................................................................
- Solución comentada del Ejercicio 8.9.
- Ejercicio 8.10: Calculadora elemental interactiva......................................................................................................
- Solución comentada del Ejercicio 8.10.
- Ejercicio 8.11: Tabla de logaritmos con formatos adecuados por columnas..............................................................
- Solución comentada del Ejercicio 8.11.
- Ejercicio 8.12: Máximo valor y vector propio por iteración directa
- Solución comentada del Ejercicio 8.12.
PRACTICA 1.
EJERCICIO 1.1: EL PRIMER PROGRAMA.
Para que tu debut como programador en C sea todo un éxito, te hemos preparado un sencillo
programa de bienvenida. Tecléalo en un fichero al que puedes poner por nombre hola.c.
Solución comentada al Ejercicio 1.1.
/* fichero hola.c / / Este programa saluda desenfadadamente. */
#include <stdio.h> void main(void) { printf("Hola! Que tal estas, futuro programador?\n"); }
Comentario : La primera línea de este programa es un comentario , y es ignorado por el compilador. La directiva #include permite utilizar la librería stdio , indispensable para diferentes instrucciones de entrada/salida del lenguaje C. El fichero stdio.h contiene las declaraciones de las funciones de entrada/salida, así como definiciones de constantes simbólicas y algunas otras definiciones de utilidad. La palabra void es opcional; indica que la función main() no tiene valor de retorno ni argumentos.
EJERCICIO 1.2: UNA CONVERSACIÓN EN C.
Seguro que el programa del ejercicio anterior te ha dejado con ganas de responder a la pregunta que
aparece en la pantalla. Para ello es necesario utilizar la función scanf(). Esta función permite leer
tanto números como cadenas de caracteres, pero cuando encuentra blancos, tabuladores o espacios
en blanco, termina de leer. Crea el siguiente programa en un fichero llamado hola2.c.
Solución comentada al Ejercicio 1.2.
/* fichero hola2.c / / Este programa saluda más personalmente */
#include <stdio.h> void main(void) { char nombre[30]; printf("Hola! Como te llamas?\n"); scanf("%s", nombre); printf("Que tal estas, %s?\n", nombre); }
Comentario : La sentencia char nombre[30] , declara una variable llamada nombre que es una cadena de 30 caracteres (tipo char ). Estos caracteres se numeran del 0 al 29, y deben incluir la marca de fin de cadena '\0'. Con la función scanf() , se lee lo que será el contenido de dicha cadena por medio del formato %s , que es propio de las cadenas de caracteres. Como la lectura se detiene al encontrar un blanco, un carácter nueva línea o un tabulador, por medio de este programa no se puede leer una frase completa, sino sólo una palabra.
Observa que a la función scanf() hay que pasarle los argumentos por referencia. Como nombre es de por sí la dirección de nombre[0] no hace falta precederlo por el operador (&).
EJERCICIO 1.3: UNA PEQUEÑA OPERACIÓN ARITMÉTICA.
Estarás pensando que C ha de servir para algo más que mantener una aburrida conversación con tu
PC (¿verdadero y fiel amigo?). En el siguiente programa te presentamos un avance de las
"complicadas" operaciones que puede realizar el lenguaje C. Escribe el programa y sálvalo como
marathon.c.
Compila el programa y ejecútalo; apuntando el resultado. Después modifica el programa
sustituyendo 1760.0 por 1760 en la línea que calcula el número de kilómetros. Vuelve a compilar
y a ejecutar. ¿Sale lo mismo que antes? ¿Qué ha podido pasar?
Solución comentada al Ejercicio 1.3.
/* fichero marathon.c / / Un marathon tiene 26 millas y 385 yardas. / / Una milla tiene 1760 yardas. / / Calcula la distancia del marathon en kilómetros. */
#include <stdio.h> void main(void) { int millas, yardas; float kilometros;
millas=26; yardas=385; kilometros=1.609*(millas+yardas/1760.0); printf("\nUn marathon tiene %f kilometros.\n\n", kilometros); }
Comentario : En C las constantes que incluyen un punto decimal son de tipo double. La variable yardas es de tipo int. Si en el denominador se pone sólo 1760 , el resultado de yardas/1760 es entero y por tanto incorrecto. Basta poner 1760.0 para que yardas sea promovido a double y todas las operaciones aritméticas de esa sentencia se realicen con precision double.
EJERCICIO 1.4: PREGUNTAS INDISCRETAS.
En este programa vas a utilizar la función scanf() con distintos tipos de variables. De paso podrás
contestar a algunas preguntas indiscretas, pero de indudable interés estadístico y social. El siguiente
programa debe ser almacenado en un fichero llamado mascota.c.
Si tu mascota favorita es una boa, una ardilla o una gacela, tendrás que cambiar el artículo
"un" por "una", para respetar la concordancia.
Solución comentada al Ejercicio 1.4.
/* fichero mascota.c */
#include <stdio.h> void main(void) { int edad; float sueldo; char cachorro[30];
printf("Confiesa tu edad, sueldo y mascota favorita.\n"); scanf("%d %f",&edad, &sueldo); scanf("%s", cachorro); printf("%d %.0f pts. %s\n",edad, sueldo, cachorro); printf("Un %s!!", cachorro); printf(" Como te puede gustar un %s?\n", cachorro); }
Comentario : En la función scanf() , se incluye el operador dirección (&) delante de las variables escalares para pasar a la función las direcciones de dichas variables (paso de argumentos por referencia ). De esta forma la función scanf() puede depositar en las direcciones de memoria correctas los valores que lee desde teclado. Recordemos que para leer cadenas de caracteres basta poner el nombre de la cadena, que de por sí ya es una dirección.
EJERCICIO 1.7: M ODIFICA EL PROGRAMA SUMAI NT. C.
Se trata del programa que suma los cinco primeros enteros que se presentó en el Ejercicio 1.5. En
primer lugar se deberá editar este programa y salvarlo con el nombre sumaFor.c.
Se te pide que modifiques la copia ( sumaFor.c ) para que el programa realice lo mismo
(sumar los cinco primeros enteros), pero empleando un bucle for en lugar de un bucle while.
Solución comentada del Ejercicio 1.7.
/* fichero sumaFor.c */
#include <stdio.h> void main(void) { int i, suma=0;
for(i=0; i<=5; i++) suma+=i; printf("La suma de los cinco primeros numeros es: %d\n", suma); }
Comentario : En este fichero se ha utilizado la equivalencia directa entre los bucles for y while. Por lo demás, este programa no tiene nada de particular.
EJERCICIO 1.8: SOLUCIÓN DE LA ECUACIÓN DE SEGUNDO GRADO.
Dada la ecuación de segundo grado ax^2 + bx + c = 0 : se calcula el discriminante discr = b^2 − 4 ac.
Se pueden presentar tres casos distintos:
- Si discr >0.0 las dos raíces son reales y distintas, y valen:
1 2
b discr b discr
x x
a a
- Si discr = 0.0 las dos raíces son reales e iguales, y valen:
1 2
b
x x
a
- Finalmente, si discr<0.0 las dos raíces son complejas conjugadas. Las partes real e imaginaria
valen:
b discr
xr xi
a a
Teclea y compila el siguiente programa para resolver la ecuación de segundo grado. Llámalo
ecuacion2.c. Compila y ejecuta este programa cambiando los valores de a , b y c , de modo que se
prueben las tres opciones del programa.
Solución comentada al Ejercicio 1.8.
/* fichero ecuacion2.c / / resolución de la ecuación de segundo grado */
#include <stdio.h> #include <math.h> /* incluye decl. de la función sqrt() */ void main(void) { double a, b, c; double discr, x1, x2, xd, xr,xi;
printf("Escribe los valores de los coeficientes A, B y C\n");
scanf("%lf%lf%lf", &a, &b, &c);
discr=bb-4.0ac; if (discr>0.0) { x1=(-b+sqrt(discr))/(2.0a); x2=(-b-sqrt(discr))/(2.0a); printf("\nLas dos raices reales son: %12.6e y %12.6e \n", x1, x2); } else if (discr<0.0) { xr=-b/(2.0a); xi=sqrt(-discr)/(2.0a); printf("\nRaices complejas:\n"); printf("(%12.6e, %12.6ei) y (%12.6e, %12.6ei)\n", xr, xi, xr, -xi); } else { x1 = -b/(2.0a); printf("\nLas dos raices son iguales y valen: %12.6e \n", x1); } }
Comentario : Incluyendo la librería math.h se pueden usar las funciones matemáticas tales como sqrt() para la raíz cuadrada; cos() para calcular el coseno de un ángulo, etc. La instrucción if...else permite hacer una bifurcación , dependiendo de la cual se realizarán diferentes actividades.
Merece la pena observar la forma utilizada para partir en varias líneas las distintas llamadas a la función printf(). La idea fundamental es que, en el fichero _.c_* la cadena de control (lo que va entre comillas como primer argumento de la función printf() ) no se puede partir entre dos o más líneas
EJERCICIO 1.9: PARA EXPERTOS.
Realiza un programa en C que escriba una tabla de dos columnas para la conversión entre las
temperaturas en grados Fahrenheit −comprendidas entre 0 ºF y 300 ºF, según incrementos de 20 ºF−
y su equivalente en grados centígrados. Se realizarán dos versiones de este programa: una llamada
temp1.c que empleará un bucle while. La otra versión se llamará temp2.c y utilizará un bucle for.
La conversión entre grados Centígrados y grados Fahrenheit obedece a la fórmula:
5 * (ºF - 32)
ºC =
siendo ºC la temperatura en grados Centígrados y ºF en grados Fahrenheit.
Solución comentada al Ejercicio 1.9.
/* fichero temp1.c */
#include <stdio.h> void main(void) { double gradosFahr, gradosCent;
printf("grados Fahrenheit grados Centigrados\n"); printf("----------------- ------------------\n\n"); gradosFahr = 0.0; while (gradosFahr<=300.0) { gradosCent=(5*(gradosFahr-32.0))/9.0; printf("%17.2lf%17.2lf\n", gradosFahr, gradosCent); gradosFahr+=20.0; } }
/* fichero temp2.c */
#include <stdio.h>
PRÁCTICA 2.
EJERCICIO 2.1: VARIAS FORMAS DE UTILIZAR EL BUCLE FOR.
En el siguiente programa se muestran distintas formas de escribir un bucle for para sumar los
enteros del 1 al 5. Escribe el siguiente programa y guárdalo con el nombre sumaFor2.c. Compílalo,
ejecútalo y observa los resultados. ¿Ves algo raro?
Solución comentada al Ejercicio 2.1.
/* fichero sumaFor2.c / / Programa para sumar los enteros del 1 al 5 */
#include <stdio.h> void main(void) { int i=1, suma=0;
for ( ; i<=5 ; ) { /* primera forma */ suma += i; ++i; } printf("suma 1 = %d\n", suma);
suma=0; /* segunda forma */ for (i=1; i<=5; ++i) suma+=i; printf("suma 2 = %d\n", suma);
for(i=1, suma=0; i<=5 ; ++i, suma+=i) /* tercera forma */ ; printf("suma 3 = %d\n", suma);
for(i=1, suma=0; i<=5 ; suma+=i, ++i) /* cuarta forma */ ; printf("suma 4 = %d\n", suma); }
Comentario : Para definir un bucle hace falta un contador o variable de control (que casi siempre es un entero y suele nombrarse con las letras típicas de subíndices: i, j, k, ...). Esta variable de control es la que se chequea cada vez que comienza el bucle y la que permite continuar o no realizando las operaciones de dentro del bucle.
Por otra parte, en C, el bucle for tiene tres componentes separadas por puntos y comas: la primera es una inicialización de la variable de control (u otras que pudieran afectar al bucle), la segunda es la sentencia de chequeo de la variable de control que siempre es necesaria (véase la primera forma); por último, la tercera son sentencias de actualización que se ejecutan al final del bucle (que también se podrían poner entre las llaves del bucle, detrás de las demás sentencias). Conociendo estas características, la forma más habitual de expresar un bucle es la segunda, ya que el bucle for contiene las instrucciones pertinentes a la variable de control.
La forma primera es más asimilable a un bucle while , ya que la instrucción for contiene sólo el chequeo de la variable.
La diferencia entre las formas tercera y cuarta es el orden en que se ejecutan las instrucciones: la forma tercera ejecuta antes el incremento de la variable que el chequeo y la suma, por tanto cuando i vale 6 ya se ha sumado a la variable suma y, por eso el resultado sale 20 en lugar de 15.
EJERCICIO 2.2: M ÁXIMO ELEMENTO DE UN CONJUNTO DE NÚMEROS.
Este programa calcula el máximo entre un conjunto de números enteros. Para ello se sigue el
siguiente algoritmo: se crea una variable llamada max , a la que se da inicialmente el valor de
conjunto[0]. Luego se recorren paso a paso todos los elementos del vector, comparando el valor
almacenado en la posición considerada del vector con el valor de la variable max. Si el valor de la
posición considerada del vector es mayor que max , entonces se copia (se sustituye el valor) en la
variable max este valor. De esta forma, una vez recorrido todo el vector, la variable max contendrá
el máximo valor. Guarda este programa con el nombre maximo.c.
Solución comentada al Ejercicio 2.2.
/* fichero maximo.c / / Programa para calcular el máximo de un conjunto de números */
#include <stdio.h> #define SIZE 5 void main(void) { int i, max, imax; int conjunto[SIZE];
printf("Introduce %d valores:\n", SIZE);
for (i=0; i<SIZE; i++) { printf("%d: ", i+1); scanf("%d", &conjunto[i] ); printf("\n"); }
max=conjunto[0]; imax=0; for (i=0; i<SIZE; i++) { if (conjunto[i]>max) { max=conjunto[i]; imax=i; } }
printf("\nEl maximo valor del conjunto es: %d.\n", max); printf("\ny esta en la posicion %d.\n", imax+1); }
Comentario : Este programa es muy sencillo, si se entiende el algoritmo. La variable max acabará siendo igual al elemento mayor del conjunto, e imax indicará la posición del máximo.
EJERCICIO 2.3: M ÍNIMO VALOR ALGEBRAICO DE UN CONJUNTO DE NÚMEROS ENTEROS.
Modifica el programa anterior maximo.c , de forma que calcule el mínimo valor del conjunto.
Guárdalo con el nombre minimo.c.
Solución comentada del Ejercicio 2.3.
/*fichero minimo.c */
#include <stdio.h> #define SIZE 5 void main(void) { int i, min, imin; int conjunto[SIZE];
printf("Introduce %d valores:\n", SIZE);
for (i=0; i<SIZE; i++) { printf("%d: ", i+1); scanf("%d", &conjunto[i] ); printf("\n"); } min=conjunto[0]; imin=0;
i = 2 {1 3 7 5 4}
j = 3 {1 3 5 7 4} Se intercambia 5 con 7
j = 4 {1 3 4 7 5 } Se intercambia 4 con 5
i = 3 {1 3 4 7 5}
j = 4 { 1 3 4 5 7} Se intercambia 5 con 7 ¡Números ordenados!
Ya se ve que no es necesario que el bucle i llegue hasta el valor 4.
Solución comentada al Ejercicio 2.4.
/* fichero ordena.c/ / Programa para ordenar un conjunto de números enteros*/
#include <stdio.h> #define SIZE 7 void main(void) { int vector[SIZE]; int j, i, temp;
printf("Introduce los %d valores para ordenar:\n", SIZE); for(i=0; i<SIZE; i++) { printf("%d: ", i+1); scanf("%d", &vector[i]); printf("\n"); } /* se aplica el algoritmo de la burbuja */ for(i=0; i<(SIZE-1); i++) { for (j=i+1; j<SIZE; j++) { if(vector[j]<vector[i]) { temp=vector[j]; vector[j]=vector[i]; vector[i]=temp; } } } printf("El vector ordenado es:\n"); for(i=0; i<SIZE ; i++) { printf("%d ", vector[i]); } printf("\n"); }
Comentario : Para intercambiar entre sí los valores de dos variables no se pueden emplear las dos instrucciones siguientes: vector[j]=vector[i]; /* esta instrucción pone en la posición j el valor de la posición i, perdiéndose el valor de la posición j / vector[i]=vector[j]; / esta instrucción pone en la posición i el valor de la posición j, pero no el original, que se ha perdido, sino el nuevo */
Por eso es necesaria una variable intermedia, que en este caso hemos llamado temp , que guarda temporalmente el valor de la posición j. Por esto se requieren tres instrucciones.
EJERCICIO 2.5: PROGRAMA ELECTORAL , QUE NO ELECTORALISTA.
Aprovechando las muy recientes elecciones al Parlamento Vasco, vamos a ver cómo se convierten
en escaños los votos de los sufridos ciudadanos siguiendo el método d’Hont. ¿Estás familiarizado
con este método? Por si acaso te lo vamos a recordar.
Supongamos que concurren 3 partidos a las elecciones y que la provincia o distrito electoral
dispone de 2 escaños. El primer escaño se lo llevará el partido más votado. Para el segundo escaño
se dividen los votos de cada partido entre el número de escaños obtenidos más uno (el partido que
no tenga todavía ningún escaño se dividirá entre 1) y se calculan los restos de dichas divisiones. El
escaño se asigna al partido que tras esta operación tenga un resto más elevado. Vamos a verlo con
un ejemplo:
Partido 1 : 6000 (Se lleva el escaño 1) → restos → 6000/(1+1) = 3000
Partido 2 : 4000 → restos → 4000/(1+0) = 4000 → Se lleva el escaño 2.
Partido 3 : 2000 → restos → 2000/(1+0) = 2000
El programa que te presentamos a continuación es para 3 partidos y 2 escaños, pero queda a tu
entera disposición para que lo particularices −si dispones de datos− para el caso de las recientes
elecciones. Ten mucho cuidado porque un fallo en la programación puede hacer caer sobre ti una
acusación de fraude electoral. Llamaremos al programa elecciones.c.
Lo primero que hace este programa es inicializar a cero el vector nEsca [ ]. En este vector se
va a almacenar el número de escaños de cada partido: nEsca [ 0 ] contendrá el número de escaños del
partido número 1, nEsca [ 1 ] los escaños del partido número 2, etc. Este vector se va a ir
modificando a lo largo de la ejecución del programa.
A continuación se almacenan en el vector nVotos [ ] los números de votos obtenidos por cada
partido, estos datos serán introducidos por el usuario a través del teclado.
La novedad de este programa es que incluye una función: nextEsc(long *, int *). Esta
función tiene como argumentos dos punteros a sendos vectores, es decir, las direcciones de
memoria o los nombres de dos vectores. Cuando se llama a la función, nextEsc(nVotos, nEsca) se
pasa la dirección de memoria de los vectores nEsca [ ] y nVotos [ ]. El nombre de un vector (como
por ejemplo nEsca ) es un puntero a la dirección del primer elemento. La función devuelve el
número del partido que ha conseguido el escaño y se almacena en la variable esca. Este número será
cero si el escaño corresponde al primer partido, 1 si corresponde al segundo, etc.
Con esta pequeña explicación ya estás en condiciones de escribir el programa y comprobar
cómo funciona.
Solución comentada al Ejercicio 2.5.
/* fichero elecciones.c/ / Calculo de escaños por partido (d'Hondt). */
#include <stdio.h> #define NESC 2 /* número de escaños en liza. / #define NPAR 3 / número de partidos que concurren / void main(void) { int i, esca; int nEsca[NPAR]; / nEsca{[NPAR]= nº de escaños por partido/ long nVotos[NPAR]; / nVotos[NPAR]=nº de votos por partido*/ int nextEsc(long *, int ); / declaración de función */
for(i=0; i<NPAR; ++i) nEsca[i]=0;
printf("Teclea el numero de votos de cada partido.\n"); for (i=0; i<NPAR; ++i) { printf("\nPartido %d: ", i+1); scanf("%ld", &nVotos[i]); }
for(i=0; i<NESC; ++i) { /* asignación de escaños */ esca = nextEsc(nVotos, nEsca); nEsca[esca] = nEsca[esca]+1; }
solucion[i]=sum; } printf("\nEl vector solucion es:\n"); for(i=0; i<SIZE; i++) { printf("Elemento %d = %lf\n", i+1, solucion[i]); } }
Comentario : Se presentan en este programa algunos pasos típicos de manejo de matrices que son muy similares en todos los lenguajes de programación.
En cuanto al algoritmo , es ya conocida la forma de multiplicar una matriz por un vector columna: cada elemento del vector producto es el producto escalar (la suma de los productos elemento a elemento) de la fila correspondiente de la matriz por el vector columna. Para ello hacen falta dos bucles: uno recorre las filas de la matriz y el otro realiza el sumatorio propio del producto escalar. Observa que, para realizar el sumatorio, se inicializa cada vez la variable sum a cero.
EJERCICIO 2.7: PRODUCTO DE MATRICES.
Basándote en el producto de matriz por vector anterior, haz un programa que multiplique dos
matrices cuadradas y llámalo bimatriz.c. Si no quieres perder el tiempo introduciendo datos con el
teclado, también puedes asignar desde el programa unos valores arbitrarios a las matrices factores.
Solución comentada del Ejercicio 2.7.
/* fichero bimatriz.c */
#include <stdio.h> #define SIZE 5 void main(void) { double matriz1[SIZE][SIZE], matriz2[SIZE][SIZE]; double solucion[SIZE][SIZE], sum; int dimension, i, j, k;
printf("Introduce la dimension de las matrices:\n"); printf("Dimension: "); scanf("%d", &dimension);
printf("Introduce los elementos de la primera matriz:\n"); for (i=0; i<dimension; i++) { for (j=0; j<dimension; j++) { printf("a(%d,%d): ", i+1, j+1); scanf("%lf", &matriz1[i][j] ); } } printf("\n");
printf("Introduce los elementos de la segunda matriz:\n"); for (i=0; i<dimension; i++) { for (j=0; j<dimension; j++) { printf("b(%d,%d): ", i+1, j+1); scanf("%lf", &matriz2[i][j] ); } } printf("\n");
for (i=0; i<dimension; i++) { for (j=0; j<dimension ; j++) { sum=0.0; for (k=0; k<dimension; k++) sum+=matriz1[i][k]*matriz2[k][j]; solucion[i][j]=sum; } }
printf("Solucion:\n\n\n");
for (i=0; i<dimension; i++) { for (j=0; j<dimension; j++) printf("%5.2lf ", solucion[i][j]); printf("\n"); } }
Comentario : Tal vez el aspecto más interesante de este programa es la necesidad de utilizar 3 bulces for para la multiplicación de dos matrices. Para verlo más claramente, sea a (^) ij un elemento de la primera matriz, bij un elemento de la segunda y c (^) ij un elemento de la matriz solución. Pensemos por un momento cómo se obtiene un elemento cualquiera de la matriz solución. El elemento c 23 , por ejemplo, se obtiene multiplicando los elementos de la fila 2 de la primera matriz, por los elementos de la columna 3 de la segunda matriz. Suponiendo que las matrices son de dimensión 3 tendremos:
c 23 = a 21 b 13 +a 22 b 23 +a 23 b 33 y en general: c (^) ij = a (^) i1b (^) 1j +a (^) i2b (^) 2j +a (^) i3b (^) 3j
Por lo tanto, para poder acceder a los elementos de la fila i de la primera matriz y a los elementos de la columna j de la segunda matriz, y para realizar el sumatorio son necesarios tres bucles, para los que se han utilizado las variables i , j y k.
EJERCICIO 2.8: UN PROGRAMA PARA UN PRIMO.
El siguiente programa comprueba si un número es primo o no. Recuerda que un número primo es
aquél que puede dividirse únicamente por sí mismo y por la unidad. Una manera de decidir si un
número es primo o no, es dividirlo por todos los números comprendidos entre el 1 y su raíz
cuadrada. Si se encuentra que el número es divisible por alguno de ellos, se deduce que ese número
no es primo. Vamos a utilizar el operador módulo o resto de la división entera (%) para comprobar
si la división es exacta. Este operador da como resultado el resto de la división del primer operando
por el segundo. Por ejemplo, 5%2 es 1, puesto que el resto de dividir 5 entre 2 es 1.
Guarda el programa con el nombre primos.c.
Solución comentada al Ejercicio 2.8.
/* fichero primos.c / / programa para determinar si un número es primo */
#include <stdio.h> #include <math.h>
void main(void) { int numero, divisor;
printf("Que numero quieres saber si es primo?\n"); scanf("%d", &numero); while(numero<2) { printf("Lo siento, no acepto numeros menores que 2.\n"); printf("Intentalo de nuevo\n"); scanf("%d", &numero); } for (divisor=2; divisor<=sqrt(numero); divisor++) { if (numero%divisor==0) { printf("%d no es primo.\n", numero); return; } } printf("%d es primo.\n", numero); }
Comentario : El comentario más apropiado para este ejercicio es el algoritmo para calcular el primo con el bucle for (divisor=2; divisor<=sqrt(numero); divisor++). Observa que este bucle se termina cuando se encuentra un divisor del número, en cuyo caso se escribe el mensaje de que el número no es primo y se termina la ejecución del programa con un return , o cuando divisor llega a su valor límite, en cuyo caso el número es primo porque no se ha encontrado ningún divisor.