You are on page 1of 16

Estructuras de control de un Programa Introducción

Los programas que permiten resolver problemas de tipo general necesitan la capacidad de controlar cuáles son las sentencias que se tienen que ejecutar y en qué momento, solo en problemas sencillos como los que habías visto hasta ahora, las instrucciones se ejecutan una detrás de la otra. Las estructuras o construcciones de control controlan la secuencia o flujo de ejecución de un programa o función. Las estructuras de control permiten combinar sentencias o instrucciones sentencias individuales en una simple unidad lógica con un punto de entrada y un punto de salida. Las estructuras de control se dividen en tres grandes categorías en función del flujo de ejecución: secuencial, selección y repetición. Secuencial: las instrucciones se ejecutan una tras otra. Una sentencia compuesta es un conjunto de sentencias encerradas entre llaves que se utiliza para especificar un flujo secuencial, esto es, el control fluye de la sentencia1 a la , sentencia2 y así sucesivamente. { sentencia1; sentencia2; :::::: sentenciaN;

}

Selectivas o Condicionales: se utilizan para que el programa elija entre cursos de acción Condicionales: alternativos. Repetitivas: permiten repetir conjuntos de instrucciones. Las instrucciones se ejecutan un : número determinado o indeterminado a priori de veces. Una condición de control establece las veces que se ejecuta una instrucción repetitiva.

Estructuras Selectivas Objetivo Terminales
Al culminar esta parte de la unidad didáctica deberás estar en la capacidad de: • Aplicar las diferentes estructuras de control selectivas, de la manera más adecuada, como elementos para el desarrollo de programa de computación eficiente. programas

Objetivos Específicos
• • Identificar los componentes esenciales de las estructur de control selectivas. estructuras Clasificar los diferentes tipos de estr estructuras de control selectivas.

Identificar la condición a evaluar, según la cual se indicará las instrucciones a ejecutarse realmente. • Escoger la estructura de control selectiva pertinente para la elaboración de programas de computación eficiente. Sentencia if

La sentencia if permite elegir entre dos alternativas en base al valor de una expresión booleana. Sintaxis:

Donde, <Explogica> es una expresión booleana y <sentenciaX> puede ser una sola sentencia o un bloque de sentencias (sentencia compuesta). Funcionamiento: Cuando el compilador encuentra la palabra reservada if, sabe que tiene que evaluar la , expresión lógica que se encuentra dentro del paréntesis que está a continuación de la palabra if. Si el resultado de la expresión es verdadero (valor distinto de cero), entonces se ejecuta . la(s) sentencia(s) que sigue(n) inmediatamente, en caso contrario no se ejecutan esas instrucciones sino las que se encuentran luego de la palabra reservada else si está presente pero si no está continúa con la ejecución de las instrucciones que se encuentran luego de dicha Sentencia if. Sentencia if básica La siguiente figura muestra un diagrama de flujo de ejecución de una sentencia if básica.

Ejemplo de una sentencia if básica: Instrucción o sentencia que muestra un mensaje si un número es divisible por otro. if (n % d == 0) cout << n << “Es divisible por” << d << end; Nota: Sólo se imprimirá el mensaje en caso que el módulo o resto de dividir el valor de la variable n entre el valor de la variable d sea 0, o sea, que la división sea exacta, en caso contrario ejecuta las instrucciones que estén luego de esta instrucción. Toda la condición tiene que ir entre paréntesis. A menos que sea estrictamente necesario, evite usar otros paréntesis que solo le traerán complicaciones, para ello debe repasar la prioridad de los operadores. Sentencia if doble: if-else La siguiente figura muestra un diagrama de flujo de ejecución de una sentencia if doble

. Ejemplo de una sentencia if doble: Instrucción o sentencia que muestra un mensaje si un estudiante está aprobado o no. if (nota >= 48) cout << cout << end; Nota: Se imprimirá el mensaje Aprobado en caso que la condición resulte verdadera, en caso contrario se aparecerá No aprobado. “Aprobado”; else cout << “No aprobado”;

Importante: En el ejemplo anterior, la instrucción cout<<endl; se ejecutará : independientemente del resultado de la expresión, pues está fuera del condicional. Sentencias if-else anidadas Hasta ahora, en las sentencias if, se han implementado decisiones que implican una o dos alternativas, pero en ocasiones se requiere programar decisiones que necesitan varias alternativas. Una sentencia if es anidada cuando la secuencia de la rama verdadera o la rama falsa es a su vez una sentencia if, la cual también puede contener otra instrucción if y así sucesivamente. Una sentencia if anidada se puede utilizar para implementar decisiones con varias alternativas. Sintaxis:

Ejemplo de una sentencia if anidada: Extracto de programa que muestra un mensaje en anidada: función de la nota obtenida de un estudiante.

Las sangrías que se observan en el ejemplo anterior en algunos casos son importantes pero en esta oportunidad se haría más legible el código si no se colocan dichas sangrías, como sigue:

Nota: El criterio que se debe seguir para decidir el anidamiento o no de estructuras l estructu selectivas es la LEGIBILIDAD DEL CÓDIGO. Comparación de Sentencias if anidadas y secuencias de sentencias if Los programadores tienen dos alternativas: 1. Usar una secuencia de sentencias if ó 2. Usar una única sentencia if anidada. Por ejemplo:

Alternativa 1 Alternativa 2 Las dos alternativas son relativamente equivalentes, pero la alternativa 2 es más ineficiente que la alternativa 1, pues en el caso que x sea un número mayor a cero la alternativa 1 se ejecuta en menos tiempo, ya que no se ejecuta el resto de la sentencia, mientras que en la otra, se tienen 3 instrucciones if, por lo cual se ejecuta la evaluación de las 3 condiciones, aún cuando se sabe que si es mayor que cero no se cumplirán ninguna de las restantes condiciones. : Nota: Sólo en algunos casos, podría ser conveniente usar secuencias de if en lugar de if anidados Sentencia switch: condiciones múltiples La sentencia switch es una instrucción en C++ que se utiliza para seleccionar una de entre múltiples alternativas. La sentencia switch es especialmente útil cuando la selección se basa sentencia en el valor de una variable simple discreta o de una expresión simple denominada expresión de control o selector. Sintaxis:

Diagrama de flujo de una sentencia switch:

Funcionamiento de una sentencia switch: La expresión selectora o selector se evalúa y se compara con cada una de los valores expresados luego de cada etiqueta case. Si coincide el resultado del selector con algún valor . case, entonces se inicia la ejecución de las instrucciones para ese caso y continuará ejecutando el resto de la sentencia switch hasta que se encuentre con el fin de la misma o con una sentencia break. Si ningún valor coincide, no se ejecutará ninguna acción a menos que se . especifique una acción por defecto (omis (omisión) en la etiqueta default. Nota: El valor de la expresión de control o selector tiene que ser de tipo ordinal (int o : char), no puede ser float, ni double, ni mucho menos string. El tipo de dato de cada valor case debe ser del mismo tipo que la expr expresión de control o selector. Y cada valor tiene que ser único (diferente de los otros). Se recomienda usar la instrucción break; luego de las sentencias a ejecutar por cada valor que pueda tomar la expresión de control o selector para que la sentencia switch sea más eficiente, esto es, para que no se ejecuten acciones innecesarias innecesarias. Importante: Aunque la etiqueta default es opcional, se recomienda su uso a menos : que se esté absolutamente seguro de que todos los valores del selector estén incluidos en las etiquetas case. as Ejemplo de sentencia switch:

¿Será que si olvido la instrucción break; me da error? ¿Si no da error entonces no hace falta colocarlo? Importante: Si se olvida una instrucción break; en una sentencia switch, el compilador no emitirá un mensaje de error, ya que sintácticamente está correcta, pero no realizará las tareas previstas. Complete esta información revisando el libro de Joyanes, recomendado para este curso. Pags. 151-175.

Estructuras Repetitivas Objetivos Terminales
Al culminar esta otra parte de la unidad didáctica deberás estar en la capacidad de: • Identificar las diferentes estructuras de control repetitivas como elementos para el desarrollo de un programa de computación. • Aplicar la estructura de control repetitiva adecuada para la elaboración de programas de computación eficiente.

Objetivos Específicos
• • • • Identificar los componentes esenciales de las estructuras de control repetitivas. Clasificar los diferentes tipos de estructuras de control repetitivas. Identificar la condición de terminación del bucle o estructura repetitiva y las instrucciones que se requieren repetir realmente. Escoger la estructura de control repetitiva adecuada para la elaboración de programas de computación eficiente. .

Introducción
Una de las ventajas más resaltantes de las computadoras es precisamente la posibilidad de ejecutar una tarea muchas veces con gran velocidad, precisión y fiabilidad, lo cual le facilita la labor de los humanos, para los cuales las tareas repetitivas, se les hace tedioso y hasta difícil. En este tema se estudian las estructuras de control, tanto selectivas (alternativas o de decisión) como repetitivas o iterativas, también llamadas bucles o ciclos, que realizan la repetición o iteración de acciones. C++ soporta tres tipos de estructuras de control repetitivas: While, for y do-while. Una estructura de control repetitiva consta de un cuerpo (sentencia o grupo de sentencias que se repite) y una condición que es la que controla la cantidad de veces que se ejecuta la sentencia o grupo de sentencias. Los dos aspectos más importantes a considerar cuando se va a diseñar un bucle o ciclo son: ¿Cuál es cuerpo del bucle? y ¿Cuántas veces se repetirá o se iterará el cuerpo del bucle?

Esquema de este tema
1. La sentencia While 1.1. Definición 1.2. Sintaxis 1.3. Funcionamiento o comportamiento del computador ejecutando un bucle while 1.4. Modalidades de While 1.4.1. Controlados por un contador 1.4.2. Controlados por Centinela 1.4.3. Controlados por Indicadores (banderas) 2. Repetición: El bucle For 2.1. Definición 2.2. Sintaxis 2.3. Funcionamiento o comportamiento del computador ejecutando un bucle for 2.4. Consideraciones específicas del bucle for 2.5. Precauciones en el uso del For 3. Repetición: El bucle Do-While 3.1. Definición 3.2. Sintaxis 4. Comparación de bucles While, For y Do-While

Desarrollo de los contenidos
1. La sentencia While 1.1. Definición Es un bucle pretest, ya que se evalúa la condición antes de que se ejecute el cuerpo del bucle, por ello puede ejecutarse 0 o más veces el cuerpo del bucle, así pues, la condición del bucle (expresión lógica) que controla la cantidad de veces que se repetirá la sentencia o grupo de sentencias está delante del cuerpo del bucle. En el libro base, en la Figura 5.1 podrás observar el diagrama de flujo del bucle While. 1.2. Sintaxis while (condición) //encabezado, recuerda que los encabezados no terminan en ; sentencia; //cuerpo que contiene una sola sentencia o instrucción while (condición) { /*Lleva llave de apertura y de cierre porque el cuerpo está formado por más de una sentencia o instrucción, sino se coloca asume que repetirá una sola sentencia */ sentencia1; sentencia2; :::::: sentenciaN;

} Donde: while es la palabra reservada para indicar que se va a usar un bucle pretest, le indica al procesador que ejecute el cuerpo del bucle repetidas veces, siempre y cuando la condición sea verdadera (true). condición, es la expresión lógica que va a controlar la cantidad de veces a repetir o iterar el cuerpo del bucle y se evalúa al inicio, o sea, que puede no llegar a ejecutarse el cuerpo del bucle, ni siquiera una vez. sentencia, instrucción simple o compuesta que se requiere repetir o iterar, esta puede ser una estructura secuencial, selectiva u otra estructura de control repetitiva. 1.3. Funcionamiento o comportamiento del computador ejecutando un bucle while 1. Evalúa la condición: • Si la condición es verdadera: a) Ejecuta la sentencia o grupo de sentencias especificada(s) y b) vuelve al paso 1, o sea, a evaluar la condición nuevamente. • Si la condición es falsa, transfiere el control a la siguiente sentencia o instrucción después del bucle while. Nota: La condición en el bucle while, generalmente, contiene una o más variable(s) de control que se le llama(n) así porque es, precisamente, lo que se evalúa, es por ello que tiene(n) que ser inicializada(s) o leída(s) antes del encabezado del bucle o ciclo while y actualizada en el cuerpo del bucle o ciclo while para garantizar la ejecución adecuada de dicha estructura repetitiva. Si la variable control no se actualiza en el cuerpo del bucle while, este se ejecutará por siempre, ya que la condición nunca llega a ser falsa y se le denomina bucle infinito. Esto no debe ocurrir en una buena programación 1.4. Modalidades de While 1.4.1. Controlados por un contador Se usa, cuando se requiere repetir el cuerpo del bucle un número conocido de veces, para ello se utilizan los operadores de incremento y decremento, es importante la inicialización de la variable de control (contador), generalmente en 0, la prueba o evaluación del contenido de dicha variable y la actualización de ese contador dentro del bucle while, para asegurar la ejecución adecuada de esta estructura. Ejemplo: //Programa que suma n cantidad de números enteros dados por el usuario #include <iostream> /* instrucción del preprocesador que incluye la librería que contiene los objetos para realizar las operaciones de entrada (input) y salida (output), i/o */

using namespace std; /*espacio de nombres necesario para las librerias estandar de C++ */ int main(){ int n, cont, num, total; //declaracion de variables cont = total = 0; /* inicialización tanto de la variable control como de la

variable donde se guardará el valor acumulado de los números introducidos, ya que como la suma es una operación que se realiza sobre la misma variable, se requiere garantizar que el resultado sea el esperado, recuerde que al declarar la variable se reserva un espacio en memoria que puede contener cualquier valor y perturbaría la solución, esto es, si la variable total tiene 0 al momento de sumar el primer número dado por el usuario, por ejemplo 2, el resultado será 2 pero sino puede ser cualquier otro valor */ cout << “Indique la cantidad de numeros a procesar: ”; cin >> n; while (cont < n){ /* se ejecuta si la variable de control o contador (cont) es menor que el valor dado en n */ cout << “Numero a sumar: ”; // muestra el mensaje por pantalla cin >> num; // lee y guarda en num el número dado por teclado total += num; /* suma el valor que tenía la variable total con el valor que tiene la variable num y el resultado se guarda en la variable total*/ cont ++; /* incrementa en 1 la variable contador (cont) y luego vuelve a evaluar la condición para saber si continua o termina la repetición */ } /*Cuando la condición se hace falsa (cont es igual a n), termina la repetición del cuerpo del bucle y se ejecuta la siguiente instrucción después del while */ cout << “La suma total de los numeros dados es: ” << total << endl; system(“PAUSE”);//Espera por una tecla mientras muestra la salida return 0;//indica que ocurrió todo bien, que tuvo un final exitoso. }//fin del main Ejecución y prueba: Si se tienen como entrada los números: 6, 2 y 4, la corrida será la siguiente:

1.4.2. Controlados por Centinela Se usa cuando no se conoce con exactitud la cantidad de veces a repetir el cuerpo del bucle, ya que hay muchos datos a procesar manualmente. Se solicita al usuario introducir un único dato antes de la evaluación de la condición y se le indica un valor que señale el último dato o el fin de ingreso de datos, a este se le denomina valor centinela. La condición evalúa cada dato y cuando se lee el valor centinela se sale del ciclo o bucle while. El valor centinela tiene que ser un valor que no tenga posibilidad de ser confundido con los datos de entrada del usuario para que pueda servir, realmente, para terminar el ciclo o bucle while y preferiblemente si es de tipo char o int para que sea fácil de comparar. Ejemplo: //Programa que suma números enteros positivos, hasta que el usuario indique 0 #include <iostream> // libreria para realizar las operaciones de i/o using namespace std; //espacio de nombres std int main(){ int num, total; //declaracion de variables total = 0; // inicialización de la variable acumulador de los números

cout << “Indique un numero entero positivo a sumar o 0 para salir: ”; cin >> num; while (num != 0) { /* se ejecuta si la variable de control o centinela es diferente de 0 (cero) */ total += num; /* suma el valor que tenía la variable total con el valor que tiene la variable num y el resultado se guarda en la variable total */ cout << “Otro Numero a sumar o 0 para salir: ”; cin >> num; /* lee y guarda en num el número dado por teclado y luego vuelve a evaluar la condición para saber si continua o termina la repetición */ } /*Cuando la condición se hace falsa (num es igual a 0), termina la repetición del cuerpo del bucle y se ejecuta la siguiente instrucción después del while */ cout << “La suma total de los numeros dados es: ” << total << endl; system(“PAUSE”);//Espera por una tecla mientras se muestra la salida return 0;//indica que ocurrió todo bien, que tuvo un final exitoso. }//fin del main Ejecución y prueba:

Si se tienen como entrada los números: 6, 2 y 4, la corrida será la siguiente:

1.4.3. Controlados por Indicadores (banderas) Se usa cuando no se conoce con exactitud la cantidad de veces a repetir el cuerpo del bucle, y se utiliza una variable o expresión de tipo bool o lógica para controlar la ejecución del bucle o ciclo while. El valor indicador se inicializa (normalmente a falso “false”) antes de la entrada del bucle y se le cambia el valor (normalmente a verdadero “true”) cuando un suceso específico ocurre en el cuerpo del bucle o ciclo. Un bucle o ciclo controlado por indicador o bandera, se ejecuta mientras se mantiene el valor inicial del indicador y se termina cuando se cambia su valor. Ejemplo: //Programa que suma tantos números como desee el usuario #include <iostream> /* instrucción del preprocesador que incluye la librería que contiene los objetos para realizar las operaciones de entrada y salida */ using namespace std; /*espacio de nombres necesario para las librerias estandar de C++ */ int main(){ //declaracion de variables int num, total, resp; bool fin; cout << “Desea procesar datos 1-Si y 0-No: ”; cin >> resp; fin = resp == 0; /* inicialización de la variable de control, ya que permitirá indicar si se ejecuta o no el cuerpo del bucle, esto es, si el usuario responde 1 (Si), la variable fin será igual a false (falso) y si responde 0 (No), la variable fin guardará true (verdadero)*/ total = 0; // inicialización de la variable acumulador de valores while (!fin){ // se ejecuta si la variable control o indicador (fin) es falso cout << “Numero a sumar: ”; //muestra el mensaje por pantalla cin >> num; //lee y guarda en num el número dado por teclado total += num; /* suma el valor que tenía la variable total con el valor que tiene la variable num y el resultado se guarda en la variable total */ cout << “Desea procesar otro dato 1-Si y 0-No: ”; cin >> resp; fin = resp == 0; // actualiza la variable indicador o bandera } /* Cuando la condición se hace falsa, o sea, fin es verdadero (true) pues el usuario respondió 0 (No), termina la repetición del cuerpo del bucle y se

ejecuta la siguiente instrucción después del while */ cout << “La suma total de los numeros dados es: ” << total << endl; system(“PAUSE”);//Espera por una tecla mientras se muestra la salida return 0;//indica que ocurrió todo bien, que tuvo un final exitoso. }//fin del main Ejecución y prueba: Si se tienen como entrada los números: 6, 4 y 2, la corrida será la siguiente:

2. Repetición: El bucle For 2.3. Definición Es el bucle o ciclo más adecuado cuando se conoce a priori la cantidad de veces a ejecutarse el cuerpo del bucle o ciclo, es mejor que implementar un bucle while controlado por contador, ya que ofrece más control sobre la inicialización, evaluación e incremento de la variable control (contador) del bucle o ciclo. La sentencia o grupo de sentencias se ejecuta una vez por cada valor de un rango especificado por anticipado. 2.4. Sintaxis for (inicializacion; condicion; incremento o decremento){ /* El cuerpo del bucle va entre llaves cuando está formado por más de una sentencia o instrucción, sino se coloca entre llaves se asume que repetirá una sola sentencia */ sentencia1; sentencia2; :::::: sentenciaN; } Donde: for, es la palabra reservada que indica al computador que se van a repetir un numero conocido de veces una o más instrucciones. Inicialización, consiste en declarar y colocar un valor inicial a la(s) variable(s) de control del bucle o ciclo for, generalmente 0, aunque puede ser en otro valor. Condición, es una expresión lógica que controlará la cantidad de repeticiones.

Incremento, es una expresión aritmética, usualmente se incrementa o se decrementa en 1, pero no siempre es así. 2.5. Funcionamiento o comportamiento del computador ejecutando un bucle for a) Declara e inicializa la(s) variable(s) de control del bucle o ciclo for b) Evalúa la condición: • Si la condición es verdadera ejecuta el cuerpo del bucle y luego, actualiza la(s) variable(s) de control y vuelve al paso b) • Si la condición es falsa, transfiere el control a la siguiente sentencia o instrucción después del bucle for. 2.6. Consideraciones específicas del bucle for • ANSI C++ Estandar requiere que la(s) variable(s) de control (contador(es)) sea(n) declarada(s) en la parte de inicialización del encabezado para que sea(n) local(es) al bloque del bucle o ciclo for. • De igual modo permite que la(s) variable(s) de control pueda(n) ser actualizada(s) con valores diferentes de 1, podría ser de dos en dos (n+=2) o con una multiplicación (n*=2). • Se puede utilizar más de una variable de control. • Generalmente, la(s) variable(s) de control es (son) de tipo int pero pueden ser de tipo double y por consiguiente se incrementarían en un valor decimal. • Tampoco se requiere que la inicialización de la(s) variable(s) de control sea una constante, puede ser cualquier expresión que desee. Naturalmente que cuando la variable no sea de tipo ordinal, se tendrán menos garantías de precisión. 2.7. Precauciones en el uso del For • Hay que asegurarse de que la expresión de inicialización, la condición del bucle y la expresión de incremento hagan que la condición del bucle se convierta en falsa en algún momento, para que no se quede en un bucle o ciclo infinito. • No se debe modificar el valor de la(s) variable(s) de control dentro del cuerpo del bucle porque cambiará el número de repeticiones predefinido y puede producir resultados imprevistos. Hacer lo anterior, se considera una mala práctica de programación, ya que la estructura for, tiene como ventaja, precisamente, controlar todas las tareas necesarias para que se ejecute una sentencia o un grupo de sentencias un número de veces conocido de antemano. Ejemplo: //Suma de tres números enteros #include <iostream> // libreria para realizar las operaciones de i/o using namespace std; //espacio de nombres std int main(){

int num, total; //declaracion de variables total = 0; // inicialización de la variable acumulador de los números for (int i = 0; i < 3 ; i++){ /* declara la variable de control i y la inicializa en 0, luego evalua que sea menor que 3 para empezar a ejecutar el cuerpo del bucle o terminar si no se cumple */ cout << "Numero a sumar: "; //muestra este mensaje en pantalla cin >> num; //lee y guarda en num el número dado por teclado total += num; //acumula en total el valor guardado en num /* incrementa automáticamente en 1 la variable de control y vuelve a evaluar la condición, para continuar ejecutando el cuerpo del bucle si resulta verdadera (true) o terminar el bucle o ciclo si es falsa (false) */ } /* cuando la condicion se hace falsa, o sea, i es igual a 3, ejecuta la siguiente instrucción: */ cout << "La suma total de los numeros dados es: " << total << endl; system("PAUSE");//Espera por una tecla mientras se observa la salida return 0;//indica que ocurrió todo bien, que tuvo un final exitoso. }//fin del main Ejecución y prueba: Si se tienen como entrada los números: 6, 2 y 4, la corrida será la siguiente:

c) Repetición: El bucle Do-While • Definición Es el bucle o ciclo que se utiliza cuando se tiene la seguridad de que el cuerpo del bucle se requiere ejecutar al menos una vez. • Sintaxis do{ //encabezado, recuerda que los encabezados no terminan en ; sentencia(s); //cuerpo que contiene una o varias sentencia(s) o instrucción(es) } while (condición);

Donde: do, es la palabra reservada para indicar que se va a usar un bucle do-while, le indica al procesador que ejecute todo lo que está entre las llaves y que se va a repetir dicha ejecución, mientras la condición a evaluar al final sea verdadera (true). while (condición), es la expresión lógica que va a controlar la cantidad de veces a repetir o iterar el cuerpo del bucle do-while y va al final de la estructura para asegurar que el cuerpo del bucle o ciclo se ejecute al menos una vez. sentencia(s), instrucción(es) simple(s) o compuesta(s) que se requiere(n) repetir o iterar, esta(s) puede(n) ser de tipo secuencial, selectiva o repetitiva.

d) Comparación de bucles While, For y Do-While
while La condición se chequea antes de entrar al bucle, si la evaluación resulta verdadera se ejecutan las sentencias. El bucle finaliza cuando la condición es falsa Se ejecuta cero o más veces, por ser de tipo pretest for Se recomienda cuando el número de repeticiones se conoce por anticipado. Es controlado por un contador. En una misma línea contiene varias instrucciones. do-while Es adecuada cuando se debe asegurar que al menos se ejecute el bucle una vez. La condición del bucle se chequea después de que se ha(n) ejecutado la(s) sentencia(s). Las sentencias se repiten mientras la condición sea verdadera.