Estructuras de repetición

Documentos relacionados
Arreglos. Donde en cada posición del array se puede guardar un elemento. tipo_dato nombre_array[cant_elem];

5. ESTRUCTURAS DE REPETICIÓN

Algoritmo, Estructuras y Programación I Ing. Marglorie Colina

Estructuras de Repetición

Tipos de Datos de python (2ª parte):

Tema 3. Estructuras de control

LABORATORIO 5 FUNCIONES

Sentencias iterativas

SESIÓN DE EJERCICIOS E1

Dobles: Es el caso de la instrucción if-else (punto 1.2).

Capítulo 13 INSTRUCCIONES DE CONTROL REPETITIVAS. Presentación resumen del libro: "EMPEZAR DE CERO A PROGRAMAR EN lenguaje C"

Estructuras de Repetición: Repita Mientras.

Distinguir las diferentes estructuras de repetición utilizadas en problemas con bucles: mientras, repetir mientras, para.

Reales. Caracteres. Cadenas de Caracteres (String)

Control de Flujo. Estructuras de Control! Experiencia Educativa de Algorítmica CONTROL DE FLUJO

Estructuras de control: Las variables: Fuertemente tipado: Tipado dinámico: Variables booleanas: Qué son las estructuras de control?

Operadores aritméticos

EJERCICIOS RESUELTOS: DIAGRAMAS DE FLUJO DOCENTE: ING. ALEXIS MASSÓN. Programación I - UTN-FRC Ing. Alexis Massón Ejercicios resueltos

Actividad Algoritmos, Estructura y Programación I. FOR, DO-WHILE

GENERALIDADES DEL LENGUAJE C

TEMA 4. ESTRUCTURAS DE CONTROL

Ejercicios de Programación

Conceptos. Generales ALGORITMOS

TEMA 5. CONTROL DE FLUJO DEL PROGRAMA. Sentencia Instrucción Expresión Operadores + Operandos Sintaxis: Sentencia ;

Estructuras Repetitivas

Programación: Estructuras de Control

ESTRUCTURAS REPETITIVAS EN PHP

TEMA 5. PROGRAMACIÓN BÁSICA EN MATLAB /OCTAVE

Palabras reservadas de C++ y C. Una palabra reservada no puede declararse como un identificador, esto haría un conflicto entre conectores y funciones.

Estructura repetitiva while

Tema: Estructuras de Repetición en C# [For].

Programación I. Ingeniería Técnica Informática. Ejercicios de los Temas 4, 5, 6 y 7

Lógica de programación

ESTRUCTURAS DE CONTROL REPETITIVAS

Lógica de programación

GENERALIDADES DEL LENGUAJE C. Nota: Los ejemplos y ejercicios especifican el tipo de archivo a enviar a

La resolución de problemas es una tarea únicamente humana comprobable en todos los casos con los mismos resultados.

Sentencias de control de flujo

Formato para prácticas de laboratorio

Autor: Ing. Nahuel González INTRODUCCIÓN A C. Clase 1

Fundamentos de programación

Tema: Estructuras de Repetición en C# [For].

GUIA DE EJERCICIOS N 1 LENGUAJE C# Página 1 de 5. Instructor: Ing. Néstor Raúl Suarez Perpiñan

Sentencias de salto: break, continue, goto Sentencia de Salto: break

WHILE Y DO WHILE BREAK EN LENGUAJE C. BUCLES MIENTRAS. FORZAR SALIDA O TERMINACIÓN. EJEMPLO (CU00534F)

Conocimientos previos

Capítulo 4. Estructuras Iterativas

Andrés Donaciano Martínez Guillén -.- Fundamentos de programación -.andresmtzgwordpress.com

Estructura repetitiva do while

Tema 3. Estructuras de Datos

Repetición Condicional

SESIÓN DE EJERCICIOS E1

EJERCICIOS PARA EMPEZAR CON PHP

Estructuras de Repetición (Repita para)

Control de Flujo. Estructuras de Control! Experiencia Educativa de Algorítmica CONTROL DE FLUJO

suma de los n>0 primeros números que se lean del teclado. El número n es un dato y es

Tema: Estructuras de Repetición en C#.

Tema: Estructuras de Repetición en C#.

Capítulo 4. Estructuras de control. Profra. Catalina Trevilla Román Profr. Armando Valera Paulino

Universidad Tecnológico Ecotec. Fundamento de programación. Deber

TEMA 4: Estructuras de Control

PYTHON. Programación estructurada

Control de Flujo II. Estructuras Repetitivas

Estructura de un programa en Java. Tipos de datos básicos. class miprimerprograma{ // comentario, no es parte del programa

Tema 06: Estructuras y sentencias de control en C

Programación en Lenguaje C

MÚLTIPLES Estructuras condicionales anidadas if(expresion1 o condición1){ Sentencias1 } else { if (expresion2){ Sentencias2

Ciclos. Recordando Estructuras de Control Básicas: SELECCIÓN (condición) SECUENCIAL

MICROSOFT WORD. Más opciones de edición de documentos

FUNDAMENTOS PARA LA CONSTRUCCIÓN DEL CÓDIGO A PARTIR DEL ALGORITMO

Tema 2: Elementos básicos de un programa. Tipos de datos, variables y constantes Asignación Operadores y expresiones

Principal material bibliográfico utilizado

Estructura de Datos ARREGLOS

Método Egipcio Mejorado

Práctico 2: Funciones y Punteros en C La teoría general para este práctico puede consultarse en los Capítulos 4 y 5 Notas de Clase

Programación Estructurada. Sesión 2:El lenguaje de programación C

Práctica Guiada: Vectores y Matrices

INFORMATICA TECNICATURA DE NIVEL SUPERIOR ALGUNOS EJERCICIOS DE SELECCIÓN E ITERACION

Programación Estructurada

Sentencias DO-WHILE EN C++

Lección 5: Ecuaciones con números naturales


ARREGLOS INTRODUCCIÓN

Objetivos de la práctica: - Trabajar las estructuras de control repetitivas en la realización de programas.

Sumar o restar porcentajes en Excel

ASIGNATURA PROGRAMACIÓN EN C++ GUÍA: 1 DOCENTE. LIZETH CORTÉS VARIABLES C++

Transcripción:

Estructuras de repetición Las estructuras de repetición sirven, como su nombre lo indica, para repetir porciones de código. Imagínense que no existieran y quisieramos mostrar todos los números del 1 al 5. Habría que hacer algo así: int num = 1; printf("%d", num); printf("%d", num+1); printf("%d", num+2); printf("%d", num+3); printf("%d", num+4); Demás está decir que con 5 números no hay problema, pero si se piden 100, ahí el tema se complica. En este caso siempre estamos haciendo lo mismo, "repitiendo" lo mismo. Lo que las estructuras de repetición nos permiten es no tener que escribir n veces el mismo bloque de código. Entonces, usando un FOR por ejemplo, quedaría así: int num; for (num = 1; num <=5; num++) printf("%d\n", num); Usando un WHILE: int num = 1; while (num <= 5) printf("%d\n", num); num++; El printf sólo lo escribimos una vez en el código, en lugar de cinco. Esto es lo básico. Lo importante acá es que vean que el tema no es tan complicado como parece, y que la única magia de los ciclos de repetición es eso, repetir.

Ahora yendo un poco más al detalle. Hay tres tipos distintos de estructuras de repetición: FOR WHILE DO-WHILE La gran diferencia que existe entre FOR y WHILE es lo que se podría llamar "control de repetición". Al WHILE se lo llama ciclo de repetición no controlada, porque, de antemano, no se sabe cuántas veces se va a repetir, es decir, no se tiene control sobre eso. Al FOR se lo llama ciclo de repetición controlada, porque para usarlo se necesita definir exactamente el intervalo de repetición. Se sabe cuándo inicia y cuándo termina, o sea, se tiene control sobre la repetición. Ojo acá, que estas definiciones no son tan rígidas como aparentan. Generalmente, para resolver un problema se puede usar tanto uno como otro tipo de ciclo (enfatizando el generalmente), pero en algunos casos es más correcto usar uno, y en otros casos resulta más correcto usar el otro. WHILE La sintaxis del WHILE es la siguiente: while (condición) Bloque de código a ejecutar mientras se cumpla la condición Un problema para resolver con WHILE sería: "Ingresar un número y multiplicarlo sucesivamente por 2, mientras el resultado sea menor a 1000. Mostrar las multiplicaciones sucesivas." Acá, inicialmente, no se sabe cuántas veces se va a tener que multiplicar el valor ingresado por 2. Incluso la cantidad de veces va a depender de qué tan grande sea el valor ingresado (no va a ser lo mismo ingresar un 2 que ingresar un 450). Es decir, la repetición es "no controlada" desde el punto de vista que, a priori, no hay un intervalo de repetición definido, por lo que es incierta la cantidad de veces que el proceso se va a repetir. El programa quedaría así: int num; printf("ingrese un numero: ");

scanf("%d", &num); while (num < 1000) printf("multiplicando... %d\n", num); num = num * 2; Mientras el resultado de multiplicar por 2 sea menor que 1000, el ciclo WHILE se va a seguir ejecutando. En el momento en que el resultado sea mayor que 1000, el WHILE termina. DO-WHILE La sintaxis del DO-WHILE es la siguiente: do Bloque de código a ejecutar mientras se cumpla la condición while (condición); El DO-WHILE es similar al WHILE, excepto en el hecho de que la condición se evalúa al final de cada repetición, en lugar de al principio. En el WHILE, si la condición no se cumple al principio, lo que está dentro del ciclo nunca se ejecuta. En cambio, en el DO-WHILE lo que está dentro del ciclo se va a ejecutar al menos una vez. Después se evalúa la condición: si se cumple, sigue, sino, termina. Un ejemplo: "Ingresar números enteros hasta que se ingrese un cero." Acá puede pasar: que se ingresen muchos números y por último un cero que el primer número que se ingrese sea un cero Entonces, hay que pedir el ingreso del número, al menos una vez. Con el código espero quede más claro: int num; do printf("ingrese un numero (cero para terminar): "); scanf("%d", &num); while (num!= 0);

Acá, primero se ejecuta el bloque de código (printf y scanf en este caso). Una vez que en la variable num se encuentra almacenado el número ingresado, recién ahí el programa se pregunta num!= 0?. Si la respuesta es VERDADERO, el ciclo se repite (solicitando otro número), si es FALSO, el ciclo termina. FOR La sintaxis del FOR es la siguiente: for (iterador = ini_intervalo; iterador < fin_intervalo; inc_iterador) Bloque de código a ejecutar siempre que el iterador se encuentre dentro del intervalo definido El "iterador" es una variable propia de la sintaxis del FOR, que: especifica el inicio del intervalo de repetición, indica el final del intervalo de repetición, se va a ir incrementando cada vez que se repita el ciclo. Por ejemplo: "Mostrar en pantalla la tabla del 3." Acá vamos a tener que mostrar, para cada número del 1 al 10, cuál es el resultado de multiplicarlo por 3 (la tablita que aprendimos en primaria). El programa quedaría así: int i, resultado; for (i = 1; i <= 10; i++) resultado = 3 * i; printf("%d * %d = %d\n", 3, i, resultado); Se utiliza el FOR porque se conoce que la tabla de multiplicar va de 1 a 10, entonces se va a tener que repetir el proceso 10 veces. Usamos la variable i como iterador, que irá tomando los valores 1, 2, 3,.., 10. Una vez que i supera a 10, el FOR termina. Y cómo hace para ir tomando un valor distinto e incremental en cada repetición? Eso está especificado en la última parte del FOR, cuando se especifica i++. Ahí lo que se está diciendo es que el i se incremente en 1 cada vez que se ejecuta el bloque de código dentro del FOR.

Una cosa a tener en cuenta: usualmente, por cada iteración el i se incrementa en 1. Pero en realidad ahí se puede especificar cualquier tipo de incremento o decremento. Se puede hacer que el i vaya de 2 en dos: i = i + 2. O que vaya de mayor a menor: i. Todo depende del problema a resolver. Hasta acá, ejemplos típicos de uso de cada ciclo/estructura de repetición. Acumuladores Muchas veces los ciclos de repetición se utilizan para acumular valores y después mostrarlos. Un ejemplo sería: "Hacer un programa que permita ingresar números, hasta que se hayan ingresado diez números pares. Luego mostrar el promedio de dichos números." Cuando tenemos cualquier problema, lo primero que tenemos que definir es lo que se llama "estrategia de resolución", es decir, a grandes razgos cuáles van a ser los pasos a seguir para resolver el problema. En este caso serían: 1. Ir pidiendo el ingreso de los números, uno por vez. 2. Por cada número, chequear si es o no par. 3. Si es par, lo acumulo. Si no es par, no hago nada. 4. Una vez que tengo los diez números, calculo el promedio. El programa quedaría así: int num, cant_pares = 0, suma = 0; double promedio; do printf("ingrese un numero: "); scanf("%d", &num); if (num % 2 == 0) cant_pares = cant_pares + 1; suma = suma + num; num++;

while (cant_pares < 10); promedio = suma / 10.0; printf("el promedio de los numeros pares ingresado es: %.2lf\n", promedio); Por qué se usa un ciclo de tipo DO-WHILE? Porque al principio no se sabía cuántas veces se iba a tener que pedir al usuario que ingresara un número. Y por qué no usar un ciclo WHILE? Se podría haber resuelto con un WHILE, pero hay que tener en cuenta que en este problema, al usuario había que pedirle que ingrese un número al menos una vez (de hecho, como mínimo va a tener que ingresar diez números, si se da el caso de que todos sean pares). Por otro lado está la variable suma, que acumula los números pares, mientras se van ingresando los números. La acumulación se realiza sumando el nuevo número a lo que ya estaba almacenado en la variable: suma = suma + num. Una vez que termina el DO-WHILE se la utiliza para calcular el promedio. Con este tipo de variables hay que tener especial cuidado de inicializarlas antes de usarlas: si suma no hubiese estado inicializada en 0, al hacer suma = suma + num, estaríamos sumando num a "basura" (el contenido de suma, o más bien el no contenido de suma). Otro ejercicio: Imprimir en pantalla el producto de todos los múltiplos de 3, que hay entre 9 y 60. Acá habría que recorrer todos los números, de tres en tres, e ir acumulándolos. Entonces: int i, producto = 1; for (i = 9; i <= 60; i = i + 3) producto = producto * i; printf("\nel producto es: %d", producto); El detalle acá es la definición del incremento: en lugar de ser i++, es i = i + 3, logrando que por cada repetición (o iteración) la i se incremente en 3. Caracteres Hasta acá hicimos ejercicios con números. Pero también existen los caracteres. No hay una

diferencia real muy grande en cuanto a los conceptos a aplicar para resolver un ejercicio con caracteres, y al final, la mecánica es la misma. Por ejemplo: "Ingresar una frase, terminada en un '.' y contar cuántas mayúsculas contiene." Cuando trabajábamos con números, los ingresábamos usando scanf(), con los caracteres, en cambio, usamos getche(). Entonces, en este ejercicio, si se tipea por ejemplo: "Bart, no quiero asustarte, pero tal vez el Coco, el Coco esta en la casa!." el programa tendría que ir ingresando cada caracter, uno a uno con el getche() y contar todas las mayúsculas. Al final tendría que informar que hay 3. La condición que se tiene que cumplir para que el programa siga aceptanto caracteres es que el caracter ingresado sea distinto de '.', entonces eso mismo se especifica en la condición del WHILE. char letra; int cant_mayusc = 0; letra = getche(); while (letra!= '.') if (letra >= 'A' && letra <= 'Z') cant_mayusc++; letra = getche(); printf("cantidad de mayusculas: %d\n", cant_mayusc); De a poco, en estos ejercicios se van incorporando todas las distintas estructuras vistas hasta ahora. Figuras El tema de las figuras no es uno sencillo, pero como todo, es cuestión de agarrarle la mano. Vamos a empezar por una simple: **** **** **** ****

Acá lo que tenemos es un cuadrado de 4 x 4. Entonces: tenemos que dibujar 4 filas por cada fila, 4 asteriscos O sea, esto se puede plantear con dos ciclos for, uno dentro del otro: el primero va a controlar la cantidad de filas que tenemos que dibujar el segundo (interno) va a controlar la cantidad de asteriscos a dibujar Algo a tener en cuenta. Una vez que se termina de dibujar la fila, tenemos que "dibujar" un \n, para poder pasar al renglón siguiente. Si no lo ponemos, todas las filas se van a dibujar en el mismo renglón. El programa quedaría así: int base, altura; printf("ingrese la base: "); scanf("%d", &base); printf("ingrese la altura: "); scanf("%d", &altura); int i, j; // la altura nos indica la cantidad de líneas for (i = 0; i < altura; i++) // la base nos indica la cantidad de asteriscos por línea for (j = 0; j < base; j++) printf("*"); printf("\n"); Esta es la figura más simple que uno puede llegar a dibujar: la cantidad de asteriscos por fila es siempre la misma y no hay que agregar espacios en blanco en ningún lado. Compliquemos un poco la cosa: ahora vamos a dibujar un triángulo rectángulo. Se tendría que ver así: **** *** ** * Acá la cantidad de asteriscos por fila se va incrementando, uno más por cada fila que dibujamos.

Conociendo la base del triángulo (el dato se ingresa por teclado), podemos saber cuántas filas vamos a tener que dibujar, por lo que se puede usar un ciclo for que vaya desde 0 hasta la cantidad de filas. Ahora analicemos cómo dibujar cada fila. Usamos un for para dibujar la cantidad de asteriscos necesarios por fila. El intervalo del for va a ir de 0 a cantpint (variable que define la cantidad de asteriscos a dibujar por fila). Se puede ver en el dibujo que en la primera fila dibujamos 4 asteriscos, en la segunda 3, en la tercera 2, y así sucesivamente hasta dibujar todas las filas. Es decir, por cada fila, se va dibujando un asterisco menos. Entonces, lo que tenemos que hacer es decrementar cantpint cada vez que terminamos de dibujar una fila. El código quedaría así: int base; printf("ingrese la base: "); scanf("%d", &base); int f, c; int cantpint = base; for (f = 0; f < base; f++) for (c = 0; c < cantpint; c++) printf("*"); printf("\n"); cantpint ; Un for externo para dibujar las filas, y, por cada fila un for interno para dibujar los asteriscos de la fila. Planteemos ahora una figura con espacios en blanco. Algo así, por ejemplo: **** 0 espacios 4 asteriscos *** 1 espacio 3 asteriscos ** 2 espacios 2 asteriscos * 3 espacios 1 asterisco Es un triángulo rectángulo como el anterior, pero sobre el margen derecho. Acá el problema es que no podemos hacer que los asteriscos se dibujen a partir de tal lugar automáticamente. Para hacer que un asterisco se dibuje en la segunda columna, hay que

rellenar la primera columna con un espacio. Para que se dibuje en la tercera columna, hay que rellenar la primera y la segunda con espacios, y así sucesivamente. Entonces, volviendo al problema, hay que analizar cómo se dibuja cada fila: 1º fila: 0 espacios - 4 asteriscos 2º fila: 1 espacio - 3 asteriscos 3º fila: 2 espacios - 2 asteriscos 4º fila: 3 espacios - 1 asteriscos Esto significa que, además de tener un for para dibujar los asteriscos, vamos a tener otro para dibujar los espacios. La estrategia sería: plantear un for externo para ir dibujando cada fila, por cada fila dos for internos: el primero para dibujar los espacios y el segundo para dibujar los asteriscos. En cuanto a los espacios, por cada fila se va incrementando en 1 la cantidad de espacios a dibujar (empezando de 0). En cuanto a los asteriscos, por cada fila se va decrementado en 1 la cantidad de asteriscos a dibujar (empezando de 4, que sería el dato de base del triángulo). En resumen, el código quedaría así: int base; printf("ingrese la base: "); scanf("%d", &base); int f, c; int cantblancos = 0; int cantpint = base; for (f = 0; f < base; f++) for (c = 0; c < cantblancos; c++) printf(" "); for (c = 0; c < cantpint; c++) printf("*"); printf("\n"); cantblancos++; cantpint ; La variable f es el iterador del ciclo for externo. Controla cada fila que se dibuja.

La variable c es el iterador de cada ciclo for interno. Sirve para dibujar cada espacio o asterisco respectivamente. Por qué cantblancos está inicializada en 0? Porque en la primera fila que hay que dibujar, no hay ningún espacio. Por qué cantpint está inicializada en base? Porque la primera fila dibuja una cantidad de asteriscos igual a la base del triángulo. Hasta ahora, los dibujos los planteamos usando contadores y buscando "reglas" que definen cómo se incrementan o decrementan esos contadores. Después, era sólo cuestión de imprimir espacios y asteriscos. Hay otra manera de dibujar: planteando regiones. Básicamente, se define una región en base a cierta condición: si el par fila:columna (f:c) cumple la condición se dibuja un *, si no, un espacio. El quid de la cuestión está en encontrar esa condición. Por ejemplo, volviendo al primer triángulo rectángulo: **** *** ** * Imaginándonos que el triángulo está dentro de una tabla con filas y columnas, si planteamos f + c, nos quedaría algo así: 0 1 2 3 0 0 1 2 3 1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 f + c Lo que a nosotros nos interesa dibujar es lo que está pintado. Entonces, lo que hay que hacer ahora es encontrar una relación que "defina" de alguna manera a todas esas celdas pintadas. Analizando un poco se puede ver que sólo están pintadas las celdas donde la suma de fila y columna f + c es menor a la base del triángulo. Es decir, que para todos los pares (f:c) que cumplan la condición f + c < base, tendríamos que dibujar un *, para los que no, un espacio. A partir de esto, ya se podría plantear el código.

int base; printf("ingrese la base: "); scanf("%d", &base); int f, c; for (f = 0; f < base; f++) for (c = 0; c < base; c++) if (f + c < base) printf("*"); else printf(" "); printf("\n"); El for externo sirve para recorrer todas las filas. El for interno nos sirve para recorrer, por cada fila, todas las columnas. Haciendo que ambos ciclos varíen entre 0 y base, logramos recorrer la tabla completa. Ahora lo único que nos queda es decidir en qué celda dibujamos un espacio y en cuál un asterisco. Usando un if podemos plantear la condición que habíamos encontrado. Si se cumple, se dibuja un *, si no, un espacio. Este método de dibujo tiene su pro y su contra. Pro: los límites de los ciclos son siempre los mismos, por lo que no hace falta estar pensando en incrementar o decrementar contadores. Contra: a veces resulta difícil identificar la condición que define a la región que queremos dibujar. Ahora con el otro triángulo: **** *** ** * Si planteamos f + c, nos quedaría algo así:

0 1 2 3 0 0 1 2 3 1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 f + c Se puede ver que la suma no nos sirve, porque tenemos iguales valores a veces pintados y a veces no. Planteemos entonces, f c: 0 1 2 3 0 0-1 -2-3 1 1 0-1 -2 2 2 1 0-1 3 3 2 1 0 f - c Acá sí podemos obtener una condición que cumplan sólo las celdas que nos interesan: f c <= 0, o poniéndolo de otra manera, f <= c. Definido esto, ya podemos armar el programa: int base; printf("ingrese la base: "); scanf("%d", &base); int f, c; for (f = 0; f < base; f++) for (c = 0; c < base; c++) if (f <= c) printf("*"); else printf(" "); printf("\n");

Hasta acá, figuras relativamente simples, en el sentido de que se pueden dibujar de una sola pasada, ya que las relaciones entre espacios y asteriscos se mantienen en toda la figura, desde la primera fila hasta la última. Hay otras en la que esto no ocurre, por lo cual para dibujarlas es necesario dividirlas en subfiguras más pequeñas, donde las relaciones sean simples. Un ejemplo de figura un poco más compleja, sería un reloj de arena, de base impar, dibujado de la siguiente manera: ***** *** * *** ***** En esta figura, hasta llegar a la mitad, la cantidad de asteriscos va disminuyendo mientras que la de espacios va aumentando. Después de la mitad, la cosa se invierte. Entonces, en lugar de complicar el tema, es mejor dividir el problema en dos subfiguras, que seguramente van a ser más fáciles de resolver. En este caso, podemos plantear el dibujo del triángulo de arriba y a continuación el dibujo del triángulo de abajo. Sólo quedaría resolver un detalle: la fila de la mitad, en qué triángulo la incluímos? Por una cuestión de manejo de contadores, en este caso conviene dibujarla con el triángulo de abajo. Pero, se puede resolver tanto de una manera como de otra. Analizando, Primera mitad: la cantidad de asteriscos comienza con un número igual a la base, decrementándose en 2 por cada fila dibujada no hay espacios en la primera fila, incrementándose después en 1 con cada fila dibujada la cantidad de filas a dibujar es igual a dividir la base sobre 2 Segunda mitad: la cantidad de asteriscos comienza en uno, incrementándose en 2 por cada fila dibujada la cantidad de espacios comienza en un valor igual a dividir la base sobre 2, y se decrementa de a 1 por cada fila dibujada la cantidad de filas a dibujar es igual a dividir la base sobre 2 y sumarle 1 A partir este análisis de las partes de la figura podemos empezar a codificar la solución como sigue a continuación:

int base; // validamos el ingreso de una base impar do printf("ingrese la base (impar): "); scanf("%d", &base); while (base % 2 == 0); int c, f; int cantblancos, cantpint; // inicializamos los contadores cantblancos = 0; cantpint = base; // dibujamos el triángulo de arriba for (f = 0; f < base / 2; f++) for (c = 0; c < cantblancos; c++) printf(" "); cantblancos++; for (c = 0; c < cantpint; c++) printf("*"); cantpint = cantpint 2; printf("\n"); // dibujamos el triángulo de abajo for (f = 0; f < (base / 2) + 1; f++) for (c = 0; c < cantblancos; c++) printf(" "); cantblancos ; for (c = 0; c < cantpint; c++) printf("*"); cantpint = cantpint + 2; printf("\n");

Lo primero que hacemos es pedir el ingreso de una base impar, cosa que se repetirá mientras el número ingresado sea par. Luego definimos e inicializamos los contadores. Y por último, el dibujo propiamente dicho, con un for para el triángulo de arriba y otro for para el triángulo de abajo. Tanto los valores iniciales de los contadores como los intervalos de repetición de todos los ciclos for están basados en el análisis previo de la figura. Algo a tener en cuenta: al dividir la figura en dos partes, logramos que la resolución se simplificase. Por qué? Porque logramos expresar una figura compleja, como dos figuras más simples de analizar y dibujar. Plateemos la solución utilizando regiones. Analicemos la región superior, planteando f c y f + c 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 0-1 -2-3 -4 0 0 1 2 3 4 0 1 1 0-1 -2-3 1 1 2 3 4 5 1 2 2 1 0-1 -2 2 2 3 4 5 6 2 3 3 2 1 0-1 3 3 4 5 6 7 3 4 4 3 2 1 0 4 4 5 6 7 8 4 f c <= 0 f + c < base Intersección de ambas condiciones De la misma manera, analizamos la región inferior, planteando f c y f + c 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 0-1 -2-3 -4 0 0 1 2 3 4 0 1 1 0-1 -2-3 1 1 2 3 4 5 1 2 2 1 0-1 -2 2 2 3 4 5 6 2 3 3 2 1 0-1 3 3 4 5 6 7 3 4 4 3 2 1 0 4 4 5 6 7 8 4 f c >= 0 f + c >= base - 1 Intersección de ambas condiciones Si sumamos las dos intersecciones, obtenemos la figura que queremos dibujar. En otras palabras, si una celda cumple la condición de la primera intersección o de la segunda, la tenemos que pintar, si no, hay que dejarla en blanco. Una vez establecido esto, podemos pasar al código.

int base; do printf("ingrese la base (impar): "); scanf("%d", &base); while (base % 2 == 0); int f, c; for (f = 0; f < base; f++) for (c = 0; c < base; c++) if (((f <= c) && (f + c < base)) ((f + c >= base 1) && (f >= c))) printf("*"); else printf(" "); printf("\n"); En este caso el código es muchísimo más corto, pero tal vez un poco más difícil de plantear en cuando a las condiciones de dibujo. Uno en general termina eligiendo el método con el cual se siente más cómodo, sea uno u otro.