En programación informática , un bloque o bloque de código o bloque de código es una estructura léxica de código fuente que se agrupa. Los bloques consisten en una o más declaraciones y enunciados . Un lenguaje de programación que permite la creación de bloques, incluidos bloques anidados dentro de otros bloques, se denomina lenguaje de programación estructurado por bloques . Los bloques son fundamentales para la programación estructurada , donde las estructuras de control se forman a partir de bloques.
Los bloques tienen dos funciones: agrupar sentencias para que puedan ser tratadas como una sola sentencia y definir alcances para los nombres a fin de distinguirlos del mismo nombre utilizado en otro lugar. En un lenguaje de programación estructurado en bloques, los objetos nombrados en bloques externos son visibles dentro de bloques internos, a menos que estén enmascarados por un objeto declarado con el mismo nombre.
Las ideas de estructura de bloques se desarrollaron en la década de 1950 durante el desarrollo de los primeros autocódigos y se formalizaron en los informes Algol 58 y Algol 60. Algol 58 introdujo la noción de "declaración compuesta", que estaba relacionada únicamente con el flujo de control . [1] El Informe Revisado posterior que describió la sintaxis y la semántica de Algol 60 introdujo la noción de bloque y alcance de bloque , con un bloque que consiste en "Una secuencia de declaraciones seguidas por una secuencia de declaraciones y encerradas entre el comienzo y el final..." en el que "[c]ada declaración aparece en un bloque de esta manera y es válida solo para ese bloque". [2]
Los bloques utilizan una sintaxis diferente en distintos lenguajes. Dos grandes familias son:
begin
en la que los bloques están delimitados por las palabras claves " " y " end
" o equivalentes. En C , los bloques están delimitados por llaves - " {
" y " }
". ALGOL 68 utiliza paréntesis.(
" y " )
", se utilizan en el lenguaje de procesamiento por lotes MS-DOSprog
o let
(como en la familia Lisp )if ~ then ~ elif ~ else ~ fi
case ~ in ~ out ~ esac
for ~ while ~ do ~ od
Algunos lenguajes que admiten bloques con declaraciones no admiten completamente todas las declaraciones; por ejemplo, muchos lenguajes derivados de C no permiten una definición de función dentro de un bloque ( funciones anidadas ). Y a diferencia de su antecesor Algol, Pascal no admite el uso de bloques con sus propias declaraciones dentro del inicio y el final de un bloque existente, solo declaraciones compuestas que permiten agrupar secuencias de declaraciones en if , while , repeat y otras declaraciones de control.
El significado semántico de un bloque es doble. En primer lugar, proporciona al programador una forma de crear estructuras arbitrariamente grandes y complejas que se pueden tratar como unidades. En segundo lugar, permite al programador limitar el alcance de las variables y, a veces, de otros objetos que se han declarado.
En los primeros lenguajes como Fortran IV y BASIC , no había bloques de instrucciones ni estructuras de control más allá de formas simples de bucles. Los condicionales se implementaban utilizando instrucciones condicionales goto :
C LANGUAGE: ANSI STANDARD FORTRAN 66 C INICIALIZAR VALORES A CALCULAR PAYSTX = . FALSE . PAYSST = . FALSE . TAX = 0.0 SUPTAX = 0.0 C SALTAR DEDUCCIÓN DE IMPUESTOS SI EL EMPLEADO GANA MENOS QUE EL UMBRAL DE IMPUESTOS SI ( SALARIOS . LE . TAXTHR ) IR A 100 PAYSTX = . TRUE . TAX = ( SALARIOS - TAXTHR ) * BASCRT C SALTAR DEDUCCIÓN DE SUPERIMPUESTO SI EL EMPLEADO GANA MENOS QUE EL UMBRAL DE SUPERIMPUESTO SI ( SALARIOS . LE . SUPTHR ) IR A 100 PAYSST = . TRUE . SUPTAX = ( SALARIOS - SUPTHR ) * SUPRAT 100 GRAVADO = SALARIOS - IMPUESTO - SUPTAX
La estructura lógica del programa no se refleja en el lenguaje y analizar cuándo se ejecuta una determinada instrucción puede resultar difícil.
Los bloques permiten al programador tratar un grupo de declaraciones como una unidad, y los valores predeterminados que deben aparecer en la inicialización en este estilo de programación pueden, con una estructura de bloques, ubicarse más cerca de la decisión:
{ Idioma: Jensen y Wirth Pascal } si salarios > umbral_impuestos entonces comience paystax := verdadero ; impuesto := ( salarios - umbral_impuestos ) * tasa_impuestos { La estructura de bloques hace que sea más fácil ver cómo se puede refactorizar el código para mayor claridad, y también hace que sea más fácil hacerlo, porque la estructura del condicional interno se puede sacar fácilmente del condicional externo por completo y los efectos de hacerlo se predicen fácilmente. } si salarios > umbral_superimpuestos entonces comience pays_supertax := verdadero ; supertax := ( salarios - umbral_superimpuestos ) * tasa_superimpuestos fin de lo contrario comience pays_supertax := falso ; supertax := 0 fin fin de lo contrario comience paystax := falso ; pays_supertax := falso ; impuesto := 0 ; supertax := 0 fin ; gravado := salario - impuesto - superimpuesto ;
El uso de bloques en el fragmento de Pascal anterior aclara la intención del programador y permite combinar los bloques resultantes en una jerarquía anidada de instrucciones condicionales . La estructura del código refleja más fielmente el pensamiento del programador, lo que facilita su comprensión y modificación.
El código fuente anterior se puede hacer aún más claro si se elimina por completo la declaración if interna de la externa y se colocan los dos bloques uno después del otro para que se ejecuten consecutivamente. En este caso, hay poca diferencia semántica y el uso de la estructura de bloques, respaldada por sangrías para facilitar la lectura, facilita que el programador refactorice el código.
En los lenguajes primitivos, las variables tenían un amplio alcance. Por ejemplo, una variable entera llamada IEMPNO podía usarse en una parte de una subrutina de Fortran para indicar el número de seguro social (SSN) de un empleado, pero durante un trabajo de mantenimiento en la misma subrutina, un programador podía usar accidentalmente la misma variable, IEMPNO, para un propósito diferente, y esto podía resultar en un error difícil de rastrear. La estructura de bloques facilita a los programadores controlar el alcance a un nivel minucioso.
;; Idioma: Esquema estándar R5RS ( let (( empno ( ssn-of employee-name ))) ( while ( is-manager empno ) ( let (( employee ( length ( underlings-of empno )))) ( printf "~a tiene ~a empleados trabajando bajo su mando:~%" employee-name employee-name employee ( for -each ( lambda ( empno ) ;; Dentro de esta expresión lambda la variable empno se refiere al ssn ;; de un subordinado. La variable empno en la expresión externa, ;; que se refiere al ssn del gerente, está sombreada. ( printf "Nombre: ~a, rol: ~a~%" ( name-of empno ) ( role-of empno ))) ( underlings-of empno )))))
En el fragmento de Scheme anterior , se utiliza empno para identificar tanto al gerente como a sus subordinados, cada uno por su respectivo número de seguro social, pero como el número de seguro social del subordinado se declara dentro de un bloque interno, no interactúa con la variable del mismo nombre que contiene el número de seguro social del gerente. En la práctica, las consideraciones de claridad probablemente llevarían al programador a elegir nombres de variable distintos, pero tienen la opción y es más difícil introducir un error sin darse cuenta.
En algunos lenguajes, una variable puede declararse en el ámbito de una función incluso dentro de bloques cerrados. Por ejemplo, en JavaScript, las variables declaradas con var
tienen ámbito de función.