Introducción a la computación Carlos Lopez Pombo Estado Se denomina estado en un modelo de cómputo a un punto en la ejecución de un programa en dicho modelo. En el modelo de Von Neumann esto responde al valor de las variables, constantes y la instrucción del programa que corresponde a dicho punto de la ejecución. Especificación de algoritmos Pero ¿por qué especificar? Pensémoslo así: aun cuando sepamos dar una secuencia de pasos capaz de resolver un problema, debemos tener bien claro qué tenemos que resolver. Especificación de algoritmos Especificar un algoritmo es describir qué es lo que hace a partir de detallar cuál es el estado posterior a su ejecución en función del estado anterior a la misma. pre = {precondición} P post = {postcondición} Instrucción (Otra oportunidad) Una instrucción es una operación que produce una transformación del estado en que se encuentra la ejecución del programa (recordar que la instrucción en la que se encuentra la ejecución es parte del estado y por lo tanto la alteración del flujo de control es una transformación del estado tanto como la modificación del contenido de una posición de . memoria) Instrucción (Detalle) Asignación: [var] = [expr] [var] es un nombre para la dirección de memoria donde se almacenará el dato, [expr] es una expresión entre variables, constantes o literales. x = 4 + y (a x se le asigna el valor correspondiente a la suma de 4 e y) iter = 7 (a iter se le asigna el valor 7) res = f (x, y, z) (a res se le asigna el valor de evaluar f en los valores correspondientes a x, y, y z) Programa ¡Una asignación es un programa! Programa Secuencialización: [prog1];[prog2] [prog1], [prog2] son programas. x = x + 2 ; y = x + y (a x se le asigna el valor de x más 2 y luego a y se le asigna el resultado de la suma de x e y). Programa Condicional: if ([expr1][comp][expr2]) { [prog1] }else{ [prog2] } [expr1], [expr2] son expresiones entre variables, constantes o literales. [comp] es un operador de comparación. [prog1], [prog2] son programas. if (x < 4) { x=5+y; z = z + 1; }else{ y = y / 2; } (si vale que el valor asignado a x es menor que 4, entonces se ejecuta el programa “x = 5 + y ; z = z + 1”. Si no, se ejecuta el programa “y = y / 2”) Programa Repetición: while ([expr1][comp][expr2]) { [prog] } [expr1], [expr2] son expresiones entre variables, constantes o literales. [comp] es un operador de comparación. [prog] es un programa. y = 1; x = 1; while (x < 10) { y = y * x; x++; } (el programa que figura entre llaves “y = y * x” es repetido mientras se satisfaga la condición “x < 10”) Programa Repetición: for ([var]; [expr1][comp][expr2]; [asig]) { [prog] } [expr1], [expr2] son expresiones entre variables, constantes o literales. [comp] es un operador de comparación. [prog] es un programa. [var] es una variable. [asig] es una asignación. x=1 y=1 for (x; x < 10; x++) { y = y * x; } (el programa que figura entre llaves “y = y * x” es repetido mientras se satisfaga la condición “x < 10”) Programa for ([var]; [expr1][comp][expr2]; [asig]) { [prog] } ≡ while ([expr1][comp][expr2]) { [prog]; [asig]; } ¡Listo! Programar es producir largas tiras de asignaciones en las que cada tanto se toma una decisión (if-then-else) o se repiten cosas (while o for), todo eso pegado por “;”. ¡Pero Matías, Mariano y yo ya nos encariñamos, así que vamos a quedarnos todo el cuatrimestre! Programar (Saber programar es mucho más que eso) Modularidad Estabilidad Usabilidad Flexibilidad Programa Elegancia Generalidad Reusabilidad Adaptabilidad No es lo mismo... ¿Cómo saber si el número Debemos verificar que “n” sea “n” es primo? sólo divisible por “n” y por 1. int i = n - 1; bool ret; while (i > 1 && n%i != 0){ i--; } if (i == 1){ ret = true; } else { ret = false; } return ret; No es lo mismo... Debemos verificar que “n” sea ¿Cómo saber si los números sólo divisible por “n” y por 1. “n” y “m” son primos? Y lo mismo para “m” int i = n-1; bool = ret; while (i > 1 && n%i != 0){ i--; } if (i == 1){ ret = true; } else { ret = false; } i = m-1; while (i > 1 && m%i != 0){ i--; } if (i == 1){ ret = ret && true; } else { ret = ret && false; } return ret; No es lo mismo... ¿Cómo saber si los números del arreglo a[10] son primos? int i = a[0]-1; bool ret; while (i > 1 && a[0]%i != 0){ i--; } if (i == 1){ ret = true; } else { ret = false; } ... i = a[9]-1; while (i > 1 && a[9]%i != 0){ i--; } if (i == 1){ ret = ret && true; } else { ret = ret && false; } return ret; bool ret; for (j; j < 10; j++){ int i = a[j]-1; while (i > 1 && a[j]%i != 0){ i--; } if (i == 1){ ret = ret && true; } else { ret = ret && false; } } return ret; Bla, bla, bla... bool ret; for (j; j < 10; j++){ ret = ret && esPrimo(a[j]) } bool esPrimo (int a){ bool ret; int i = a[j]-1; while (i > 1 && a[j]%i != 0){ i--; } if (i == 1){ ret = true; } else { ret = false; } return ret; } Funciones Una función es una unidad de código que aísla una parte de un cómputo... sí, es un programa dentro de un programa. •Permite dividir la solución de un problema en la solución de problemas más simples, •permite ordenar conceptualmente el código de forma que sea más fácil de entender, •permite reutilizar soluciones a problemas pequeños en la solución de problemas mayores, •etc. Funciones Tanto los datos de entrada, como el valor de retorno de una función, tienen un tipo. En este caso la función toma como entrada (parámetro) un int y retorna un bool. bool esPrimo (int a){ int i = a[j]-1; bool ret; while (i > 1 && a[j]%i != 0){ i--; } if (i == 1){ ret = ret && true; } else { ret = ret && false; } return ret; } Pasaje de parámetros Además de un tipo, los parámetros de cualquier programa tienen un modo. •Entrada (Copia): los valores pasados como parámetro a una función son copiados y todo cambio que se le realice no será visible desde el programa llamador, •Entrada/salida (Referencia): los valores pasados como parámetro son en realidad una referencia a la posición de memoria en que se encuentra el valor y por lo tanto cualquier modificación será visible desde el programa llamador, bool esPrimo (int a){...}: el valor de a puede cambiar durante la ejecución de la función pero al salir de la misma ese cambio no es visible, bool restar10 (int &a){...}: si el valor de a cambia durante la ejecución ese cambio será visible desde el programa llamador. Pasaje de parámetros (Ejemplo) ... {i == 28} int i = 28; resto = restar10 (i); {i == 28} {i == 28} ... bool restar10 (int a){ {a == 28} if (a < 10) return false; {a == 28} else { a = a - 10; return true; {a == 18} } } ... int i = 28; resto = restar10 (i); ... {i == 28} {i == 28} {i == 18} bool restar10 (int &a){ {a == 28} if (a < 10) return false; {a == 28} else { a = a - 10; {a == 18} return true; } } Procedimientos Para recordar... los tipos de datos son nombres para un conjunto de cosas. Así, int denota al conjunto de los “enteros”, float al de los “reales”, etc. Existe un tipo distinguido llamado void que denota al conjunto vacío... se preguntarán para qué, no? ¡Para cuando el tipo de las cosas no importa! Procedimientos Un procedimiento es una función que no tiene valor de retorno. ¿Se acuerdan de resta10? El bool de retorno es totalmente ficticio y fue usado a modo de ejemplo. En realidad queremos una función que le reste 10 al número pasado como parámetro. Procedimientos Un procedimiento es una función que no tiene valor de retorno. bool restar10 (int &a){ if (a < 10) return false; else { a = a - 10; return true; } } void restar10 (int &a){ if !(a < 10) a = a - 10; } Resumen • Instrucciones y estructuras de control • Programa • Funciones y procedimientos • Pasaje de parámetros