Articulo de referencia

Programación imperativa

En informática , la programación imperativa es un paradigma de programación de software que proporciona instrucciones específicas sobre cómo deben realizarse los cálculos. Este ...

En informática , la programación imperativa es un paradigma de programación de software que proporciona instrucciones específicas sobre cómo deben realizarse los cálculos. Este paradigma puede utilizar sentencias que pueden cambiar el estado de un proceso . De forma similar a como el modo imperativo en los lenguajes naturales expresa órdenes, un programa imperativo consiste en órdenes que la computadora debe ejecutar. La programación imperativa se centra en describir cómo opera un programa paso a paso (el orden de los pasos generalmente se determina en el código fuente mediante la colocación de sentencias una debajo de la otra), [ 1 ] en lugar de en descripciones de alto nivel de sus resultados esperados.

El término se usa a menudo en contraste con la programación declarativa , que se centra en lo que el programa debe lograr sin especificar todos los detalles de cómo el programa debe lograr el resultado. [ 2 ]

Programación procedimental

La programación procedimental es un tipo de programación imperativa en la que el programa se construye a partir de uno o más procedimientos (también llamados subrutinas o funciones). Si bien a menudo se usan como sinónimos, el uso de procedimientos influye notablemente en la apariencia y la estructura de los programas imperativos. La programación procedimental intensiva, en la que los cambios de estado se localizan en los procedimientos o se restringen a argumentos y retornos explícitos de los mismos, es una forma de programación estructurada . Desde la década de 1960, la programación estructurada y la programación modular en general se han promovido como técnicas para mejorar la mantenibilidad y la calidad general de los programas imperativos. Los conceptos de la programación orientada a objetos buscan extender este enfoque.

La programación procedimental podría considerarse un paso hacia la programación declarativa. Un programador a menudo puede deducir, simplemente observando los nombres, argumentos y tipos de retorno de los procedimientos (y los comentarios relacionados), qué se supone que debe hacer un procedimiento en particular, sin necesidad de analizar los detalles de cómo logra su resultado. Al mismo tiempo, un programa completo sigue siendo imperativo, ya que determina en gran medida las instrucciones que se ejecutarán y su orden de ejecución.

Fundamentos y principios de la programación imperativa

El paradigma de programación utilizado para crear programas para casi todas las computadoras generalmente sigue un modelo imperativo. [ nota 1 ] El hardware de las computadoras digitales está diseñado para ejecutar código máquina , que es nativo de la computadora y generalmente se escribe en estilo imperativo, aunque existen compiladores e intérpretes de bajo nivel que utilizan otros paradigmas para algunas arquitecturas como las máquinas Lisp .

Desde esta perspectiva de bajo nivel, el estado del programa se define por el contenido de la memoria , y las instrucciones son el lenguaje de máquina nativo de la computadora. Los lenguajes imperativos de nivel superior utilizan variables e instrucciones más complejas, pero siguen el mismo paradigma. Las recetas y las listas de verificación de procesos , si bien no son programas informáticos , también son conceptos familiares con un estilo similar a la programación imperativa; cada paso es una instrucción, y el mundo físico almacena el estado. Dado que las ideas básicas de la programación imperativa son conceptualmente familiares y están directamente implementadas en el hardware, la mayoría de los lenguajes de programación son de estilo imperativo.

En el paradigma imperativo, las sentencias de asignación realizan una operación sobre la información almacenada en memoria y guardan los resultados para su uso posterior. Los lenguajes imperativos de alto nivel, además, permiten la evaluación de expresiones complejas , que pueden consistir en una combinación de operaciones aritméticas y evaluaciones de funciones , y la asignación del valor resultante a la memoria. Las sentencias de bucle (como los bucles while , do while y for ) permiten que una secuencia de sentencias se ejecute varias veces. Los bucles pueden ejecutar las sentencias que contienen un número predefinido de veces o repetirlas hasta que se cumpla alguna condición. Las sentencias de bifurcación condicional permiten que una secuencia de sentencias se ejecute solo si se cumple alguna condición. De lo contrario, las sentencias se omiten y la secuencia de ejecución continúa desde la sentencia siguiente. Las sentencias de bifurcación incondicional permiten que una secuencia de ejecución se transfiera a otra parte de un programa. Estas incluyen el salto (llamado goto en muchos lenguajes), el switch y la llamada a subprograma, subrutina o procedimiento (que normalmente regresa a la siguiente sentencia después de la llamada).

En los inicios del desarrollo de los lenguajes de programación de alto nivel , la introducción del bloque permitió la construcción de programas en los que un grupo de instrucciones y declaraciones podía tratarse como si fueran una sola instrucción. Esto, junto con la introducción de las subrutinas , posibilitó la expresión de estructuras complejas mediante la descomposición jerárquica en estructuras procedimentales más simples.

Historia de los lenguajes imperativos y orientados a objetos.

Los primeros lenguajes imperativos fueron los lenguajes de máquina de las primeras computadoras. En estos lenguajes, las instrucciones eran muy simples, lo que facilitaba la implementación del hardware, pero dificultaba la creación de programas complejos.

Fortran , desarrollado por John Backus en International Business Machines (IBM) a partir de 1954, fue el primer lenguaje de programación importante que eliminó los obstáculos que presentaba el código máquina para la creación de programas complejos. Fortran era un lenguaje compilado que permitía variables con nombre, expresiones complejas, subprogramas y muchas otras características que ahora son comunes en los lenguajes imperativos.

En las dos décadas siguientes se desarrollaron muchos otros lenguajes de programación imperativos de alto nivel. A finales de la década de 1950 y durante la de 1960, se desarrolló ALGOL para facilitar la expresión de algoritmos matemáticos e incluso sirvió como lenguaje de destino del sistema operativo para algunos ordenadores.

MUMPS (1966) llevó el paradigma imperativo a un extremo lógico, al prescindir por completo de sentencias y basarse únicamente en comandos, llegando incluso a independizar los comandos IF y ELSE, conectados solo por una variable intrínseca llamada $TEST. COBOL (1960) y BASIC (1964) fueron intentos de lograr que la sintaxis de programación se pareciera más al inglés.

En la década de 1970, Niklaus Wirth desarrolló Pascal , y Dennis Ritchie creó C mientras trabajaba en los Laboratorios Bell . Wirth diseñó posteriormente Modula-2 y Oberon . Para satisfacer las necesidades del Departamento de Defensa de los Estados Unidos , Jean Ichbiah y un equipo de Honeywell comenzaron a diseñar Ada en 1978, tras un proyecto de cuatro años para definir los requisitos del lenguaje. La especificación se publicó por primera vez en 1983, con revisiones en 1995, 2005 y 2012.

En la década de 1980 se produjo un rápido crecimiento del interés por la programación orientada a objetos . Estos lenguajes eran imperativos en su estilo, pero añadieron características para dar soporte a objetos . Las dos últimas décadas del siglo XX vieron el desarrollo de muchos de estos lenguajes. Smalltalk -80, concebido originalmente por Alan Kay en 1969, fue lanzado en 1980 por el Xerox Palo Alto Research Center ( PARC ). Inspirándose en conceptos de otro lenguaje orientado a objetos, Simula (considerado el primer lenguaje de programación orientado a objetos del mundo , desarrollado en la década de 1960), Bjarne Stroustrup diseñó C++ , un lenguaje orientado a objetos basado en C. El diseño de C++ comenzó en 1979 y la primera implementación se completó en 1983. A finales de la década de 1980 y en la de 1990, los lenguajes imperativos notables que se basaban en conceptos orientados a objetos fueron Perl , lanzado por Larry Wall en 1987; Python , lanzado por Guido van Rossum en 1990; Visual Basic y Visual C++ (que incluía Microsoft Foundation Class Library (MFC) 2.0), lanzados por Microsoft en 1991 y 1993 respectivamente; PHP , lanzado por Rasmus Lerdorf en 1994; Java , por James Gosling ( Sun Microsystems ) en 1995, JavaScript , por Brendan Eich ( Netscape ), y Ruby , por Yukihiro "Matz" Matsumoto, ambos lanzados en 1995. El .NET Framework de Microsoft (2002) es imperativo en su esencia, al igual que sus principales lenguajes objetivo, VB.NET y C# que se ejecutan en él; sin embargo, F# de Microsoft , un lenguaje funcional, también se ejecuta en él.

Ejemplos

Fortran

Fortran (1958) se presentó como "El sistema de traducción de fórmulas matemáticas de IBM". Fue diseñado para cálculos científicos, sin funciones de manejo de cadenas . Además de declaraciones , expresiones y sentencias , admitía:

Tuvo éxito porque:

  • Los costos de programación y depuración fueron inferiores a los costos de funcionamiento de la computadora.
  • Contó con el apoyo de IBM.
  • Las aplicaciones en ese momento eran científicas. [ 3 ]

Sin embargo, otros proveedores que no eran de IBM también escribieron compiladores de Fortran, pero con una sintaxis que probablemente no sería compatible con el compilador de IBM. [ 3 ] El Instituto Nacional Estadounidense de Estándares (ANSI) desarrolló el primer estándar de Fortran en 1966. En 1978, Fortran 77 se convirtió en el estándar hasta 1991. Fortran 90 admite:

COBOL

COBOL (1959) significa "Lenguaje Común Orientado a los Negocios". Fortran manipulaba símbolos. Pronto se comprendió que los símbolos no tenían por qué ser números, por lo que se introdujeron las cadenas de caracteres. [ 4 ] El Departamento de Defensa de los Estados Unidos influyó en el desarrollo de COBOL, siendo Grace Hopper una de las principales contribuyentes. Las sentencias eran similares al inglés y prolijas. El objetivo era diseñar un lenguaje que los gerentes pudieran leer. Sin embargo, la falta de sentencias estructuradas dificultó este objetivo. [ 5 ]

El desarrollo de COBOL estuvo estrictamente controlado, por lo que no surgieron dialectos que requirieran estándares ANSI. En consecuencia, no se modificó durante 15 años, hasta 1974. La versión de la década de 1990 introdujo cambios importantes, como la programación orientada a objetos . [ 5 ]

ALGOL

ALGOL (1960) significa "Lenguaje ALGOrítmico". Tuvo una profunda influencia en el diseño de lenguajes de programación. [ 6 ] Surgió de un comité de expertos europeos y estadounidenses en lenguajes de programación, utilizó notación matemática estándar y tenía un diseño estructurado y legible. ALGOL fue el primero en definir su sintaxis utilizando la forma Backus-Naur . [ 6 ] Esto dio lugar a compiladores dirigidos por sintaxis . Añadió características como:

Entre los descendientes directos de ALGOL se encuentran Pascal , Modula-2 , Ada , Delphi y Oberon en una rama. En otra rama están C , C++ y Java . [ 6 ]

BÁSICO

BASIC (1964) significa "Código de Instrucción Simbólica de Propósito General para Principiantes". Fue desarrollado en el Dartmouth College para que todos sus estudiantes lo aprendieran. [ 7 ] Si un estudiante no continuaba con un lenguaje más potente, aún recordaría BASIC. [ 7 ] Se instaló un intérprete de BASIC en las microcomputadoras fabricadas a finales de la década de 1970. A medida que crecía la industria de las microcomputadoras, también lo hacía el lenguaje. [ 7 ]

BASIC fue pionero en la sesión interactiva . [ 7 ] Ofrecía comandos del sistema operativo dentro de su entorno:

  • El comando 'new' creó un lienzo en blanco.
  • Declaraciones evaluadas de inmediato
  • Las instrucciones podrían programarse anteponiéndoles un número de línea.
  • El comando 'list' mostró el programa.
  • El comando 'run' ejecutó el programa.

Sin embargo, la sintaxis de BASIC era demasiado simple para programas grandes. [ 7 ] Los dialectos más recientes añadieron estructura y extensiones orientadas a objetos. Visual Basic de Microsoft sigue siendo ampliamente utilizado y produce una interfaz gráfica de usuario . [ 8 ]

do

El lenguaje de programación C (1973) recibió su nombre porque el lenguaje BCPL fue reemplazado por B , y AT&T Bell Labs llamó a la siguiente versión "C". Su propósito era escribir el sistema operativo UNIX . [ 9 ] C es un lenguaje relativamente pequeño, lo que facilita la escritura de compiladores. Su crecimiento reflejó el crecimiento del hardware en la década de 1980. [ 9 ] Su crecimiento también se debió a que posee las facilidades del lenguaje ensamblador , pero utiliza una sintaxis de alto nivel . Añadió características avanzadas como:

Mapa de memoria de la computadora

C permite al programador controlar en qué región de la memoria se almacenarán los datos. Las variables globales y estáticas requieren la menor cantidad de ciclos de reloj para su almacenamiento. La pila se utiliza automáticamente para las declaraciones de variables estándar . La memoria del montón se devuelve a una variable de puntero desde la malloc()función.

  • La región de datos global y estático se encuentra justo encima de la región del programa . (Técnicamente, la región del programa se denomina región de texto . Es donde se almacenan las instrucciones de la máquina).
    • La región de datos global y estática es técnicamente dos regiones. [ 10 ] Una región se llama segmento de datos inicializados , donde se almacenan las variables declaradas con valores predeterminados. La otra región se llama segmento de bloque iniciado por , donde se almacenan las variables declaradas sin valores predeterminados.
    • Las variables almacenadas en la región de datos globales y estáticos tienen sus direcciones definidas en tiempo de compilación. Conservan sus valores durante toda la vida del proceso.
    • La región global y estática almacena las variables globales que se declaran encima (fuera) de la main()función. [ 11 ] Las variables globales son visibles para main()y todas las demás funciones en el código fuente.
  • Por otro lado, las declaraciones de variables dentro de main()otras funciones o dentro {}de delimitadores de bloque son variables locales . Las variables locales también incluyen variables de parámetros formales . Las variables de parámetros están encerradas entre paréntesis en las definiciones de funciones. [ 12 ] Proporcionan una interfaz a la función.
    • Las variables locales declaradas usando el staticprefijo también se almacenan en la región de datos global y estático . [ 10 ] A diferencia de las variables globales, las variables estáticas solo son visibles dentro de la función o bloque. Las variables estáticas siempre conservan su valor. Un ejemplo de uso sería la función
      int increment_counter () { static int counter = 0 ; counter ++ ; return counter ; }
  • La región de pila es un bloque contiguo de memoria ubicado cerca de la dirección de memoria superior. [ 13 ] Las variables colocadas en la pila se llenan de arriba a abajo. [ 13 ] Un puntero de pila es un registro especial que mantiene un registro de la última dirección de memoria llenada. [ 13 ] Las variables se colocan en la pila mediante la instrucción PUSH del lenguaje ensamblador . Por lo tanto, las direcciones de estas variables se establecen durante el tiempo de ejecución . El método para que las variables de pila pierdan su ámbito es mediante la instrucción POP.
    • Las variables locales declaradas sin el staticprefijo, incluidas las variables de parámetros formales, [ 14 ] se denominan variables automáticas [ 11 ] y se almacenan en la pila. [ 10 ] Son visibles dentro de la función o bloque y pierden su ámbito al salir de la función o bloque.
    • La región de memoria dinámica (heap) se encuentra debajo de la pila. [ 10 ] Se llena de abajo hacia arriba. El sistema operativo administra la memoria dinámica mediante un puntero a memoria dinámica y una lista de bloques de memoria asignados. [ 15 ] Al igual que la pila, las direcciones de las variables de memoria dinámica se establecen durante la ejecución. Se produce un error de falta de memoria cuando el puntero a memoria dinámica y el puntero a pila coinciden.
    • C proporciona la malloc()función de biblioteca para asignar memoria dinámica (heap). [ 16 ] El llenado del heap con datos es una función de copia adicional. Las variables almacenadas en el heap se pasan de forma eficiente a las funciones mediante punteros. Sin punteros, todo el bloque de datos tendría que pasarse a la función a través de la pila.

C++

En la década de 1970, los ingenieros de software necesitaban soporte de lenguaje para dividir grandes proyectos en módulos . [ 17 ] Una característica obvia era descomponer físicamente los grandes proyectos en archivos separados . Una característica menos obvia era descomponer lógicamente los grandes proyectos en tipos de datos abstractos . [ 17 ] En ese momento, los lenguajes admitían tipos de datos concretos ( escalares ) como números enteros , números de punto flotante y cadenas de caracteres . Los tipos de datos concretos tienen su representación como parte de su nombre. [ 18 ] Los tipos de datos abstractos son estructuras de tipos de datos concretos, con un nuevo nombre asignado. Por ejemplo, una lista de enteros podría llamarse .integer_list

En la jerga de la programación orientada a objetos, los tipos de datos abstractos se denominan clases . Sin embargo, una clase es solo una definición; no se le asigna memoria. Cuando se le asigna memoria a una clase, se la denomina objeto . [ 19 ]

Los lenguajes imperativos orientados a objetos se desarrollaron combinando la necesidad de clases y la necesidad de una programación funcional segura . [ 20 ] En un lenguaje orientado a objetos, una función se asigna a una clase. Una función asignada se denomina método , función miembro u operación . La programación orientada a objetos consiste en ejecutar operaciones sobre objetos . [ 21 ]

Los lenguajes orientados a objetos admiten una sintaxis para modelar relaciones de subconjunto/superconjunto . En la teoría de conjuntos , un elemento de un subconjunto hereda todos los atributos contenidos en el superconjunto. Por ejemplo, un estudiante es una persona. Por lo tanto, el conjunto de estudiantes es un subconjunto del conjunto de personas. Como resultado, los estudiantes heredan todos los atributos comunes a todas las personas. Además, los estudiantes tienen atributos únicos que otras personas no tienen. Los lenguajes orientados a objetos modelan las relaciones de subconjunto/superconjunto mediante la herencia . [ 22 ] La programación orientada a objetos se convirtió en el paradigma de lenguaje dominante a finales de la década de 1990. [ 17 ]

C++ (1985) se llamó originalmente "C con clases". [ 23 ] Fue diseñado para ampliar las capacidades de C añadiendo las funcionalidades orientadas a objetos del lenguaje Simula . [ 24 ]

Un módulo orientado a objetos se compone de dos archivos. El archivo de definiciones se denomina archivo de cabecera . Aquí se muestra un archivo de cabecera de C++ para la clase GRADE en una aplicación escolar sencilla:

// grade.h // -------// Se utiliza para permitir que varios archivos fuente incluyan // este archivo de encabezado sin errores de duplicación. // Véase: https://en.wikipedia.org/wiki/Include_guard // ---------------------------------------------- #ifndef GRADE_H #define GRADE_Hclase GRADE { public : // Esta es la operación del constructor. // ---------------------------------- GRADE ( const char letter );// Esta es una variable de clase. // ------------------------- char letra ;// Esta es una operación miembro. // --------------------------- int grade_numeric ( const char letter );// Esta es una variable de clase. // ------------------------- int numeric ; }; #endif

Una operación constructora es una función con el mismo nombre que el nombre de la clase. [ 25 ] Se ejecuta cuando la operación que la llama ejecuta la newinstrucción.

El otro archivo de un módulo es el archivo fuente . Aquí hay un archivo fuente de C++ para la clase GRADE en una aplicación escolar simple:

// grade.cpp // --------- #include "grade.h"CALIFICACIÓN :: CALIFICACIÓN ( const char letra ) { // Referencia el objeto usando la palabra clave 'this'. // ---------------------------------------------- this -> letra = letra ;// Esto es cohesión temporal // ------------------------- this -> numeric = grade_numeric ( letter ); }int GRADE :: grade_numeric ( const char letter ) { if ( ( letter == 'A' || letter == 'a' ) ) return 4 ; else if ( ( letter == 'B' || letter == 'b' ) ) return 3 ; else if ( ( letter == 'C' || letter == 'c' ) ) return 2 ; else if ( ( letter == 'D' || letter == 'd' ) ) return 1 ; else if ( ( letter == 'F' || letter == 'f' ) ) return 0 ; else return -1 ; }

Aquí tenéis un archivo de cabecera de C++ para la clase PERSON en una sencilla aplicación escolar:

// person.h // -------- #ifndef PERSON_H #define PERSON_Hclase PERSONA { público : PERSONA ( const char * nombre ); const char * nombre ; }; #endif

Aquí tenéis un archivo fuente en C++ para la clase PERSONA en una sencilla aplicación escolar:

// person.cpp // ---------- #include "person.h"PERSONA :: PERSONA ( const char * nombre ) { this -> nombre = nombre ; }

Aquí tenéis un archivo de cabecera de C++ para la clase ESTUDIANTE en una sencilla aplicación escolar:

// student.h // --------- #ifndef ESTUDIANTE_H #define ESTUDIANTE_H#incluir "persona.h" #incluir "grado.h"// Un ESTUDIANTE es un subconjunto de PERSONA. // -------------------------------- class ESTUDIANTE : public PERSONA { public : ESTUDIANTE ( const char * nombre ); ~ ESTUDIANTE (); CALIFICACIÓN * calificación ; }; #endif

Aquí tenéis un archivo fuente de C++ para la clase ESTUDIANTE en una sencilla aplicación escolar:

// student.cpp // ----------- #include "student.h" #include "person.h"ESTUDIANTE :: ESTUDIANTE ( const char * nombre ) : // Ejecuta el constructor de la superclase PERSONA. // ------------------------------------------------- PERSONA ( nombre ) { // No hay nada más que hacer. // ------------------- }ESTUDIANTE ::~ ESTUDIANTE () { // liberar la memoria de la calificación // para evitar fugas de memoria. // ------------------------------------------------- eliminar esto -> calificación ; }

Aquí hay un programa de controlador a modo de demostración:

// student_dvr.cpp // --------------- #include <iostream> #include "student.h"int main ( void ) { ESTUDIANTE * estudiante = nuevo ESTUDIANTE ( "El estudiante" ); estudiante -> calificación = nuevo CALIFICACIÓN ( 'a' );std :: cout // Observe que el estudiante hereda el nombre de PERSONA << estudiante- > nombre << ": Calificación numérica = " << estudiante- > calificación- > numérico << " \n " ;// liberar la memoria del estudiante // para evitar fugas de memoria. // ------------------------------------------------- eliminar estudiante ;devolver 0 ; }

Aquí tenéis un archivo makefile para compilarlo todo:

# makefile # -------- all : student_dvrlimpiar : rm student_dvr *.o student_dvr : student_dvr.cpp grade.o student.o person.o c ++ student_dvr.cpp grade.o student.o person.o -o student_dvr​​​grade.o : grade . cpp grade . h c++ -c grade.cppestudiante.o : estudiante.cpp estudiante.h c ++ -c estudiante.cpppersona.o : persona . cpp persona . h c++ -c persona.cpp 

Fuentes

  • Joseph Goguen y Grant Malcolm, "Semántica algebraica de programas imperativos", MIT Press, 1966, ISBN 9780262071727

Véase también

Notas

  1. La computación reconfigurable es una excepción notable.

Referencias

  1. Jain, Anisha (10 de diciembre de 2022). "Promesas de Javascript: ¿Existe un mejor enfoque?" . Medium . Archivado del original el 20 de diciembre de 2022. Consultado el 20 de diciembre de 2022 .
  2. "Programación imperativa: Panorama general del paradigma de programación más antiguo" . IONOS Digitalguide . 21 de mayo de 2021. Archivado del original el 3 de mayo de 2022. Consultado el 3 de mayo de 2022 .
  3. 1 2 Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 16. ISBN  0-201-71012-9.
  4. Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 24. ISBN  0-201-71012-9.
  5. 1 2 Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 25. ISBN  0-201-71012-9.
  6. 1 2 3 4 Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 19. ISBN  0-201-71012-9.
  7. 1 2 3 4 5 Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 30. ISBN  0-201-71012-9.
  8. Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 31. ISBN  0-201-71012-9.
  9. 1 2 3 Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 37. ISBN  0-201-71012-9.
  10. 1 2 3 4 "Disposición de la memoria de los programas C" . 12 de septiembre de 2011. Archivado del original el 6 de noviembre de 2021. Recuperado el 25 de mayo de 2022 .
  11. 1 2 Kernighan, Brian W.; Ritchie, Dennis M. (1988). El lenguaje de programación C, segunda edición . Prentice Hall. pág. 31. ISBN  0-13-110362-8.
  12. Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 128. ISBN  0-201-71012-9.
  13. 1 2 3 Kerrisk, Michael (2010). La interfaz de programación de Linux . No Starch Press. pág. 121. ISBN  978-1-59327-220-3.
  14. Kerrisk, Michael (2010). La interfaz de programación de Linux . No Starch Press. pág. 122. ISBN  978-1-59327-220-3.
  15. Kernighan, Brian W.; Ritchie, Dennis M. (1988). El lenguaje de programación C, segunda edición . Prentice Hall. pág. 185. ISBN  0-13-110362-8.
  16. Kernighan, Brian W.; Ritchie, Dennis M. (1988). El lenguaje de programación C, segunda edición . Prentice Hall. pág. 187. ISBN  0-13-110362-8.
  17. 1 2 3 Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 38. ISBN  0-201-71012-9.
  18. Stroustrup, Bjarne (2013). El lenguaje de programación C++, cuarta edición . Addison-Wesley. pág. 65. ISBN  978-0-321-56384-2.
  19. Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 193. ISBN  0-201-71012-9.
  20. Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 39. ISBN  0-201-71012-9.
  21. Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 35. ISBN  0-201-71012-9.
  22. Wilson, Leslie B. (2001). Lenguajes de programación comparativos, tercera edición . Addison-Wesley. pág. 192. ISBN  0-201-71012-9.
  23. Stroustrup, Bjarne (2013). El lenguaje de programación C++, cuarta edición . Addison-Wesley. pág. 22. ISBN  978-0-321-56384-2.
  24. Stroustrup, Bjarne (2013). El lenguaje de programación C++, cuarta edición . Addison-Wesley. pág. 21. ISBN  978-0-321-56384-2.
  25. Stroustrup, Bjarne (2013). El lenguaje de programación C++, cuarta edición . Addison-Wesley. pág. 49. ISBN  978-0-321-56384-2.
  • Pratt, Terrence W. y Marvin V. Zelkowitz . Lenguajes de programación: diseño e implementación , 3.ª ed. Englewood Cliffs, NJ: Prentice Hall, 1996.
  • Sebesta, Robert W. Conceptos de lenguajes de programación , 3.ª ed. Reading, Mass.: Addison-Wesley Publishing Company, 1996.
Originalmente basado en el artículo 'Programación imperativa' de Stan Seibert, de Nupedia , bajo licencia GNU Free Documentation License .