Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
Como vimos anteriormente, en nuestros algoritmos se pueden producir diferentes variantes en el conjunto de sentencias que se ejecutan para diferentes entradas. Según preguntas y evaluaciones sobre los valores de variables, el flujo de ejecución toma un camino u otro. Para poder crear un programa, necesitamos tener un conjunto de instrucciones o estructuras que nos permitan controlar el flujo de ejecución; en otras palabras, necesitamos ser capaces de controlar las acciones del programa que estamos creando y codificar esas preguntas o evaluaciones sobre los datos de nuestro programa. De manera general, al desarrollar software, tendremos tres componentes: Lección 2 de 7 Unidad 1: Estructuras de control Evento de entrada: lo que desencadena el procesamiento. Puede consistir en alguna acción del usuario, por ejemplo, hacer clic en un botón o escribir una palabra, o algún cambio en el ambiente, como la temperatura, o incluso algún mensaje de otro programa. 1 Proceso: lo que nuestro software está programado para hacer, de acuerdo con el evento de entrada. Nuestro software hará lo que 2 https://updf.com Supongamos que tenemos un programa que cambia el color de una pantalla cuando hacemos clic en un botón: el evento de entrada sería el clic en el botón, el proceso sería el cambio de color y el resultado sería el nuevo color mostrado en pantalla. Ahora bien, ¿cómo sabe el programa que tiene que cambiar el color cuando se hace clic en un botón y no en otro lado? ¿Cómo sabe que tiene que cambiar el color de la pantalla y no de otra cosa? Este tipo de decisiones tienen que estar plasmadas en el código y no dejar nada librado al azar. Todo esto se logra mediante las estructuras de control que veremos a continuación. Tema 1: Condicionales indiquen los algoritmos que codificamos. Salida: el resultado del proceso una vez que los algoritmos se ejecuten sobre la base de las entradas proporcionadas por el evento. 3 Los ejemplos en este módulo son codificados en C++, pero las estructuras de control son comunes en todos los lenguajes. https://updf.com Los condicionales son instrucciones que evalúan la veracidad de una sentencia. Evalúan una expresión booleana (una proposición lógica) y, según el valor booleano (verdadero o falso) resultante, deciden si ejecutan o no una determinada sección de código. A estas secciones se las llama “bloques de código”. La sentencia if If establece la evaluación de una variable u operación cuyo valor o resultado es de tipo booleano, es decir, verdadero o falso. En el caso de que sea verdadero, ejecuta una sección de código, el bloque if. Si, por el contrario, es falso, no la ejecuta y pasa a la siguiente sección de código. Figura 1: Diagrama de flujo de if https://updf.com Fuente: elaboración propia. Veamos un ejemplo: Figura 2: Condicional if (en C++) https://updf.com Fuente: elaboración propia. En la imagen anterior, podemos ver cómo se define un condicional en el lenguaje C++. En primer lugar, definimos una variable booleana llamada “isAnIfStructure” y le asignamos el valor “true”. Luego, utilizamos la palabra clave “if” que le indica al programa que evalúe la variable “isAnIfStructure” y, en el caso de que sea verdadera, ejecute el bloque con el código “cout << "¡Es una estructura IF!" << endl;”. Esto último muestra un mensaje "¡Es una estructura IF!". Como “isAnIfStructure” es verdadero, el código dentro de la sentencia if se va a ejecutar y el sistema imprime lo que está entre comillas. El resultado es el siguiente: https://updf.com Figura 3: Resultado de condicional if (en C++) Fuente: elaboración propia. En la figura 3 se puede ver el resultado de ejecutar el archivo “a.out”. Dicho archivo se genera luego de compilar el algoritmo de la figura 2. De ser falso el valor de “isAnIfStructure”, la sentencia cout no se ejecuta y el mensaje no se muestra en pantalla. La sentencia else Else puede considerarse una extensión de la sentencia if y significa “de lo contrario”. Permite la ejecución de un conjunto de sentencias en caso de que la expresión booleana del if sea falsa, esta sección se llama “bloque else”. https://updf.com Figura 4: Diagrama de flujo de if-else Fuente: elaboración propia. Para el ejemplo del if anterior, existe la posibilidad de indicar una sección de código para ejecutar en el caso de que “isAnIfStructure” no sea verdadera utilizando la palabra “else”: https://updf.com Figura 5: Condicional con else (en C++) Fuente: elaboración propia. La palabra “else” especifica que, si “isAnIfStructure” no es verdadero, se ejecute el código que corresponde al bloque else. En el ejemplo de la figura anterior, ese código es “cout << "¡Es una estructura IF-ELSE!" << endl;”. Veamos el resultado: Figura 6: Resultado de condicional con else (en C++) https://updf.com Fuente: elaboración propia. Es importante destacar que la sentencia else solo puede utilizarse si una sentencia if ha sido declarada anteriormente. La combinación else-if Hasta ahora, la sentencia if y la sentencia else pueden ser de gran utilidad, pero ¿qué sucede si necesitamos evaluar más de dos condiciones? Por ejemplo, debemos realizar un programa que muestre en pantalla el nombre “Juan” si el valor de una variable es igual a 0; si no es igual a 0 pero es igual a 1, deberá mostrar el nombre “Lucas”. Por último, si es distinto de 0 y de 1, deberá mostrar “Error”. El código sería como el siguiente: Figura 7: Condicional con else-if (en C++) https://updf.com Fuente: elaboración propia. El símbolo “==” se utiliza cuando se quiere comparar que el valor de una variable sea igual a otro determinado valor. No debemos confundirlo con “=”, ya que este símbolo no compara valores, sino que los asigna a la variable. No resulta ser una sentencia en sí misma, sino que consiste en agregar un bloque if como bloque else. Por lo tanto, surge de combinar las sentencias if y else anidado bloques. Anidamiento de sentencias El anidamiento es la práctica de incorporar bloques de código dentro de otros. Cada lenguaje tiene su sintaxis para identificar un bloque. En C, C++ https://updf.com y Java se identifican encerrando las sentencias que conforman el bloque entre llaves (“{” para indicar el inicio del bloque y “}” para indicar el fin). De este modo, dentro de un bloque if o else, podemos anidar otros bloques if o else. Es importante notar que else-if es posible gracias a esta característica. Figura 8: Anidamiento de bloques (en C++) Fuente: elaboración propia. Observa que, en el ejemplo de la figura 8, el primer bloque if además de la sentencia de salida por consola (cout) tiene otro bloque if anidado. Lo mismo podríamos hacer en el bloque else en caso de ser necesario. La sentencia switch https://updf.com Con switch, podemos evaluar el valor de una variable o el resultado de una expresión de cualquier tipo y, de acuerdo con este, ejecutar cierta sección del código. Es similar a else-if, ya que es útil cuando queremos comparar el valor de una variable o resultado con más de una opción. Su principal característica es que permite establecer muchas opciones para el flujo de ejecución a diferencia de la sentencia if, en donde solo hay dos opciones. Figura 9: Diagrama de flujo de switch Switch y else-if cumplen la misma función. Siempre es recomendado utilizar switch en vez de else-if debido a su simplicidad. https://updf.com Fuente: elaboración propia. Por ejemplo, tenemos que codificar un algoritmo que, dada la variable “intNumber”, pueda mostrar su equivalente en números romanos. El algoritmo debe funcionar para los números entre el 1 y el 5. Figura 10: Sentencia switch (en C++) https://updf.com Fuente: elaboración propia. Switch permite agregar una opción por defecto (por default), es decir, una opción que se ejecute cuando ninguna de las demás es verdadera (también puede ser nombrada “opción por defecto”). Esto permite responder en caso de que el valor de la variable no correspondacon ninguna de las opciones esperadas. Para el ejemplo, podríamos imprimir un mensaje que indique que el valor evaluado por el switch no está dentro de los esperados: https://updf.com Figura 11: Switch con default (Java) Fuente: elaboración propia. La cláusula default siempre va como opción final del switch aunque no es obligatoria. https://updf.com Figura 12: Resultado de switch para el número 4 (en C++) Fuente: elaboración propia. Tema 2: Ciclos o bucles Un ciclo o bucle es el acto de repetir un proceso con la intención de alcanzar una meta, objetivo o resultado deseado. En programación, a dicho proceso se lo denomina “iteración”. Técnicamente hablando, en un ciclo o bucle, una sección de código se repite de acuerdo con una condición. Son similares al if, pero tienen la capacidad de ejecutar varias veces el mismo bloque de código. Son muy útiles cuando queremos, por ejemplo, recorrer una lista de elementos o ejecutar una misma sección de código una cierta cantidad de veces. El bucle while https://updf.com Es un bucle que permite la repetición de la ejecución de un bloque de código determinado mientras (while, en inglés) se cumpla una condición determinada. Dicha condición es una expresión booleana. Figura 13: Diagrama de flujo de un while Fuente: elaboración propia. Una característica de la sentencia while es que, si en la primera evaluación de la expresión booleana el resultado es falso, el bloque no se ejecuta https://updf.com ninguna vez. Por ejemplo, queremos mostrar los números del 0 al 10. ¿Cómo podría codificarse? Esta sería una de las formas: Figura 14: Bucle while (en C++) Fuente: elaboración propia. Veamos el código anterior en más detalle: Figura 15: Bucle while en detalle (en C++) https://updf.com Fuente: elaboración propia. El bucle do-while Este bucle es similar al bucle while y permite la repetición de la ejecución de un bloque de código determinado mientras se cumpla una condición determinada. La única diferencia es que la expresión booleana se evalúa al final de cada repetición (iteración). Figura 16: Diagrama de flujo del do-while https://updf.com Fuente: elaboración propia. Podés observar que, a diferencia del while, en el bucle do-while el bloque de código se ejecuta al menos una vez (invariablemente), ya que es al final de cada iteración cuando se evalúa la condición que determina el final del ciclo. La siguiente sería una forma de imprimir los números del 0 al 10 con un do- while: https://updf.com Figura 17: Bucle do-while (en C++) Fuente: elaboración propia. Es muy similar a while, pero con la palabra clave “do” y luego el código que se repite. La condición de repetición se indica al final. El bucle for Este bucle también permite la repetición de una sección de código de acuerdo con el valor de una variable o expresión booleana, pero teniendo cierto control y conocimiento sobre la cantidad de iteraciones. En el caso de que la expresión sea verdadera, el código se repite. En el caso de que sea falsa, el código no se repite y pasa a la línea siguiente. https://updf.com Con un for, es necesario tener un valor inicial, un valor final de referencia y una expresión que indique cómo será el paso de una iteración a la siguiente. Por ello, una sentencia for está compuesta por tres partes: Volvamos a tomar ejemplo en el que mostramos los números del 0 al 10: ¿cómo podría codificarse con un for? Esta sería una de las formas: Figura 18: Bucle for (en C++) Fuente: elaboración propia. Inicialización de una variable que utilizaremos en la condición: incondicionalmente, se ejecuta solo una vez al principio del ciclo. Indicación de la condición por la cual finalizará el bucle: se evalúa esta expresión al comienzo de cada iteración. Modificación de la variable: se ejecuta al final de cada iteración. https://updf.com Vamos a describir el código anterior en partes. Veamos con más detalle la primera línea: Figura 19: Bucle for en detalle (en C++) Fuente: elaboración propia. Como se puede ver en la figura anterior, en el bucle for podemos definir una variable, utilizarla como punto de partida y como condición para decidir si el código repite la ejecución (conocida como “condición de repetición” o “condición de corte”) y, también, aumentar el valor de dicha variable al final de cada repetición. https://updf.com El bucle for-each For-each es una simplificación de la declaración de un for en el caso de que necesitemos recorrer una lista de elementos. La función for-each, qué significa para “cada uno”, establece que, por cada elemento presente en una lista, se ejecute un bloque de código. Por ejemplo, ¿cómo podríamos imprimir en pantalla una lista de palabras? Veamos el siguiente código: En la mayoría de los casos, se utilizaba un for para recorrer una lista de elementos, por lo que los lenguajes de programación con el tiempo agregaron el for-each. https://updf.com Figura 20: Bucle for-each (en C++) Fuente: elaboración propia. For-each es mucho más simple que un for regular debido a que no necesitamos establecer la condición de repetición. Se evaluará la variable “listaDePalabras”, y, a medida que se va recorriendo la lista, la variable “palabra” va tomando el valor de cada uno de los ítems de dicha lista. Tema 3: Funciones y funciones anónimas Hay muchas formas de codificar un sistema, y algo particular sobre el desarrollo de software es que no existe una única forma de construir ese sistema. Ahora bien, sí hay lineamientos y guías para que ese desarrollo pueda ser reutilizado (ahorrando costos, ya que no tenemos que gastar tiempo haciendo las cosas de nuevo) y extensible, que quiere decir que tiene la capacidad de agregar funcionalidad de manera fácil. https://updf.com Uno de esos lineamientos es crear funciones. Las funciones son secciones de código que podemos reutilizar de forma tal que no tengamos que codificar varias veces el mismo código y lo podamos reutilizar. Por ejemplo, si tenemos el requerimiento de informar el área de dos triángulos, podríamos hacerlo así: Figura 21: Mostrar en pantalla el área de dos triángulos (en C++) Fuente: elaboración propia. https://updf.com El resultado sería el siguiente: Figura 22: Resultado de ejecutar el código de la figura 21 Fuente: elaboración propia. En el código de la figura 21, tuvimos que escribir el código de la fórmula dos veces. Ahora bien, ¿qué sucede si tuviésemos que calcular el área para 4 triángulos? Para este ejemplo, solo tenemos que repetir dos líneas de código (cada una con los valores respectivos) por cada uno de los triángulos. Sin embargo, en sistemas más grandes, para resolver una https://updf.com funcionalidad común para ciertos casos, podemos tener muchas más líneas. Una mejor forma de hacer esto es escribiendo el código repetido en una función que resuelva el problema y que podamos invocar cada vez que sea necesario. En nuestro ejemplo, en lugar de escribir el código de la fórmula, invocamos la función y le proporcionamos los datos del triángulo como parámetros de entrada para que realice el cálculo. Figura 23: Función para imprimir el área de un triángulo (en C++) Fuente: elaboración propia. La palabra “void” indica que la función no va a generar ningún resultado para quien la llama, solamente calculará el área e imprimirá el resultado. En caso de que, por ejemplo, la función devuelva algún dato, se debe reemplazar “void” por el tipo de dato correspondiente al que retorna la función. Seguido del nombre de la función, y entre paréntesis, se deben indicar los parámetros de entrada con sus nombres y el tipo de dato https://updf.com correspondiente (en el ejemplo, son base y altura del triángulo). Estos últimos son los valores sobre los cuales se ejecutará el algoritmo de la función. El código para utilizar esta función de la figura 20 sería el siguiente: Figura 24: Uso de función para imprimir el área de un triangulo (en C++) Fuente: elaboración propia.De esta manera, cada vez que necesitemos mostrar por pantalla el área de un triángulo, simplemente invocamos la función con los parámetros de entrada correspondientes a la altura y la base. https://updf.com Si, en lugar de imprimir el área, necesitamos que la función retorne ese valor para que sea procesado en otra parte del código, la función debería especificarse de la siguiente manera: Figura 25: Función para devolver el área de un triangulo (en C++) Fuente: elaboración propia. En este caso, “int” especifica que la función devolverá el área como un valor entero en donde el parámetro es de salida de la función. La sentencia para realizar este retorno es, en C++, “return”, seguida de la variable que contiene el resultado (en este caso, la variable “área”). https://updf.com Figura 26: Uso de función para devolver el área de un triangulo (en C++) Fuente: elaboración propia. Luego de ejecutar el código de la figura 23, las variables “areaT1” y “areaT2” tendrán asignados los valores que retorne la función calcularArea en cada una de las invocaciones. Funciones anónimas Las funciones de tipo anónimas se caracterizan por no poseer un nombre. En nuestro ejemplo anterior, creamos una “función nombrada”, cuya función es calcularArea, que usamos para ejecutarla. https://updf.com Ahora bien, si una función no tiene nombre, ¿cómo la utilizamos? En realidad, estas funciones no se utilizan más que en el lugar donde son definidas, ya que no pueden ser llamadas. El propósito de estas funciones es darle flexibilidad al programador. Sin embargo, como regla general, no deberíamos usarlas salvo que sea estrictamente necesario, porque agregan más complejidad al código. En su lugar, deberíamos utilizar funciones nombradas o no anónimas, como vimos en el ejemplo anterior. Las funciones lambda, a menudo, son enviadas como parámetros de entrada a funciones nombradas para que estas las apliquen a otros datos que procesan. Si la función solo se usa una vez o un número limitado de veces, una expresión lambda puede ser sintácticamente más simple que usar una función con nombre. Figura 27: Ejemplo de función lambda (en C++) Fuente: elaboración propia. Las funciones anónimas son también conocidas como “funciones lambda”. https://updf.com En C++ entre corchetes, podemos definir las variables que podrán ser utilizadas en el cuerpo de la función, entre paréntesis, los parámetros de entrada de la función. Luego, el operador lambda (->) separa la declaración de parámetros de entrada de la declaración del cuerpo de la función. Opcionalmente, se puede especificar el tipo de data que retornará la función. Figura 28: Función lambda como argumento de otra función Fuente: elaboración propia. Este código calcula el total de todos los elementos de la lista. La variable “total” se almacena para poder ser utilizada en la función lambda. La función https://updf.com for_each definida por C++ permite procesar listas de valores. Es importante que sepas que “for_each” tiene tres parámetros de entrada: el primero es el inicio de la lista de valores; el segundo es el final de la lista; y el tercero es la función lambda que se debe aplicar a cada uno de los valores de la lista. Esta función sumará los valores de los elementos. Finalmente, el algoritmo imprime por consola el valor de la variable “total”. Figura 29: Resultado del código de la función 25 Fuente: elaboración propia. Tema 4: Recursividad Existen algunas situaciones en las que necesitamos otro tipo de iteración del código que no se podría hacer con bucles o que sería muy complicado de hacerlo. Una de las opciones ante esos casos es la recursividad. Podemos definir un algoritmo recursivo como aquel que se utiliza dentro de sí mismo. Una función recursiva es la codificación de dicho algoritmo, y se https://updf.com caracteriza por llamarse a sí misma dentro de la propia función. Son comunes para expresar series matemáticas cuando son necesitadas en una aplicación específica. Veamos un ejemplo de un cálculo matemático que podría resolverse mejor con una función recursiva. El más común para entender la recursividad es el cálculo del factorial de un número. Primero, veremos la función calcularFactorial sin recursividad y, luego, la utilizaremos para comparar ambas soluciones. Antes, veamos en qué consiste la función factorial. El factorial de un número es la multiplicación de los números que están comprendidos entre 1 hasta Los algoritmos recursivos deberían utilizarse cuando fuera necesario, ya que consumen más recursos computacionales que los algoritmos que no lo son. https://updf.com dicho número. Para expresar el factorial, se suele utilizar la notación “n!”. Así, la definición es la siguiente: n! = 1 * 2 * 3 * 4 * 5 * ... * (n-1) * n Ejemplo: 4! = 1 * 2 * 3 * 4 = 24 Figura 30: Función calcularFactorial sin recursividad (en C++) https://updf.com Fuente: elaboración propia. En el código de la figura 27 vemos que el cálculo se realiza utilizando un for que acumula las multiplicaciones en la variable “factorial”. El cálculo del factorial de un número, además de como lo vimos anteriormente, podría ser representado de la siguiente forma: n! = n * (n -1)! Para el ejemplo del factorial de 4: 4! = 4 * 3! Por lo tanto, si tenemos una función para calcular el factorial, podremos utilizarla dentro del mismo cálculo y estaríamos generando recursividad. La misma función de la figura 27 pero con recursividad sería la siguiente: Figura 31: Función calcularFactorial con recursividad (en C++) https://updf.com Fuente: elaboración propia. A simple vista, se puede notar lo relativamente más simple que queda la función utilizando recursividad. Es importante que una función de este tipo tenga una condición que finalice la recursión. Dicha condición se llama “condición de corte” y, de no estar presente la función, podría generar un ciclo infinito, por lo que el programa fallaría, ya que nunca se llegaría a la solución esperada. Además, recordá siempre que, dentro de la función, no se debe invocar con los mismos parámetros de entrada, dado que, de este modo, también se ingresaría en un ciclo recursivo infinito. En el ejemplo del factorial, la función “calcularFactorial” se vuelve a invocar siempre con el parámetro “numero - 1”. https://updf.com Podemos definir los datos como hechos que describen sucesos y entidades. En programación, los datos permiten que el programa realice operaciones y genere algo de valor. Para ello, se necesitan operadores que permitan manipular los datos para generar cambios en ellos o para generar nuevos datos. Por ejemplo, en un programa que hace sumas, los datos serían los números y la operación la suma, mientras que el resultado sería el total de esa suma. En general, un programa maneja muchos datos, por lo que, para hacer su manipulación y almacenamiento más sencillos, se utilizan diferentes estructuras, como arreglos, matrices y listas. Tema 1: Operadores Los operadores permiten manipular los datos de un programa. Existen operadores binarios, que necesitan dos variables (como suma y resta), y otros unarios, que pueden manipular solo una variable (como el aumento en uno y el cambio de signo). Lección 3 de 7 Unidad 2: Estructuras de manejo de datos https://updf.com A continuación, vamos a ver los más comunes: Tabla 1: Operadores y sus ejemplos Operador Operación Ejemplo - Cambio de signo (operador unario, aplicado a una sola variable, le cambia el signo) -var1 (cambia el signo que tenía el valor numérico, o sea, es como una multiplicación por -1). + Suma var1 + var2 (el resultado es la suma de la variable “var1” y la variable “var2”). - Resta var1 - var2 (el resultado es la resta de la variable “var1” y la variable “var2”). * Multiplicación var1 * var2 (el resultado es la multiplicación de la variable “var1” con “var2”). / División var1 / var2 (el resultado es la división de “var1” con “var2”). % Módulo var1 % var2(el resultado es el resto de la división de “var1” y “var2”). https://updf.com && AND lógico var1 && var2 (el resultado es verdadero si ambas son verdaderas y falso en todo otro caso). || OR lógico var 1 || var2 (el resultado es falso si ambas son falsas y verdadero en cualquier otro caso). = Asignación de valor var1 = 2 (el resultado es que “var1” ahora tiene el valor 2). == Verifica igualdad var1 == var2 (el resultado es verdadero si “var1” es igual a “var2”, falso en otro caso). != Verifica la no igualdad (distinto) var1 != var2 (el resultado es verdadero si “var1” es distinto de “var2” y verdadero si no lo son). += Suma el valor a la derecha de la expresión en la variable a la izquierda var1 += 2 (en el caso de que “var1” sea igual a 3, el resultado sería igual a 5). Equivalente a var1 = var1 + 2. -= Resta el valor a la derecha de la expresión en la variable a la izquierda var1 -= 2 (en el caso que “var1” sea igual a 3, el resultado sería https://updf.com igual a 1). Equivalente a var1 = var1 – 2. > Valida si la variable a la izquierda es mayor que la de la derecha var1 > var2 (verdadero si el valor de “var1” es mayor que el de “var2”). >= Valida si la variable a la izquierda es mayor o igual que la de la derecha var1 >= var2 (verdadero si el valor de “var1” es mayor o igual que el de “var2”). < Valida si la variable a la izquierda es menor que la de la derecha var1 < var2 (verdadero si el valor de “var1” es menor que el de “var2”). <= Valida si la variable a la izquierda es menor o igual que la de la derecha var1 <= var2 (verdadero si el valor de “var1” es menor o igual que el de “var2”). ++ Aumenta en uno el valor de la variable var1++ (si “var1” es igual a 2, el resultado es igual a 3) -- Disminuye en uno el valor de la variable var1-- (si “var1” es igual a 2, el resultado es igual a 1). ! Negación, cambia el valor booleano de la variable !var1 (verdadero si “var1” es igual a falso; falso si “var1” es verdadero). Fuente: elaboración propia. https://updf.com Los operadores, junto con las variables y estructuras de datos, son las bases para el desarrollo de software, que permiten llevar a cabo acciones de acuerdo con el valor de dichas variables y el resultado de los operadores. Tema 2: Listas Las listas son una estructura de datos muy importante. Son un conjunto de elementos de un tipo dado que se encuentran ordenados y pueden variar en número. Permiten el recorrido de todos y cada uno de sus elementos, sin saltear ninguno y en forma ordenada. Las listas poseen algunos aspectos fundamentales: No son accedidas directamente con un índice (valor que indique la posición del elemento que queremos obtener de la lista), sino de manera secuencial. Esto significa que, si queremos acceder a un elemento, debemos buscar elemento por elemento en la lista hasta encontrarlo. 1 No tienen tamaño fijo; no necesitamos crear una nueva lista si queremos agregar más elementos. Es la misma estructura la que se encarga de buscar más espacio en la memoria para almacenar los nuevos elementos. 2 https://updf.com Las listas son secuenciales debido a que cada elemento contiene un puntero hacia el siguiente elemento. Por esa razón, siempre que busquemos un elemento en una lista, debemos empezar por el primero, ya que este tiene el puntero hacia el segundo. Luego, el segundo tiene el puntero hacia el tercero, y así sucesivamente. Por ejemplo, una lista de números sería de la siguiente manera: Figura 32: Estructura de lista de números (simple enlace) Fuente: [imagen sin título sobre estructura de lista de números (simple enlace)], s. f., https://bit.ly/2ZKtWWh La lista anterior es de tipo simple enlace, ya que tiene un solo puntero hacia el siguiente elemento. Otro tipo es la lista doble enlace, en donde cada elemento posee un puntero o referencia no solo al siguiente, sino también al elemento anterior. Figura 33: Estructura de lista de números (doble enlace) https://updf.com Fuente: [imagen sin título sobre estructura de lista de números (doble enlace)], s. f., https://bit.ly/3shyTlC En C++, se puede implementar una lista de doble enlace, la cual podemos definir de la siguiente manera: Figura 34: Ejemplo de lista en código (en C++) Fuente: elaboración propia. https://updf.com Figura 35: Resultado de la ejecución del código de la figura 34 Fuente: elaboración propia. Tema 3: Arreglos Los arreglos son estructuras de datos que también permiten almacenar un conjunto de variables del mismo tipo. Por ejemplo, podemos tener un arreglo que contenga los números 2, 3, 5, 2 u otro que contenga las palabras “gaseosa”, “vino” y “agua”. Una característica fundamental de los arreglos (también conocidos como “arrays”) es que son de tamaño fijo y que a cada elemento puede accederse directamente si se conoce su posición en el arreglo, denominado “índice”. https://updf.com Los índices en los arreglos empiezan con el número 0 y termina con un valor menos de la cantidad de elementos que puede almacenar, la cual se especifica cuando se crea. Figura 36: Arreglo de 10 ítems Fuente: [imagen sin título sobre arreglo de 10 ítems], 2006, https://bit.ly/3uoLogW Por ejemplo, tenemos que crear un arreglo que va a almacenar cinco números. El código sería de la siguiente manera: Figura 37: Creación de un array de cinco elementos (en C++) Fuente: elaboración propia. https://updf.com Como este arreglo es de tipo int (integer), solo puede almacenar números. Al ser de tamaño 5, los índices van de 0 a 4. Para acceder y asignar valores a un ítem particular de un arreglo, necesitamos su índice, el cual se indica entre corchetes; por ejemplo, para el caso del primer elemento, sería [0]. Si quisiéramos imprimir en pantalla el valor de un elemento de este arreglo, podríamos hacerlo así: Figura 38: Acceso e impresión en pantalla del valor de un arreglo (en C++) Fuente: elaboración propia. En el ejemplo anterior, se imprime el número 22, ya que ese ha sido asignado al índice 4. Por ejemplo, para sumar todos los elementos de un arreglo, el código puede ser el siguiente: https://updf.com Figura 39: Suma de los elementos de un arreglo numérico (en C++) Fuente: elaboración propia. El código anterior imprime 26, que es el resultado de la suma de cada uno de los elementos del arreglo “arregloDeEnteros”. En cada iteración del for, se accede con el valor que en ese momento tiene la variable “i”, la cual se utiliza como índice para acceder a las posiciones del arreglo. https://updf.com Por ser de tamaño fijo, si necesitamos almacenar más elementos de los definidos en la creación del arreglo, tenemos que crear uno nuevo y copiar los elementos a este último. En nuestro ejemplo, si queremos agregar un sexto elemento, tenemos que crear un arreglo con seis lugares copiando los elementos agregados al arreglo previo a este último. Tanto las listas como los arreglos son muy utilizados y tienen sus ventajas y desventajas, por lo que, a la hora de elegir qué estructura de datos utilizar, los debemos tener en cuenta: Tabla 2: Arreglos y listas - Arreglo Lista Acceso Indexado (dado el índice, accedemos directamente al elemento). Secuencial (debemos recorrer desde el primer elemento hasta encontrar el que buscamos) Tamaño Fijo. Variable Utilidad Sabemos de antemano la cantidad de elementos. Al ser indexado, el acceso es muy eficiente, por lo que se puede tener en cuenta para aplicaciones que necesiten No sabemos la cantidad de elementos de antemano. Es útil cuando la velocidad de acceso al elemento no es un factor clave. Al no requerir https://updf.com alto rendimiento. No es eficiente tener que recrear el arreglo todo el tiempo, porque necesitamos más espacio. cambio de tamaño, la adición y eliminación de un elemento son muy eficientes. Fuente: elaboración propia. Tema 4: Matrices Las matrices son estructuras de datos que permiten almacenar datos en formade tabla, en donde especificamos un índice para la fila y otro para la columna. Son iguales que los arreglos en el sentido que necesitan índices para acceder a los elementos y son de tamaño fijo. La principal diferencia entre un arreglo y una matriz es que con esta última necesitamos dos índices. Tabla 3: Ejemplo de matriz Las matrices técnicamente son un arreglo de arreglos, es decir, un arreglo en el que cada elemento es otro arreglo. https://updf.com Fuente: elaboración propia. En este ejemplo, para poder acceder al elemento de la primera fila y segunda columna (Clara), tenemos que usar dos índices: 0 (fila) y 1 (columna). Estos índices se representan entre corchetes: [0][1]. Una matriz en Java puede definirse de la siguiente manera: Figura 40: Ejemplo de matriz (en C++) https://updf.com Fuente: elaboración propia. Para obtener el valor de una matriz, podemos hacerlo de la siguiente manera: Figura 41: Ejemplo de acceso de un elemento de una matriz (en C++) https://updf.com Fuente: elaboración propia. En el resultado del ejemplo anterior, se muestra en pantalla el valor de la fila 0 y la columna 1, cuyo valor es “Clara”. Para recorrer y acceder a cada uno de los elementos de una matriz, se necesita utilizar un for anidado dentro de otro. El código para hacerlo sería el siguiente: Figura 42: Recorrido de los elementos de una matriz (en C++) Fuente: elaboración propia. Al igual que los arreglos, si necesitamos almacenar más elementos de los definidos inicialmente, es preciso crear una matriz más grande. Las matrices, por estar hechas de arreglos, no se pueden cambiar de tamaño. https://updf.com Para poder crear un programa, necesitamos ser capaces de controlar las acciones del programa que estamos elaborando. Al desarrollar software, tendremos tres componentes: Condicionales: Los condicionales son instrucciones que evalúan la veracidad de una sentencia, por lo tanto, utilizan valores booleanos (“verdadero” o “falso”) para decidir si ejecuta o no una determinada sección de código. Las variantes son dos: Figura 43: Diagrama de flujo if Lección 5 de 7 Glosario Evento de entrada. Proceso. Salida. Sentencia if. Sentencia if- else. https://updf.com Fuente: elaboración propia. Figura 44: Diagrama de flujo if-else Fuente: elaboración propia. https://updf.com Condicional múltiple: Es una alternativa a la utilización de sucesivos ifs. Permite establecer múltiples caminos posibles para el flujo de ejecución. Podemos evaluar el valor de una variable o el resultado de una expresión de cualquier tipo y, de acuerdo con este, ejecutar cierta sección del código. La sentencia para realizar esta funcionalidad es la sentencia switch. Figura 45: Diagrama de flujo switch Fuente: elaboración propia. Ciclos o bucles: Un ciclo o bucle es una sección de código en la cual la ejecución se repite de acuerdo con una condición. Son muy útiles cuando queremos recorrer una lista de elementos o ejecutar una sección de código indefinidamente. Las variantes son las siguientes: El bucle while. El bucle do-while. El bucle for. https://updf.com Figura 46: Diagrama de flujo while Fuente: elaboración propia. Figura 47: Diagrama de flujo do-while El bucle for- each. https://updf.com Fuente: elaboración propia. Funciones/Funciones anónimas: Son secciones de código que podemos reutilizar. Se estructuran manera tal que no tenemos que codificar varias veces el mismo código, sino que lo hacemos una sola vez dentro de una función que podamos invocar cada vez que lo necesitemos en el resto del código. Recursividad: Podemos definir un algoritmo recursivo como aquel que se utiliza dentro de sí mismo. Una función recursiva es la codificación de dicho algoritmo y se caracteriza por llamarse a sí misma dentro de la función. Los algoritmos recursivos deberían utilizarse cuando fuera necesario, ya que consumen más recursos computacionales que los algoritmos que no lo son. Operadores: Son símbolos que permiten manipular los datos de un programa. Representan las operaciones que podemos realizar sobre los datos del algoritmo. Entre los operadores más comunes, tenemos los matemáticos, los lógicos (booleanos) y los de comparación. Listas: Son una estructura de datos que permiten almacenar un conjunto de elementos de un tipo dado de forma ordenada y pueden variar en número. Permiten el recorrido de todos y cada uno de sus elementos, sin saltear ninguno y en forma ordenada. Arreglos: https://updf.com Los arreglos son estructuras de datos que también permiten almacenar un conjunto de variables del mismo tipo pero con una cantidad fija. Estos datos pueden accederse a través de la posición que ocupan dentro del arreglo; a dicha posición se la llama “índice”. Matrices: Son estructuras de datos que permiten almacenar datos en forma de tabla, en donde especificamos un índice para la fila y otro para la columna. Se los puede considerar como arreglos multidimensionales. CONTINUAR https://updf.com
Compartir