Lenguaje C
Estructuras de Control Repetitivo
Una estructura de control repetitivo es una instrucción compleja compuesta por:
Un condición de repetición
Un bloque o instrucción que se repite de acuerdo a la condición.
Diagrama ejemplo:
inicio de repetición
bloque o instrucción
preparación para repetir
condición de repetición
Estas 4 componentes SIEMPRE están presentes en un proceso repetitivo, -aunqe muchas veces parecen omitirse. Pueden cambiar de
posición en el programa; lo cual genera 3 tipos de estructuras de control repetitivo.
1) Repetición Do While
Ejecuta un bloqueInstruccion y verifica un condición de repetición de ejecución
Diagrama de flujo
Sintaxis:
do bloqueInstruccion while(condicion);
// 03_01a.c : Escribir un programa que lea un número n y valide (verifique) que su valor esté entre 1 y 4
#include<stdio.h>
void main(void){
int n;
do {
printf("Escriba un número entero entre 0 y 4: ");
scanf("%d", &n); // ingrese 6 y 3
} while (n < 0 || n > 4);
printf("Número: %dn", n);
}
Salida:
Escriba un número entero entre 0 y 4: 6 // Repite porque no cumple con la restricción
Escriba un número entero entre 0 y 4: 3
Número: 3
2) Repetición While
Verifica un condición, si es verdad ejecuta una bloqueInstruccion y vuelve a verificar la condición.
Sintaxis
while (condición) bloqueInstruccion
PÁGINA: 1
Lenguaje C
Diagrama de flujo
Repetir el programa anterior: leer un número n y validar (verificar) que su valor esté entre 1 y 4
// 03_01a.c : do bloqueInstruccion while(condicion) // 03_01b.c : while (condición) bloqueInstruccion
#include<stdio.h>
void main(void){
int n;
do {
int n = -1;
while (n < 0 || n > 4) {
printf("Escriba un número entero entre 0 y 4: ");
scanf("%d", &n); // ingrese 6 y 3
} while (n < 0 || n > 4); }
printf("Número: %dn", n);
}
Salida:
Escriba un número entero entre 0 y 4: 6 // Repite porque no cumple con la restricción
Escriba un número entero entre 0 y 4: 3
Número: 3
3) Repetición For
Ejecuta varias operaciones, su diagrama de flujo es:
(1)
(2)
(4) (3a) (3b)
Sintaxis:
for([inicios]; [instrucciones, condición]; [variaciones]) bloqueInstruccion
Flujo de ejecución del for: Observe el flujo de ejecución en el diagrama (1), (2), (3a ó 3b) y (4); en la sintaxis se apreciaría así:
for( (1)inicios; (2)instrucciones, condición; (4) variaciones) {
(3a) // viene, si condición es verdad
….
… sigue a (4)
}
(3b) // viene, si condición es falsa
PÁGINA: 2
Lenguaje C
Ejemplo:
for(i=0; i < 3; i++) printf("%d: %dn", i, i*i);
Salida:
0: 0
1: 1
2: 4
Ejemplo:
int i, j, k = 0;
for(i=0, j =2; k++, i < 3; i++, j--) printf("i: %d, j: %d, k: %dn", i, j, k);
Salida:
i: 0, j: 2, k: 1
i: 1, j: 1, k: 2
i: 2, j: 0, k: 3
Descripción:
Parámetro Descripción Ejemplo
Inicios 0 ó más instrucciones de inicio, separadas por comas.
Si no hay instrucciones, no se ejecuta nada.
i = 0, j = 2
Instrucciones
Condición
0 ó más instrucciones, separadas por comas.
Si no hay instrucciones, no se ejecuta nada
0 ó 1 condición
Si no hay condición, se evalúa a Verdad
K++,
i < 3
Variaciones 0 ó más instrucciones de variación, separadas por
comas
Si no hay instrucciones, no se ejecuta nada.
I++, j--
bloqueInstrccion 1 ó más instrucciones
Si no hay instrucciones, no se ejecuta nada.
printf("i: %d, j: %d, k: %dn", i, j, k)
// 03_02.c : Elevar al cuadrado los primeros 5 enteros
#include<stdio.h>
void main(void){
int n;
printf("Numero Cuadrado");
for(n = 0; n < 3; n++) // inicios: n = 0, condición: n < 3, variaciones: n++
printf("n%dt%d", n, n*n);
printf("n");
}
Salida:
Número Cuadrado
0 0
1 1
2 4
Ejemplo:
#include<stdio.h>
void main(void){
for( ; ; ) ;
}
Salida: No hace nada y no acaba nunca (se queda colgado); para matarlo: ctrl+c.
Este ejemplo que solo hace perder el tiempo, sirve para recordarnos que:
1) Si no hay inicios : No se hace nada.
2) Si no hay condición : Se evalua a verdad.
3) Si no hay variaciones: No se hace nada.
4) La instrucción ; : No hace nada.
Salir del loop: Normalmente se acaba la iteración cuando la condición es falsa; pero se puede salir antes, utilizando la instrucción
break; // que salta al final del bloque
Ejemplo:
#include<stdio.h>
void main(void){
for( ; ; ) break;
}
PÁGINA: 3
Lenguaje C
salida: No hace nada , pero no se queda colgado, termina de inmediato.
Anidamiento: Se pueden anidar varias estructuras: de repetición, de decisión, combinadas, en uno o más niveles.
Ejemplo: Este ejemplo ya fue presentado en los dos capítulos anteriores, ahora lo modificaremos para presentar más opciones.
Escriba un programa que lea dos enteros m y n , luego presente el menú:
Operación que requiere:
1) Sumar: m + n
2) Restar: m – n
3) Multiplicar: m * n
4) Dividir: m/n // Atento a la división entre 0
5) Salir:
Elija la operación: _
Indicaciones:
Valide que la operación esté entre 1 y 5. // Sugerencia: Use do.
Ejecute la operación seleccionada. // Sugerencia: Use switch.
Presente nuevamente el menú hasta que operación = 5, lo cual termina el programa. // Sugerencia: Use do.
// 03_03.c : Leer dos números, presentar un menú de operaciones, ejecutarlas repetidamente y salir finalmente.
#include<stdio.h>
void main(void){
int m, n, op;
printf("Ingrese un entero m = "); scanf("%d",&m);
printf("Ingrese un entero n = "); scanf("%d",&n);
do { // presentar el menú si n !=5
printf("nOperación que requiere:n");
printf("1) Sumar: m + nn");
printf("2) Restar: m – nn");
printf("3) Multiplicar: m * nn");
printf("4) Dividir: m/nn");
printf("5) Salir:n");
do {
printf("Elija su opción: "); scanf("%d",&op);
} while (op<1 || op > 5); // Valida la opción entre 1 y 5
switch(op){ // Ejecuta la operación seleccionada
case 1: printf("suma = %dn", m+n); break;
case 2: printf("Resta = %dn", m-n); break;
case 3: printf("Multiplicación = %dn", m*n); break;
case 4: if(n!=0) printf("División = %.2fn", (float)m/n);
else printf("Divisor es 0n"); break;
default: printf("Gracias por su visitan");
}
} while(op!=5);
}
Salida:
PÁGINA: 4
Lenguaje C
Matriz de prueba:
Caso Entradas Salida Chequeo
m n opción
1 3 2 1 5 √
2 3 2 2 1 √
3 3 2 3 6 √
4 3 2 4 1.50 √
5 3 0 4 Divisor 0 √
6 7 Solicita opción √
7 5 Sale del programa √
Un nuevo algoritmo: Para resolver ciertos problemas difíciles, conocemos algoritmos fáciles de calcular, por ejemplo para hallar el
máximo común divisor de dos números m y n = MCD(m, n), conocemos tres algoritmos clásicos:
a) El método de Euclides
b) El que nos enseñaron en la escuela: Producto de (factores primos de m y n comunes de menor potencia):
c) Aplicar la fórmula m*n = MCD(m, n) * MCM(m, n); si conocemos el MCM(m, n)
d) Podemos disponer de un nuevo algoritmo que utiliza el poder de cálculo del computador; por ejemplo para hallar el MCD(m, n)
podemos aplicar la definición literalmente, cosa que no hacíamos antes porqué era muy pesado calcular. El algoritmo aplica la
definición en modo literal y es muy fácil ya que aplica la definición literal:
a. mn = mínimo(m,n);
b. MCD = 1;
c. for(i = 2; i <= mn; i++) MCD = (m%i==0 && n%i==0)? i:MCD;
// (m%i==0 && n%i==0) quiere decir que i es común divisor de m y n
Este mismo caso se presenta si queremos saber si un número es, o no, primo; aplicamos la definición literal y la calculamos
con el computador. No siempre es posible aplicar este método: ya sea porqué los algoritmos requieren mucho calculo, aún
para una computadora o no tienen solución.
Resumen de las iteraciones: Hemos estudiado tres tipos de iteración, ¿cuál elegir?, Vamos a compararlos (hacer un
benchmark):
Sintaxis
for([inicios]; [instrucciones, condición];
[variaciones]) bloqueInstruccion
do bloqueInstruccion while(condición); while (condición) bloqueInstruccion
Si fuera necesario abandonar un bloque, puede usar break; y saltará al final de la estructura.
Esquema de programación
do {...} while(...); y while(…) {….}
No tienen inicios (se colocan al inicio)
No tienen variaciones (se colocan dentro).
for([inicios]; [condición]; [variaciones]) {
ejecutarTarea;
}
Inicios;
do {
ejecutarTarea;
variaciones;
} while(condición);
Inicios;
while(condición) {
ejecutarTarea;
variaciones;
};
PÁGINA: 5
Lenguaje C
// 03_04.c : Leer un número entero > 0 y determine si es primo o no. Desarrolle las 3 alternativas usando bucles.
#include<stdio.h>
void main(void){
int n, i=2, primo=1;
printf("Ingrese un entero > 0: ");
scanf("%d", &n);
for(;i<n && i*i <= n && primo ; i++)
if(n%i==0) primo=0;
if(n>2) do if(n%i++==0) primo=0;
while(i<n && i*i <= n && primo);
while(i<n && i*i <= n && primo)
if(n%i++==0) primo=0;
if(primo) printf("%d es primon", n);
else printf("%d no es primon", n);
}
¿Qué alternativa le gusta, y por qué?
No solo es cuestión de forma y gusto, el problema específico determina cuál de las estructuras es la más adecuada para su
programación. Las 3 estructuras requieren los mismos componentes: inicio, variaciones, condición y bloque de repetición; la diferencia
está en el orden en que se dan, un criterio puede ser:
Elija for() si tiene claramente definidos el inicio y el fin.
Caso contrario:
Elija do {...} while(...) si el condición va mejor al final
Caso contrario: Elija while (condición) { … }.
03_05.c : Leer y sumar números. Desarrolle las 3 alternativas usando bucles.
Lea n > 0, lea y sume n datos Lea y sume datos positivos, termine si un dato es negativo.
#include<stdio.h>
void main(void){
int i, n, dato, suma = 0;
printf("Ingrese el número de datos: ");
scanf("%d", &n);
for (i=1; i <= n; i++) {
printf("Ingrese dato: ");
scanf("%d", &dato);
suma += dato;
}
int dato = 0, suma = 0;
do {
suma += dato;
printf("Ingrese dato: ");
scanf("%d", &dato);
} while (dato > 0);
int dato, suma = 0;
printf("Ingrese dato: ");
scanf("%d", &dato);
while (dato > 0){
suma += dato;
printf("Ingrese dato: ");
scanf("%d", &dato);
}
printf("la suma es: %dn", suma);
}
Ejemplo: Una estudiante de C tiene insomnio, un colega decide ayudarla y le escribe un programa bien cuchi (así se dice en mi tierra)
escrito en C: zz.c, el cual muestra en el monitor:
3 ovejitas
6 conejitos
9 ovejitas
…
96 conejitos
99 ovejitas
96 conejitos
….
3 ovejitas
zzz zzz ….C que te quito el sueño, C que te hago soñar despierta y, C hacerte dormir: Linda noche para la más linda.
Sugerencias:
1) Use do{ .. } while( … );
2) Fíjese que se escriben conejitos para los números pares, y ovejitas para los impares
Nota: El programa será corto, robusto (correcto, flexible), ingenioso, a esto se le llama sexi en el argot de computación.
PÁGINA: 6
Lenguaje C
// Conejitos - ovejitas
// 03_06a.c : Usa do{ … } while(condicion); // 03_06b.c : Usa for
#include<stdio.h>
void main(void){
int n = 3, salto = 3; // Inicios
do{
int n, salto;
for(n = 3, salto = 3; n>0; n += salto, salto = (n==99)? -3:salto) {
if(n%2==0) printf("n%d conejitos", n); // ejecución
else printf("n%d ovejitas", n);
n += salto; // Variaciones
if(n==99) salto = -3; // variaciones
} while(n>0); // condición }
printf("nzzz zzz ….C que te quito el sueño, C que te hago soñar despierta y, C hacerte dormir: Linda noche para la más
linda.n");
}
Salida: Se muestra lo prometido
Esperemos que se duerma la chica y que el chico haya aprendido a usar las instrucciones do y for
Pasos para desarrollar un programa
Un programa se puede desarrollar en 4 pasos, veámoslo con un ejemplo concreto: Graficar en el monitor.
1) Solicitud del usuario: Definición del entregable incluyendo la matriz de pruebas, la cual es parte de las condiciones de aceptación.
Entregable: programa en C: Dado un entero n >=0, grafique un rombo relleno, con diagonales 2n+1.
Matriz de Prueba:
Caso Entrada: n Salida Chequeo
1 0 *
2 1 *
* * *
*
3 2 *
* * *
* * * * *
* * *
*
2) Algoritmo de solución: algoritmo matemático, pseudo-código.
Este no es un problema sencillo de programar y requiere del apoyo de nuestros conocimientos de matemáticas. Hay dos alternativas
para la solución.
Nota: En matemáticas identificamos a los ejes de coordenadas con X y Y; en computación, para números enteros solemos identificar
las filas con i (eje Y) y las columnas con j (eje X).
Alternativa
Algoritmo
matemático
Poner el eje de coordenadas en el centro del rombo,
graficar en el primer cuadrante:
La linea de borde del rombo cumple la ecuación:
i = -j +n
Todos los * del primer cuadrante cumplen:
i + j <= n
Otros cuadrantes: Aplicar simetrías con los dos ejes
Poner el eje de coordenadas a la izquierda, graficar la
parte superior:
Para cada fila i:
Calcular el número de blancos nb e imprimirlos.
Calcular el número de * na e imprimirlos.
nb = i
na = 2(n-i) -1
Parte inferior: Aplicar simetría con el eje horizontal
Pseudocódigo Primer Cuadrante:
Variar i: n → 0 // eje vertical
Variar j: 0 → n // eje horizontal
Si i + j <= n imprimir *, sino imprimir blanco
Parte superior:
Variar i: n → 0 // eje vertical
nb = n-i; imprimir
na = 2(n-i); imprimir
PÁGINA: 7
Lenguaje C
Otros cuadrantes:
Variar i: n → -n // eje vertical
Variar j: -n → n // eje horizontal
ai = abs(i); aj = abs(j) // valores absolutos
Si ai + aj <= n imprimir *, sino imprimir blanco
Parte inferior:
Variar i: n → -n // eje vertical
ai = abs(i) // valor absoluto
nb = ai; imprimir
na = 2(n-ai) -1; imprimir
Se elije la posición de los ejes que más facilite el algoritmo.
3) Programación: diseño, desarrollo, validación contra la matiz de pruebas.
// 03_07a.c: Ejes en el centro del rombo // 03_07b.c: Ejes a la izquierda del rombo
// primer cuadrante, para probar
#include<stdio.h>
void main(void){
int n, i, j;
printf("Ingrese un entero >= 0: ");
scanf("%d", &n);
for(i=n; i>=0; i--){
for(j=0; j<=n; j++)
if(i+j<=n) printf (" *");
else printf (" ");
printf("n");
}
}
// parte superior, para probar
#include<stdio.h>
void main(void){
int n, i, j, nb, na;
printf("Ingrese un entero >= 0: ");
scanf("%d", &n);
for(i=n; i>=0; i--){
nb = i;
for(j=0; j<= nb; j++) printf (" ");
na = 2*(n-i);
for(j=0; j<= na; j++) printf (" *");
printf("n");
}
}
// solución completa: simetría en los dos ejes
#include<stdio.h>
#include<math.h> // compile con: -lm
void main(void){
int n, i, j, ai, aj;
printf("Ingrese un entero >= 0: ");
scanf("%d", &n);
for(i=n; i>=-n; i--){
ai = fabs(i);
for(j=-n; j<=n; j++){
aj = fabs(j);
if(ai+aj<=n) printf (" *");
else printf (" ");
}
printf("n");
}
}
// solución completa: simetría con eje horizontal
#include<stdio.h>
#include<math.h> // compile con: -lm
void main(void){
int n, i, j, nb, na;
printf("Ingrese un entero >= 0: ");
scanf("%d", &n);
for(i=n; i>=-n; i--){
nb = fabs(i);
for(j=0; j<= nb; j++) printf (" ");
na = 2*(n-nb);
for(j=0; j<= na; j++) printf (" *");
printf("n");
}
}
Salida: Se grafica el rombo
4) Prueba y entrega al usuario: Chequear la matriz de pruebas, repetir el chequeo de la matriz de prueba con el usuario y entregar.
PÁGINA: 8
Lenguaje C
Ejemplo: Pida ingresar un entero impar n > 3, ejemplo: n = 7 y dibuje la siguiente figura con "*":
* * * * * * *
* * * *
* * * *
* * *
* * * *
* * * *
* * * * * * *
Análisis: Hay * en las diagonales y en los extremos: ¿dónde conviene poner el eje de coordenadas? Hay varias alternativas:
// 03_08a.c: Ejes en el centro del rombo
// Variaciones: n/2 >= i >= - n/2; -n/2 <= j <= n/2
// 03_08b.c: Ejes arriba a la izquierda
// Variaciones: 1<= i <= n; 1<= j <= n:
#include<stdio.h>
void main(void){
int n, i, j;
printf("Tamaño del arreglo: "); scanf("%d", &n); // Ingrese = 7
int ai, aj;
n /=2;
for(i=n; i>=-n; i--){
ai =(i>0)? i:-i; // valor absoluto de i
for(j=-n; j<=n; j++){
aj =(j>0)? j:-j;
if(ai==n || aj==n || ai == aj) printf("* ");
else printf(" ");
}
for(i=1; i<= n; i++){
for(j=1; j<= n; j++)
if(i==1 || i==n || j==1 || j==n || i==j || i == n-j+1) printf("* ");
else printf(" ");
printf("n");
}
}
Ejercicios:
Escriba, compile y ejecute programas que hagan lo siguiente:
1) Lea un número entero n, calcule el factorial de n! = 1*2*3..*n utilizando do … while y muestre n y n!
2) Lea un número entero n y calcule la suma sn de los n primeros números: sn = 1 + 2 + … + n, y muestre n y sn, de dos modos:
a) sn = n*(n+1)/2
b) utilizando while () {….}
3) Lea un número entero n y determine si es ó no primo, Hágalo de 3 formas distintas. Imprima:
n es primo
n no es primo
4) Lea dos números enteros m y n positivos, encuentre el máximo común divisor MCD e imprima, utilice el método de aplicar la
definición literal sugerido antes.
5) Lea dos números enteros m y n positivos, encuentre el máximo común divisor MCD y el mínimo común múltiplo MCM e
imprímalos.
6) Que hace el siguiente programa:
…
int i, j;
for(i=0, j=20; i < 10; i++, j--) printf("ni= %d; j = %d", i, j);
PÁGINA: 9

03 iteracion

  • 1.
    Lenguaje C Estructuras deControl Repetitivo Una estructura de control repetitivo es una instrucción compleja compuesta por: Un condición de repetición Un bloque o instrucción que se repite de acuerdo a la condición. Diagrama ejemplo: inicio de repetición bloque o instrucción preparación para repetir condición de repetición Estas 4 componentes SIEMPRE están presentes en un proceso repetitivo, -aunqe muchas veces parecen omitirse. Pueden cambiar de posición en el programa; lo cual genera 3 tipos de estructuras de control repetitivo. 1) Repetición Do While Ejecuta un bloqueInstruccion y verifica un condición de repetición de ejecución Diagrama de flujo Sintaxis: do bloqueInstruccion while(condicion); // 03_01a.c : Escribir un programa que lea un número n y valide (verifique) que su valor esté entre 1 y 4 #include<stdio.h> void main(void){ int n; do { printf("Escriba un número entero entre 0 y 4: "); scanf("%d", &n); // ingrese 6 y 3 } while (n < 0 || n > 4); printf("Número: %dn", n); } Salida: Escriba un número entero entre 0 y 4: 6 // Repite porque no cumple con la restricción Escriba un número entero entre 0 y 4: 3 Número: 3 2) Repetición While Verifica un condición, si es verdad ejecuta una bloqueInstruccion y vuelve a verificar la condición. Sintaxis while (condición) bloqueInstruccion PÁGINA: 1
  • 2.
    Lenguaje C Diagrama deflujo Repetir el programa anterior: leer un número n y validar (verificar) que su valor esté entre 1 y 4 // 03_01a.c : do bloqueInstruccion while(condicion) // 03_01b.c : while (condición) bloqueInstruccion #include<stdio.h> void main(void){ int n; do { int n = -1; while (n < 0 || n > 4) { printf("Escriba un número entero entre 0 y 4: "); scanf("%d", &n); // ingrese 6 y 3 } while (n < 0 || n > 4); } printf("Número: %dn", n); } Salida: Escriba un número entero entre 0 y 4: 6 // Repite porque no cumple con la restricción Escriba un número entero entre 0 y 4: 3 Número: 3 3) Repetición For Ejecuta varias operaciones, su diagrama de flujo es: (1) (2) (4) (3a) (3b) Sintaxis: for([inicios]; [instrucciones, condición]; [variaciones]) bloqueInstruccion Flujo de ejecución del for: Observe el flujo de ejecución en el diagrama (1), (2), (3a ó 3b) y (4); en la sintaxis se apreciaría así: for( (1)inicios; (2)instrucciones, condición; (4) variaciones) { (3a) // viene, si condición es verdad …. … sigue a (4) } (3b) // viene, si condición es falsa PÁGINA: 2
  • 3.
    Lenguaje C Ejemplo: for(i=0; i< 3; i++) printf("%d: %dn", i, i*i); Salida: 0: 0 1: 1 2: 4 Ejemplo: int i, j, k = 0; for(i=0, j =2; k++, i < 3; i++, j--) printf("i: %d, j: %d, k: %dn", i, j, k); Salida: i: 0, j: 2, k: 1 i: 1, j: 1, k: 2 i: 2, j: 0, k: 3 Descripción: Parámetro Descripción Ejemplo Inicios 0 ó más instrucciones de inicio, separadas por comas. Si no hay instrucciones, no se ejecuta nada. i = 0, j = 2 Instrucciones Condición 0 ó más instrucciones, separadas por comas. Si no hay instrucciones, no se ejecuta nada 0 ó 1 condición Si no hay condición, se evalúa a Verdad K++, i < 3 Variaciones 0 ó más instrucciones de variación, separadas por comas Si no hay instrucciones, no se ejecuta nada. I++, j-- bloqueInstrccion 1 ó más instrucciones Si no hay instrucciones, no se ejecuta nada. printf("i: %d, j: %d, k: %dn", i, j, k) // 03_02.c : Elevar al cuadrado los primeros 5 enteros #include<stdio.h> void main(void){ int n; printf("Numero Cuadrado"); for(n = 0; n < 3; n++) // inicios: n = 0, condición: n < 3, variaciones: n++ printf("n%dt%d", n, n*n); printf("n"); } Salida: Número Cuadrado 0 0 1 1 2 4 Ejemplo: #include<stdio.h> void main(void){ for( ; ; ) ; } Salida: No hace nada y no acaba nunca (se queda colgado); para matarlo: ctrl+c. Este ejemplo que solo hace perder el tiempo, sirve para recordarnos que: 1) Si no hay inicios : No se hace nada. 2) Si no hay condición : Se evalua a verdad. 3) Si no hay variaciones: No se hace nada. 4) La instrucción ; : No hace nada. Salir del loop: Normalmente se acaba la iteración cuando la condición es falsa; pero se puede salir antes, utilizando la instrucción break; // que salta al final del bloque Ejemplo: #include<stdio.h> void main(void){ for( ; ; ) break; } PÁGINA: 3
  • 4.
    Lenguaje C salida: Nohace nada , pero no se queda colgado, termina de inmediato. Anidamiento: Se pueden anidar varias estructuras: de repetición, de decisión, combinadas, en uno o más niveles. Ejemplo: Este ejemplo ya fue presentado en los dos capítulos anteriores, ahora lo modificaremos para presentar más opciones. Escriba un programa que lea dos enteros m y n , luego presente el menú: Operación que requiere: 1) Sumar: m + n 2) Restar: m – n 3) Multiplicar: m * n 4) Dividir: m/n // Atento a la división entre 0 5) Salir: Elija la operación: _ Indicaciones: Valide que la operación esté entre 1 y 5. // Sugerencia: Use do. Ejecute la operación seleccionada. // Sugerencia: Use switch. Presente nuevamente el menú hasta que operación = 5, lo cual termina el programa. // Sugerencia: Use do. // 03_03.c : Leer dos números, presentar un menú de operaciones, ejecutarlas repetidamente y salir finalmente. #include<stdio.h> void main(void){ int m, n, op; printf("Ingrese un entero m = "); scanf("%d",&m); printf("Ingrese un entero n = "); scanf("%d",&n); do { // presentar el menú si n !=5 printf("nOperación que requiere:n"); printf("1) Sumar: m + nn"); printf("2) Restar: m – nn"); printf("3) Multiplicar: m * nn"); printf("4) Dividir: m/nn"); printf("5) Salir:n"); do { printf("Elija su opción: "); scanf("%d",&op); } while (op<1 || op > 5); // Valida la opción entre 1 y 5 switch(op){ // Ejecuta la operación seleccionada case 1: printf("suma = %dn", m+n); break; case 2: printf("Resta = %dn", m-n); break; case 3: printf("Multiplicación = %dn", m*n); break; case 4: if(n!=0) printf("División = %.2fn", (float)m/n); else printf("Divisor es 0n"); break; default: printf("Gracias por su visitan"); } } while(op!=5); } Salida: PÁGINA: 4
  • 5.
    Lenguaje C Matriz deprueba: Caso Entradas Salida Chequeo m n opción 1 3 2 1 5 √ 2 3 2 2 1 √ 3 3 2 3 6 √ 4 3 2 4 1.50 √ 5 3 0 4 Divisor 0 √ 6 7 Solicita opción √ 7 5 Sale del programa √ Un nuevo algoritmo: Para resolver ciertos problemas difíciles, conocemos algoritmos fáciles de calcular, por ejemplo para hallar el máximo común divisor de dos números m y n = MCD(m, n), conocemos tres algoritmos clásicos: a) El método de Euclides b) El que nos enseñaron en la escuela: Producto de (factores primos de m y n comunes de menor potencia): c) Aplicar la fórmula m*n = MCD(m, n) * MCM(m, n); si conocemos el MCM(m, n) d) Podemos disponer de un nuevo algoritmo que utiliza el poder de cálculo del computador; por ejemplo para hallar el MCD(m, n) podemos aplicar la definición literalmente, cosa que no hacíamos antes porqué era muy pesado calcular. El algoritmo aplica la definición en modo literal y es muy fácil ya que aplica la definición literal: a. mn = mínimo(m,n); b. MCD = 1; c. for(i = 2; i <= mn; i++) MCD = (m%i==0 && n%i==0)? i:MCD; // (m%i==0 && n%i==0) quiere decir que i es común divisor de m y n Este mismo caso se presenta si queremos saber si un número es, o no, primo; aplicamos la definición literal y la calculamos con el computador. No siempre es posible aplicar este método: ya sea porqué los algoritmos requieren mucho calculo, aún para una computadora o no tienen solución. Resumen de las iteraciones: Hemos estudiado tres tipos de iteración, ¿cuál elegir?, Vamos a compararlos (hacer un benchmark): Sintaxis for([inicios]; [instrucciones, condición]; [variaciones]) bloqueInstruccion do bloqueInstruccion while(condición); while (condición) bloqueInstruccion Si fuera necesario abandonar un bloque, puede usar break; y saltará al final de la estructura. Esquema de programación do {...} while(...); y while(…) {….} No tienen inicios (se colocan al inicio) No tienen variaciones (se colocan dentro). for([inicios]; [condición]; [variaciones]) { ejecutarTarea; } Inicios; do { ejecutarTarea; variaciones; } while(condición); Inicios; while(condición) { ejecutarTarea; variaciones; }; PÁGINA: 5
  • 6.
    Lenguaje C // 03_04.c: Leer un número entero > 0 y determine si es primo o no. Desarrolle las 3 alternativas usando bucles. #include<stdio.h> void main(void){ int n, i=2, primo=1; printf("Ingrese un entero > 0: "); scanf("%d", &n); for(;i<n && i*i <= n && primo ; i++) if(n%i==0) primo=0; if(n>2) do if(n%i++==0) primo=0; while(i<n && i*i <= n && primo); while(i<n && i*i <= n && primo) if(n%i++==0) primo=0; if(primo) printf("%d es primon", n); else printf("%d no es primon", n); } ¿Qué alternativa le gusta, y por qué? No solo es cuestión de forma y gusto, el problema específico determina cuál de las estructuras es la más adecuada para su programación. Las 3 estructuras requieren los mismos componentes: inicio, variaciones, condición y bloque de repetición; la diferencia está en el orden en que se dan, un criterio puede ser: Elija for() si tiene claramente definidos el inicio y el fin. Caso contrario: Elija do {...} while(...) si el condición va mejor al final Caso contrario: Elija while (condición) { … }. 03_05.c : Leer y sumar números. Desarrolle las 3 alternativas usando bucles. Lea n > 0, lea y sume n datos Lea y sume datos positivos, termine si un dato es negativo. #include<stdio.h> void main(void){ int i, n, dato, suma = 0; printf("Ingrese el número de datos: "); scanf("%d", &n); for (i=1; i <= n; i++) { printf("Ingrese dato: "); scanf("%d", &dato); suma += dato; } int dato = 0, suma = 0; do { suma += dato; printf("Ingrese dato: "); scanf("%d", &dato); } while (dato > 0); int dato, suma = 0; printf("Ingrese dato: "); scanf("%d", &dato); while (dato > 0){ suma += dato; printf("Ingrese dato: "); scanf("%d", &dato); } printf("la suma es: %dn", suma); } Ejemplo: Una estudiante de C tiene insomnio, un colega decide ayudarla y le escribe un programa bien cuchi (así se dice en mi tierra) escrito en C: zz.c, el cual muestra en el monitor: 3 ovejitas 6 conejitos 9 ovejitas … 96 conejitos 99 ovejitas 96 conejitos …. 3 ovejitas zzz zzz ….C que te quito el sueño, C que te hago soñar despierta y, C hacerte dormir: Linda noche para la más linda. Sugerencias: 1) Use do{ .. } while( … ); 2) Fíjese que se escriben conejitos para los números pares, y ovejitas para los impares Nota: El programa será corto, robusto (correcto, flexible), ingenioso, a esto se le llama sexi en el argot de computación. PÁGINA: 6
  • 7.
    Lenguaje C // Conejitos- ovejitas // 03_06a.c : Usa do{ … } while(condicion); // 03_06b.c : Usa for #include<stdio.h> void main(void){ int n = 3, salto = 3; // Inicios do{ int n, salto; for(n = 3, salto = 3; n>0; n += salto, salto = (n==99)? -3:salto) { if(n%2==0) printf("n%d conejitos", n); // ejecución else printf("n%d ovejitas", n); n += salto; // Variaciones if(n==99) salto = -3; // variaciones } while(n>0); // condición } printf("nzzz zzz ….C que te quito el sueño, C que te hago soñar despierta y, C hacerte dormir: Linda noche para la más linda.n"); } Salida: Se muestra lo prometido Esperemos que se duerma la chica y que el chico haya aprendido a usar las instrucciones do y for Pasos para desarrollar un programa Un programa se puede desarrollar en 4 pasos, veámoslo con un ejemplo concreto: Graficar en el monitor. 1) Solicitud del usuario: Definición del entregable incluyendo la matriz de pruebas, la cual es parte de las condiciones de aceptación. Entregable: programa en C: Dado un entero n >=0, grafique un rombo relleno, con diagonales 2n+1. Matriz de Prueba: Caso Entrada: n Salida Chequeo 1 0 * 2 1 * * * * * 3 2 * * * * * * * * * * * * * 2) Algoritmo de solución: algoritmo matemático, pseudo-código. Este no es un problema sencillo de programar y requiere del apoyo de nuestros conocimientos de matemáticas. Hay dos alternativas para la solución. Nota: En matemáticas identificamos a los ejes de coordenadas con X y Y; en computación, para números enteros solemos identificar las filas con i (eje Y) y las columnas con j (eje X). Alternativa Algoritmo matemático Poner el eje de coordenadas en el centro del rombo, graficar en el primer cuadrante: La linea de borde del rombo cumple la ecuación: i = -j +n Todos los * del primer cuadrante cumplen: i + j <= n Otros cuadrantes: Aplicar simetrías con los dos ejes Poner el eje de coordenadas a la izquierda, graficar la parte superior: Para cada fila i: Calcular el número de blancos nb e imprimirlos. Calcular el número de * na e imprimirlos. nb = i na = 2(n-i) -1 Parte inferior: Aplicar simetría con el eje horizontal Pseudocódigo Primer Cuadrante: Variar i: n → 0 // eje vertical Variar j: 0 → n // eje horizontal Si i + j <= n imprimir *, sino imprimir blanco Parte superior: Variar i: n → 0 // eje vertical nb = n-i; imprimir na = 2(n-i); imprimir PÁGINA: 7
  • 8.
    Lenguaje C Otros cuadrantes: Variari: n → -n // eje vertical Variar j: -n → n // eje horizontal ai = abs(i); aj = abs(j) // valores absolutos Si ai + aj <= n imprimir *, sino imprimir blanco Parte inferior: Variar i: n → -n // eje vertical ai = abs(i) // valor absoluto nb = ai; imprimir na = 2(n-ai) -1; imprimir Se elije la posición de los ejes que más facilite el algoritmo. 3) Programación: diseño, desarrollo, validación contra la matiz de pruebas. // 03_07a.c: Ejes en el centro del rombo // 03_07b.c: Ejes a la izquierda del rombo // primer cuadrante, para probar #include<stdio.h> void main(void){ int n, i, j; printf("Ingrese un entero >= 0: "); scanf("%d", &n); for(i=n; i>=0; i--){ for(j=0; j<=n; j++) if(i+j<=n) printf (" *"); else printf (" "); printf("n"); } } // parte superior, para probar #include<stdio.h> void main(void){ int n, i, j, nb, na; printf("Ingrese un entero >= 0: "); scanf("%d", &n); for(i=n; i>=0; i--){ nb = i; for(j=0; j<= nb; j++) printf (" "); na = 2*(n-i); for(j=0; j<= na; j++) printf (" *"); printf("n"); } } // solución completa: simetría en los dos ejes #include<stdio.h> #include<math.h> // compile con: -lm void main(void){ int n, i, j, ai, aj; printf("Ingrese un entero >= 0: "); scanf("%d", &n); for(i=n; i>=-n; i--){ ai = fabs(i); for(j=-n; j<=n; j++){ aj = fabs(j); if(ai+aj<=n) printf (" *"); else printf (" "); } printf("n"); } } // solución completa: simetría con eje horizontal #include<stdio.h> #include<math.h> // compile con: -lm void main(void){ int n, i, j, nb, na; printf("Ingrese un entero >= 0: "); scanf("%d", &n); for(i=n; i>=-n; i--){ nb = fabs(i); for(j=0; j<= nb; j++) printf (" "); na = 2*(n-nb); for(j=0; j<= na; j++) printf (" *"); printf("n"); } } Salida: Se grafica el rombo 4) Prueba y entrega al usuario: Chequear la matriz de pruebas, repetir el chequeo de la matriz de prueba con el usuario y entregar. PÁGINA: 8
  • 9.
    Lenguaje C Ejemplo: Pidaingresar un entero impar n > 3, ejemplo: n = 7 y dibuje la siguiente figura con "*": * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Análisis: Hay * en las diagonales y en los extremos: ¿dónde conviene poner el eje de coordenadas? Hay varias alternativas: // 03_08a.c: Ejes en el centro del rombo // Variaciones: n/2 >= i >= - n/2; -n/2 <= j <= n/2 // 03_08b.c: Ejes arriba a la izquierda // Variaciones: 1<= i <= n; 1<= j <= n: #include<stdio.h> void main(void){ int n, i, j; printf("Tamaño del arreglo: "); scanf("%d", &n); // Ingrese = 7 int ai, aj; n /=2; for(i=n; i>=-n; i--){ ai =(i>0)? i:-i; // valor absoluto de i for(j=-n; j<=n; j++){ aj =(j>0)? j:-j; if(ai==n || aj==n || ai == aj) printf("* "); else printf(" "); } for(i=1; i<= n; i++){ for(j=1; j<= n; j++) if(i==1 || i==n || j==1 || j==n || i==j || i == n-j+1) printf("* "); else printf(" "); printf("n"); } } Ejercicios: Escriba, compile y ejecute programas que hagan lo siguiente: 1) Lea un número entero n, calcule el factorial de n! = 1*2*3..*n utilizando do … while y muestre n y n! 2) Lea un número entero n y calcule la suma sn de los n primeros números: sn = 1 + 2 + … + n, y muestre n y sn, de dos modos: a) sn = n*(n+1)/2 b) utilizando while () {….} 3) Lea un número entero n y determine si es ó no primo, Hágalo de 3 formas distintas. Imprima: n es primo n no es primo 4) Lea dos números enteros m y n positivos, encuentre el máximo común divisor MCD e imprima, utilice el método de aplicar la definición literal sugerido antes. 5) Lea dos números enteros m y n positivos, encuentre el máximo común divisor MCD y el mínimo común múltiplo MCM e imprímalos. 6) Que hace el siguiente programa: … int i, j; for(i=0, j=20; i < 10; i++, j--) printf("ni= %d; j = %d", i, j); PÁGINA: 9