Lenguajes de Programación Historia. Programación imperativa o por procedimientos. Paradigmas de programación abstracta. 75.40 Algoritmos y Programación I Curso Prof. Servetto 1 Historia El desarrollo de sistemas de software complejos como sistemas operativos, software de redes o la gran variedad de software de aplicación que se aprecia hoy en día hubiera sido imposible si los humanos hubiesen sido forzados a escribir programas en lenguaje de máquina. En los años 40 la programación comenzó a simplificarse mediante el uso de sistemas de notación de instrucciones a través de códigos mnemónicos en lugar de código binario. Para convertir los programas escritos en código mnemónico al lenguaje de máquina se desarrollaron programas llamados ensambladores (assemblers), y los sistemas mnemónicos para representar programas, lenguajes de ensambladura (assembly languages). 75.40 Algoritmos y Programación I Curso Prof. Servetto 2 Ejemplo de lenguaje de ensambladura Resta en punto flotante Código de máquina Lenguaje de ensambladura Dirección Instrucción (en hexadecimal) Identificadores Código Operandos 00 110E LD R1, Minuendo 02 120F LD R2, Sustraendo 04 2380 LDI R3, H80 06 9223 XOR R2, R2, R3 08 6412 ADDF R4, R1, R2 0A 3410 0C C000 0E 695C ST R4, Resultado HLT Minuendo 2.25 10 Sustraendo 1.5 12 Resultado 75.40 Algoritmos y Programación I Curso Prof. Servetto 3 Historia Los lenguajes de ensambladura se denominaron de segunda generación, siendo los de la primera los lenguajes de máquina mismos. Los lenguajes de ensambladura eran dependientes de la máquina para la que fueran diseñados y obligaban a los programadores a pensar soluciones a problemas en términos de operaciones elementales de máquina. Luego surgieron los lenguajes de tercera generación que incluyeron primitivas de alto nivel y fueron independientes de máquinas, como FORTRAN (FORmula TRANslation), para aplicaciones científicas y de ingeniería y COBOL (COmmon Business Oriented Language), para aplicaciones de negocios. 75.40 Algoritmos y Programación I Curso Prof. Servetto 4 Historia Los lenguajes de tercera generación permitieron a los programadores pensar soluciones a problemas en términos de primitivas con un nivel de abstracción equiparable al del lenguaje natural. Los programas escritos en lenguajes de tercera generación se pueden convertir al lenguaje de máquina mediante programas llamados traductores, que para traducir primitivas de alto nivel deben compilar secuencias de instrucciones de máquina, por lo que también se denominan compiladores. Una alternativa a los compiladores son los intérpretes, que en vez de grabar traducciones para uso futuro, ejecutan las primitivas como si fuera una traducción simultánea (en vez de producir una copia en lenguaje de máquina de un programa que pueda ejecutarse después, ejecutan realmente un programa desde su forma de alto nivel). 75.40 Algoritmos y Programación I Curso Prof. Servetto 5 Programación imperativa o por procedimientos Representa la aproximación tradicional al proceso de programación, considerado como el desarrollo de una secuencia de ordenes que, cuando se ejecutan, manipulan datos para producir los resultados deseados. El paradigma de programación imperativa implica encontrar un algoritmo para resolver el problema en mano y expresarlo como una secuencia de comandos, estructurada con las primitivas de control ya vistas (selectivas, iterativas y de invocación de subprogramas); por esto mismo, el paradigma también se conoce como de programación estructurada. 75.40 Algoritmos y Programación I Curso Prof. Servetto 6 Programación imperativa o por procedimientos Los programas en ese paradigma consisten de una colección de sentencias que se categorizan en: Declarativas: definen la terminología que se utilizará luego en el programa para referenciar estructuras e ítems de datos. Imperativas: describen pasos del algoritmo que se está representando, en términos de comandos organizados con estructuras de control. Comentarios: realzan la legibilidad o comprensión de un programa explicando sus características en términos más amigables para el ser humano. 75.40 Algoritmos y Programación I Curso Prof. Servetto 7 Variables y tipos de datos Los lenguajes de programación de alto nivel permiten que localizaciones de la memoria principal se puedan referenciar con nombres en lugar de direcciones numéricas. Estos nombres se denominan variables, en reconocimiento de que representan valores que pueden variar durante la ejecución del programa. En general, los lenguajes de programación requieren que las variables se identifiquen vía sentencias declarativas antes de ser usadas en el programa, y que además se especifique el tipo de datos que se almacenará en las localizaciones de la RAM asociadas. El tipo de datos implica la forma en que los ítems de datos estarán codificados y las operaciones que se podrá realizar con ellos. Por ejemplo, para la restar dos números enteros en Pascal debería definirse: Y en C, C++, C# o Java: 75.40 Algoritmos y Programación I minuendo, sustraendo, resultado: Smallint; int minuendo, sustraendo, resultado; Curso Prof. Servetto 8 Variables y tipos de datos Todos los lenguajes de programación incluyen como tipos básicos o primitivos a los que puede manipular la CPU: enteros no negativos (sin signo), enteros en complemento a 2, fraccionarios en punto flotante, caracteres y booleanos (una abstracción de un bit, que sólo puede tener como valores verdadero o falso). Como los lenguajes de programación de alto nivel son independientes de la arquitectura de la máquina, para los tipos numéricos suele haber distintas precisiones (capacidades de representación). Las operaciones que se pueden efectuar con valores numéricos son las aritméticas tradicionales y las de comparación. 75.40 Algoritmos y Programación I Curso Prof. Servetto 9 Variables y tipos de datos Equivalencia de tipos en Pascal y C Enteros sin signo o en complemento a 2 Pascal C Byte Fraccionarios Bytes Pascal C unsigned char 1 Single float 4 Shortint char 1 Double double 8 Smallint short int 2 Extended long double Word unsigned short int 2 Comp 8 Longint long int 4 Currency 8 Longword unsigned long int 4 Int64 long long int 8 QWord unsigned long long int 8 75.40 Algoritmosy Programación I Curso Prof. Servetto Bytes 10 10 Constantes y literales Es muy común la necesidad de usar en un programa valores fijos predeterminados, como una aproximación del valor de , para cálculos geométricos, o del valor del número de Euler para otros cálculos. Para valores de uso frecuente en un programa, los lenguajes permiten definir objetos llamados constantes, que se definen por un nombre y su valor en la sección declarativa de los programas. En las expresiones de estructuras de control o para asignar valores a variables, se puede emplear el nombre de la constante en representación de su valor; si se expresa directamente un valor, se dice que se usa un valor literal. 75.40 Algoritmos y Programación I Curso Prof. Servetto 11 Constantes y literales Pascal C Program SC; {calcula superficie de círculos} const Pi: double = 3.14159265358979; var radio, superf: double; begin // Prólogo {Solicitar al usuario el ingreso del radio del círculo} // Desarrollo superf:=Pi * radio * radio; // Epilogo // Informar la superficie al usuario end. const double Pi = 3.14159265358979; 75.40 Algoritmos y Programación I double radio, superf; int main () { // Prólogo /* Solicitar al usuario el ingreso del radio del círculo */ // Desarrollo superf = Pi * radio * radio; // Epilogo // Informar la superficie al usuario return (0); } Curso Prof. Servetto 12 Estructuras de datos Al ver la organización de la RAM se dijo que una de las ventajas de que las celdas estén direccionadas era que se podía almacenar en celdas consecutivas datos que ocupen más de una celda, y referenciarlos por la dirección de la primer celda. Además de tener tipos, los datos pueden tener también una estructura, que es la forma o disposición conceptual de los mismos. Por ejemplo el texto normalmente es visto como una cadena de caracteres, un dato que represente a una persona como un conjunto de valores de distintos tipos que representen distintas características de la persona, o una lista de nombres como una secuencia de cadenas. Los lenguajes de programación tienen estructuras de datos primitivas que se pueden asociar directamente a variables cuando éstas se declaran, y también permiten definir patrones estructurales (definición de tipos) para luego definir variables. 75.40 Algoritmos y Programación I Curso Prof. Servetto 13 Estructuras de datos Cadenas de caracteres Pascal C Var nombre1, nombre2: String[20]; texto: String; {hasta 255 caracteres} O bien: Type tnombre = String[20]; Var nombre1, nombre2: tnombre; texto: String; #include <string.h> char nombre1[21], nombre2[21]; char texto[256]; /* En C los strings terminan con el carácter nulo \0 (0 en binario en 8 bits) */ 75.40 Algoritmos y Programación I Curso Prof. Servetto 14 Estructuras de datos Cadenas de caracteres Pascal C begin … {Ejemplos de asignación de valores literales} nombre1:='Juan Alvarez'; nombre2:='Laura Rosetti'; texto:=''; // string nulo (dos apóstrofes) … end. int main() { … /* C no permite asignación de valores literales a las cadenas. Se debe usar un subprograma de la librería string.h llamado strcpy */ strcpy(nombre1, "Juan Alvarez"); strcpy(nombre2 , "Laura Rosetti"); strcpy(texto, "“); … } 75.40 Algoritmos y Programación I Curso Prof. Servetto 15 Estructuras de datos Registros o estructuras Pascal C Var persona1, persona2: record nombre: String; fnac: Longword end; O bien: Type tpersona = record nombre: String; fnac: Longword {aaaammdd} end; Var persona1, persona2: tpersona; struct tpersona { char nombre[256]; unsigned long int fnac; } persona1, persona2; O bien: struct tpersona { char nombre[256]; unsigned long int fnac; }; struct tpersona persona1, persona2; 75.40 Algoritmos y Programación I Curso Prof. Servetto 16 Estructuras de datos Registros o estructuras Acceso a miembros de una estructura (ejemplo de asignación): En Pascal persona1.nombre:='Juan Alvarez'; persona1.fnac:=19680714; En C strcpy(persona1.nombre, "Juan Alvarez"); persona1.fnac = 19680714; 75.40 Algoritmos y Programación I Curso Prof. Servetto 17 Estructuras de datos Arreglos Un arreglo es un bloque de elementos del mismo tipo, y puede ser unidimensional, para representar listas, o multidimensional, para tablas de elementos. La definición de arreglos requiere la especificación del nombre y de la longitud de cada dimensión. El tamaño de los arreglos queda determinado en el momento de la definición, y puede suceder que al utilizarlos en un programa, no se llegue a usar toda su capacidad, por lo que usualmente se les debe asociar una variable por dimensión para indicar las cantidades de elementos efectivas en cada dimensión. Para referenciar los elementos de un arreglo se suele usar una variable por dimensión para indicar sus posiciones en la estructura. Estas variables se denominan variables índice. 75.40 Algoritmos y Programación I Curso Prof. Servetto 18 Estructuras de datos Arreglos Pascal C Type struct tlistanombres { unsigned char long, i; char nom[100][21]; }; struct tlistanombres listanom; tlistanombres = record long, i: byte; nom: array[1..100] of string[20]; end; Var listanom: tlistanombres; 75.40 Algoritmos y Programación I Curso Prof. Servetto 19 Estructuras de datos Arreglos Referencia a elementos de un arreglo (ejemplo de escritura en pantalla): En Pascal with listanom do for i:=1 to long do writeln(nom[i]); {escribe en pantalla los nombres, uno por línea} En C /* en C los elementos se indican a partir de 0 */ for (listanom.i = 0; listanom.i < listanom.long; listanom.i++) printf("%s\n", listanom.nom[listanom.i]); 75.40 Algoritmos y Programación I Curso Prof. Servetto 20 Estructuras de control Selectivas Condicionales simples cond actividad 75.40 Algoritmos y Programación I expr cond F V Condicional múltiple V actividad 1 F literal1 actividad 2 actividad 1 Curso Prof. Servetto literal n literal2 actividad 2 … actividad n 21 Estructuras de control Selectivas Pascal C if expresión then acción1 else acción2; donde expresión debe evaluarse como verdadera o falsa, y acción1 y acción2 pueden ser una sentencia simple o un conjunto de sentencias delimitadas con begin y end. La cláusula else es opcional. if (expresión) acción1 else acción2; donde expresión debe evaluarse como verdadera o falsa, y acción1 y acción2 pueden ser una sentencia simple o un conjunto de sentencias delimitadas con llaves ({, }). La cláusula else es opcional. 75.40 Algoritmos y Programación I Curso Prof. Servetto 22 Estructuras de control Selectivas Pascal C var n: word; // número natural begin // Se solicita al usuario el ingreso de un número write(ˈIngrese un número: ˈ); readln(n); // Ingresa el número n // Se informa si n es par o impar: if n mod 2 = 0 then writeln(ˈEl número es parˈ) else write(ˈEl número es imparˈ); readln end. #include <stdio.h> int main () { unsigned int n; // número natural //Se solicita al usuario el ingreso de un número printf("Ingrese un número: "); scanf("%u", &n); // Ingresa el número n // Se informa si n es par o impar: if (n % 2 == 0) puts("El número es par") else puts("El número es impar") return (0); } 75.40 Algoritmos y Programación I Curso Prof. Servetto 23 Estructuras de control Selectivas Pascal C case expresión of literal1: acción1; … literaln: acciónn; else acción; end; donde expresión debe evaluarse resultando un valor del mismo tipo de los literales, literali puede ser una valor o lista de valores literales (separados por comas), y acción y accióni pueden ser una sentencia simple o un conjunto de sentencias delimitadas con begin y end. La cláusula else es opcional. switch (expresión) { case literal1: acción1; break; … case literaln: acciónn; break; default: acción; } donde expresión debe evaluarse resultando un valor entero, literali debe ser un valor literal entero, y acción y accióni pueden ser una sentencia simple o un conjunto de sentencias. La cláusula default es opcional. 75.40 Algoritmos y Programación I Curso Prof. Servetto 24 Estructuras de control Selectivas Pascal C var fecha: longword; a: word; // a año que se toma de fecha unsigned long int fecha; unsigned short int a; // año que se toma de fecha … switch ((fecha % 10000) / 100) { case 1:; case 3:; case 5:; case 7:; case 8:; case 10:; case 12: dias = 31; break; case 4:; case 6:; case 9:; case 11: dias = 30; break; default: { … case (fecha mod 10000) div 100 of 1, 3, 5, 7, 8, 10, 12: dias:=31; 4, 6, 9, 11: dias:=30; else begin a:=fecha div 10000; // año if ((a mod 4 = 0) and (a mod 100 <> 0)) or (a mod 400 = 0) then dias:=29 a=fecha / 10000; // año else dias:=28 if (((a % 4 == 0) && (a % 100 != 0)) || (a % 400 == 0)) dias = 29 else dias = 28 } end end; … 75.40 Algoritmos y Programación I } … Curso Prof. Servetto 25 Estructuras de control Repetitivas Control inicial Control final condición falsa Actividad condición condición verdadera condición Actividad condición falsa condición verdadera 75.40 Algoritmos y Programación I Curso Prof. Servetto 26 Estructuras de control Repetitivas Pascal C while expresión do acción; o repeat acción until expresión; o for variable := valor_inicial to/downto valor_final do acción; while (expresión) acción; o do acción while (expresión); o for (inicialización; expresión; actualización) acción; 75.40 Algoritmos y Programación I Curso Prof. Servetto 27 Estructuras de control Repetitivas Pascal C {Impresión de los dígitos decimales en una línea de pantalla} var d: byte = 0; begin while d < 10 do begin write(d:2); d:=d+1 end end. /* Impresión de los dígitos decimales en una línea de pantalla */ #include <stdio.h> unsigned char d = 0; int main () { while (d < 10) printf ("%d ", d++); return (0); } 75.40 Algoritmos y Programación I Curso Prof. Servetto 28 Estructuras de control Repetitivas Pascal C {Impresión de los dígitos decimales en una línea de pantalla} var d: byte = 0; begin repeat write(d:2); d:=d+1 until d = 10 end. /* Impresión de los dígitos decimales en una línea de pantalla */ #include <stdio.h> unsigned char d = 0; int main () { do printf ("%d ", d++); while (d < 10); return (0); } 75.40 Algoritmos y Programación I Curso Prof. Servetto 29 Estructuras de control Repetitivas Pascal C {Impresión de los dígitos decimales en una línea de pantalla} var d: byte; begin for d:=0 to 9 do write(d:2) end. /* Impresión de los dígitos decimales en una línea de pantalla */ #include <stdio.h> unsigned char d; int main () { for (d = 0; d < 10; d++) printf ("%d ", d); return (0); } 75.40 Algoritmos y Programación I Curso Prof. Servetto 30 Subprogramas Constituyen la principal herramienta para obtener una representación modular de un algoritmo como programa, es decir, de la división del problema a resolver en subproblemas. Son conjuntos de instrucciones para realizar una tarea, que pueden usarse como herramientas abstractas toda vez que en un programa se requiera realizar dicha tarea. El control se transfiere al subprograma mediante una sentencia de invocación, y una vez que el subprograma termina de ejecutarse, el control vuelve al programa o subprograma que lo invocó. Los subprogramas se codifican como unidades de programa individuales, y tienen la misma estructura que un programa: una sección declarativa y otra imperativa. 75.40 Algoritmos y Programación I Curso Prof. Servetto 31 Subprogramas Ejecución de programa o subprograma invocante El control se transfiere al subprograma Subprograma Invocación del subprograma Se ejecuta el subprograma Continúa la ejecución del invocante El control vuelve al invocante cuando se completa el subprograma 75.40 Algoritmos y Programación I Curso Prof. Servetto 32 Subprogramas La codificación de todo subprograma debe comenzar con una sentencia denominada cabecera, que debe incluir un nombre que lo identifique y sirva para invocarlo, y la lista de parámetros o nombres genéricos que se convertirán en específicos en el momento de su invocación, que suele denominarse la firma del subprograma. Los parámetros serían como variables que representan variables o valores literales para invocar al subprograma. Pueden servir: Para ingresar datos al subprograma para que éste opere con ellos sin modificarlos: parámetros de entrada (pueden ser valores literales en la invocación). Para ingresar datos que el programa puede modificar: parámetros de entrada/salida (no pueden ser valores literales en la invocación). Para que el subprograma devuelva resultados: parámetros de salida (tampoco pueden ser valores literales en la invocación). Existen dos tipos de subprogramas, que se distinguen por la forma de invocación: Los procedimientos: se invocan con su nombre como sentencia. Las funciones: devuelven un valor asociado a su invocación, por lo que sólo pueden invocarse en expresiones de asignación o de condiciones de control, o como parámetros de entrada. 75.40 Algoritmos y Programación I Curso Prof. Servetto 33 Procedimientos Definición Pascal C procedure amdFecha( fecha: longword; // fecha de entrada var a: word; // año de fecha resultado var m, d: byte); // mes y día de fecha resultados {recibe una fecha con formato aaaammdd y devuelve el año en a, el mes en m y el día en d} begin a:=fecha div 10000; // cálculo del año m:=(fecha div 100) mod 100; // cálculo del mes d:=fecha mod 100 // cálculo del día end; /* en C los procedimientos se definen como funciones que no devuelven nada */ 75.40 Algoritmos y Programación I void amdFecha ( unsigned long int fecha, // fecha de entrada unsigned short int *a, // dirección para devolver año unsigned char *m, // dirección para devolver mes unsigned char *d ); // dirección para devolver día /* recibe una fecha con formato aaaammdd y devuelve el año en a, el mes en m y el día en d */ { *a = fecha / 10000; // almacenamiento del año en la dirección de a *m = (fecha / 100) % 100; // almacenamiento del mes en dir. de m *d = fecha % 100; // almacenamiento del día en dir. de d }; Curso Prof. Servetto 34 Procedimientos Invocación Pascal C … var f: longword; // fecha anio: word; mes, dia: byte; begin write(ˈIngrese fecha: ˈ); readln(f); amdFecha(f, anio, mes, dia); writeln(dia, ˈ/ ˈ, mes, ˈ/ ˈ, anio) end; … unsigned long int f; // fecha unsigned short int anio; unsigned char mes, dia; int main () { 75.40 Algoritmos y Programación I printf("Ingrese una fecha: "); scanf("%lu", &f); amdFecha(f, &anio, &mes, &dia); // & es dir. de… printf("\n%u/%u/%u", dia, mes, anio); return (0); } Curso Prof. Servetto 35 Parámetros Los parámetros que se utilizan en la codificación de subprogramas se denominan formales, mientras que los significados precisos que se asigna a esos parámetros formales cuando se invoca al subprograma, se denominan parámetros reales. La transferencia de datos entre parámetros reales y formales varía según el propósito de los parámetros: Para parámetros de entrada, se generan copias del valor del parámetro real, para asignarlas al parámetro formal. Se dicen pasados por valor. Para parámetros de entrada y salida o sólo de salida, se asigna la dirección de los parámetros reales a los parámetros formales. Se dicen pasados por referencia. Los datos estructurados de gran tamaño, aunque no se modifiquen en un subprograma, conviene que sean pasados por referencia, por resultar esto más eficiente. 75.40 Algoritmos y Programación I Curso Prof. Servetto 36 Parámetros Cuando un parámetro se pasa por valor, el subprograma puede modificar el valor del parámetro formal sin afectar el valor del parámetro real, ya que está modificando una copia. Cuando un parámetro se pasa por referencia, si el subprograma modifica el parámetro formal está modificando al real, ya que la dirección de ambos es la misma. las convenciones para pasar parámetros de una u otra forma varían según el lenguaje de programación. En Pascal basta con indicar en la cabecera del subprograma que un parámetro es variable, para determinar que su pasaje sea por referencia, mientras que en C, se debe indicar en la definición de subprogramas que se manipulan valores por referencia con “*”, y en la invocación que se pasa la dirección de una variable con “&”. 75.40 Algoritmos y Programación I Curso Prof. Servetto 37 Funciones Definición Pascal C function numFecha( a: word; // año m, d: byte // mes y día ): longword; // resultado de la función {recibe una fecha fragmentada en año, mes y día y la devuelve con formato aaaammdd} begin numFecha:= a*10000+m*100+d end; unsigned long int numFecha ( unsigned short int a, // año unsigned char m, // mes unsigned char d ); // día /* recibe una fecha fragmentada en año, mes y día y la devuelve con formato aaaammdd */ { return (a*10000+m*100+d); }; 75.40 Algoritmos y Programación I Curso Prof. Servetto 38 Funciones Invocación Pascal C … … unsigned short int anio; unsigned char mes, dia; int main () { var anio: word; mes, dia: byte; begin write(ˈIngrese día, mes y año: ˈ); readln(dia, mes, anio); printf("Ingrese dia, mes y año: "); scanf("%u %u %u", dia, mes, anio); printf("La fecha en un solo numero es: "); write(ˈLa fecha en un solo numero es: ˈ); printf("%lu", numFecha(anio, mes, dia)); writeln(numFecha(anio, mes, dia)) return (0); end; } 75.40 Algoritmos y Programación I Curso Prof. Servetto 39 Traducción de programas Un programa escrito en un lenguaje de alto nivel se denomina programa fuente, y su versión traducida al lenguaje de máquina, programa objeto. El proceso de traducción o compilación implica tres etapas: Análisis léxico: reconocimiento y clasificación (variables, valores literales, operadores, palabras clave) de cadenas o símbolos del programa fuente como identificadores (tokens). Análisis sintáctico (parsing): procesamiento del código producido por el análisis léxico en términos de unidades léxicas para identificar la estructura gramatical del programa y reconocer el rol de cada componente. Generación de código. 75.40 Algoritmos y Programación I Curso Prof. Servetto 40 Enlace de programas Los lenguajes de programación de alto nivel incluyen subprogramas como primitivas, como los vistos en los ejemplos precedentes para operaciones de lectura y escritura. Estos subprogramas suelen estar agrupados por afinidad en librerías que ya están traducidas como programas objeto. Para producir un programa ejecutable, debe reunirse el código objeto de los programas desarrollados con el código objeto de aquellas librerías de las cuales se invocan subprogramas en el programa desarrollado. Para esto debe intervenir un programa llamado editor de enlaces (link editor), que está incluido en los ambientes integrados de desarrollo o IDE (integrated development environments). El compilador de Pascal reconoce por defecto un conjunto de subprogramas de uso común que incluye en una librería llamada System, y además tiene otras librerías que, para poder invocar sus subprogramas, debe agregarse una sentencia declarativa indicándolo (la sentencia Uses); en cambio en el lenguaje C no se incluye ninguna librería por defecto y es por eso que para poder invocar subprogramas de entrada o salida como scanf, printf o puts hay que incluir como sentencia declarativa #include <stdio.h>, o para usar cadenas #include <string.h>. 75.40 Algoritmos y Programación I Curso Prof. Servetto 41 Paradigmas de programación La clasificación de lenguajes de programación por generaciones se basa en una escala lineal en la cual la posición de un lenguaje está determinada por cuán lejos está el usuario del lenguaje de tener que pensar en términos de las instrucciones de máquina o cuán cerca de poder hacerlo en términos asociados al problema que quiera resolver. En realidad, el desarrollo de lenguajes de programación progresó a lo largo de diferentes caminos como aproximaciones alternativas al proceso de programación, denominadas paradigmas de programación o de desarrollo de software. 75.40 Algoritmos y Programación I Curso Prof. Servetto 42 Paradigmas de programación Funcional Orientada a objetos Lenguaje Imperativa de máquina Declarativa 75.40 Algoritmos y Programación I Curso Prof. Servetto 43 Paradigmas de programación En contraste con la programación imperativa, la programación declarativa permite al programador describir el problema que debe resolver sin tener que especificar cómo resolverlo. Aplica un algoritmo preestablecido para la resolución general de problemas, como la inferencia lógica (programación lógica basada en el cálculo de predicados –lenguaje Prolog). Otro paradigma es el de programación funcional, en la que los programas se conciben como la composición de funciones predefinidas para, a partir de ciertos datos de entrada, obtener datos de salida. El paradigma más prominente en el desarrollo de software actual es el de programación orientada a objetos, en el que un sistema de software se concibe como un conjunto de unidades llamadas objetos, cada uno de los cuales es capaz de realizar un conjunto de acciones que le pueden ser solicitadas por otros objetos, en interacciones que conduzcan a la solución de un problema. 75.40 Algoritmos y Programación I Curso Prof. Servetto 44