En programación informática , el estilo de sangría es una convención , también conocida como estilo , que rige la sangría de los bloques de código fuente . Un estilo de sangría generalmente implica un ancho uniforme de espacio en blanco (tamaño de sangría) antes de cada línea de un bloque, de modo que las líneas de código parezcan estar relacionadas, y dicta si se deben usar espacios o caracteres de tabulación para los espacios en blanco de sangría.
Este artículo aborda principalmente los estilos para lenguajes de programación de formato libre . Como su nombre lo indica, este tipo de código de lenguaje no necesita seguir un estilo de sangría. La sangría es una notación secundaria que suele tener como objetivo reducir la carga cognitiva de un programador para comprender la estructura del código. La sangría puede aclarar la separación entre el código ejecutado en función del flujo de control .
Los lenguajes estructurados, como Python y Occam , utilizan la sangría para determinar la estructura en lugar de utilizar llaves o palabras clave; esto se denomina regla del lado opuesto . En estos lenguajes, la sangría tiene sentido para el procesador del lenguaje (como el compilador o el intérprete ). Un programador debe cumplir con las reglas de sangría del lenguaje, aunque puede ser libre de elegir el tamaño de la sangría.
Este artículo se centra en los lenguajes que utilizan llaves (que delimitan bloques con llaves, también conocidas como corchetes ) y, en particular, en los lenguajes de la familia C , pero una convención utilizada para un lenguaje se puede adaptar a otro. Por ejemplo, un lenguaje que utiliza palabras clave BEGIN
y END
en lugar de llaves se puede adaptar tratándolas BEGIN
de la misma manera que la llave de apertura, y así sucesivamente.
El estilo de sangría solo se aplica a lenguajes basados en texto. Los lenguajes de programación visual no tienen sangría.
A pesar del uso omnipresente de los estilos de sangría, se han realizado pocas investigaciones sobre su valor. Los primeros experimentos, realizados por Weissman en 1974, no mostraron ningún efecto. [1]
En 2023, un experimento de Morzeck et al. [2] mostró un efecto positivo significativo para if
las declaraciones anidadas donde el código sin sangría requería en promedio un 179% más de tiempo para leerse que el código con sangría. Un experimento de seguimiento de Hanenberg et al. [3] confirmó un gran efecto (aunque en ese experimento el código sin sangría solo tomó un 113% más de tiempo para leerse) y reveló que las diferencias en los tiempos de lectura pueden explicarse por el código que se puede omitir (para el código con sangría). En otro experimento sobre objetos JSON [4] el código sin sangría tomó incluso un 544% más de tiempo para leerse.
La siguiente tabla incluye ejemplos de código de varios estilos de sangría. Para mantener la coherencia, el tamaño de la sangría para el código de ejemplo es de 4 espacios, aunque esto varía según la convención de codificación.
Los atributos de C , C++ y otros estilos de codificación de lenguajes de programación entre llaves incluyen, entre otros:
else if
construcción y un do{}while
bloque).El estilo Kernighan & Ritchie (K&R) se utiliza habitualmente para el código C y C++ y es la base de muchos estilos derivados. Se utiliza en el núcleo Unix original, en el libro de Kernighan y Ritchie The C Programming Language y en el libro de Kernighan y Plauger The Elements of Programming Style .
Aunque el lenguaje de programación C no define explícitamente este estilo, lo sigue de manera consistente. Del libro:
La posición de los brackets es menos importante, aunque la gente tiene creencias apasionadas. Hemos elegido uno de los varios estilos populares. Elija un estilo que se adapte a usted y luego úselo de manera constante.
En este estilo, una función tiene sus llaves de apertura y cierre en sus propias líneas y con la misma sangría que la declaración, mientras que las declaraciones en el cuerpo de la función tienen una sangría de un nivel adicional. Sin embargo, un bloque de múltiples declaraciones dentro de una función tiene su llave de apertura en la misma línea que su cláusula de control, mientras que la llave de cierre permanece en su propia línea a menos que esté seguida por una palabra clave como else
o while
.
Código de ejemplo:
int main ( int argc , char * argv []) { while ( x == y ) { hacer_algo (); hacer_algo_más (); if ( algún_error ) arreglar_problema (); // bloque de una sola declaración sin llaves else continue_as_usual (); } cosa_final (); }
Las llaves no alineadas de los bloques de varias líneas reciben el sobrenombre de "llaves egipcias" (o "soportes egipcios") por su parecido con los brazos en algunas poses fantasiosas de los antiguos egipcios. [5] [6] [7]
Un bloque de una sola declaración no tiene llaves, lo que es causa de errores fáciles de pasar por alto, como el error goto fail .
El estilo de una sola llave verdadera [8] (abreviado 1TBS u OTBS [9] ) es como el estilo K&R, pero las funciones están formateadas como bloques de múltiples declaraciones con la llave de apertura en la misma línea que la declaración, y las llaves no se omiten para un bloque de una sola declaración. [10]
bool is_negative ( int x ) { si ( x < 0 ) { devuelve verdadero ; } de lo contrario { devuelve falso ; } }
Aunque no es requerido por lenguajes como C/C++, el uso de llaves para bloques de una sola declaración garantiza que la inserción de una declaración no resulte en un flujo de control que no esté de acuerdo con la sangría, como se ve, por ejemplo, en el infame error goto fail de Apple .
Las ventajas citadas incluyen un código más corto (que K&R) ya que la llave inicial no necesita una línea adicional, que la llave final se alinea con la declaración a la que pertenece conceptualmente y la consistencia estilística percibida de usar el mismo estilo de llave en los cuerpos de funciones y en los bloques de declaraciones de varias líneas. [11]
Las fuentes no están de acuerdo en cuanto al significado de One True Brace Style. Algunos dicen que es la variación que se especifica aquí, [10] mientras que otros dicen que es una "jerga de hackers" para K&R. [12]
El árbol de código fuente del núcleo de Linux tiene un estilo que sigue una variante de K&R. [13] Linus Torvalds recomienda a los colaboradores que lo sigan. Los atributos incluyen:
switch
declaración se alinean con el bloque que las encierra (solo hay un nivel de sangrías)if-else
declaración requieren llaves, ambas deben estar entre llaves:int potencia ( int x , int y ) { int resultado ; si ( y < 0 ) { resultado = 0 ; } de lo contrario { resultado = 1 ; mientras ( y -- > 0 ) resultado *= x ; } devolver resultado ; }
Una parte importante del código Java utiliza una variante del estilo K&R en la que la llave de apertura está en la misma línea no solo para los bloques dentro de una función, sino también para las declaraciones de clases o métodos. Este estilo está muy extendido en gran medida porque las guías de estilo originales de Sun Microsystems [15] [16] [17] utilizaban esta variante de K&R y, como resultado, la mayor parte del código fuente estándar de la API de Java está escrito en este estilo. También es un estilo de sangría popular para ActionScript y JavaScript , junto con el estilo Allman.
Bjarne Stroustrup adaptó el estilo K&R para C++ en sus libros, como Programación: Principios y práctica usando C++ y El lenguaje de programación C++ . [18]
A diferencia de las variantes anteriores, Stroustrup no utiliza un "abrazo más". Por lo tanto, Stroustrup escribiría [18]
si ( x < 0 ) { pone ( "Negativo" ); negativo ( x ); } de lo contrario { pone ( "No negativo" ); no negativo ( x ); }
Stroustrup extiende el estilo K&R para las clases, escribiéndolas de la siguiente manera:
clase Vector { public : // construye un Vector Vector ( int s ) : elem ( new double [ s ]), sz ( s ) { } // acceso a elementos: subíndice double & operador []( int i ) { return elem [ i ]; } int size () { return sz ; } private : // puntero a los elementos double * elem ; // número de elementos int sz ; };
Stroustrup no sangra las etiquetas public:
y private:
. Además, en este estilo, mientras que la llave de apertura de una función comienza en una nueva línea, la llave de apertura de una clase está en la misma línea que el nombre de la clase.
Stroustrup permite escribir funciones cortas en una sola línea. El estilo Stroustrup es un estilo de sangría con nombre disponible en el editor Emacs . Stroustrup fomenta un diseño de estilo derivado de K&R con C++, como se indica en sus modernas Pautas básicas de C++ . [19]
Los sistemas operativos de la distribución de software de Berkeley (BSD) utilizan un estilo que a veces se denomina Forma normal del núcleo (KNF). Aunque está pensado principalmente para el código del núcleo, también se utiliza mucho en el código del espacio de usuario . Es esencialmente una variante completamente documentada del estilo K&R que se utiliza en el código fuente de Unix de las versiones 6 y 7 de Bell Labs . [20]
El núcleo y el espacio de usuario de SunOS utilizan un estilo de sangría similar. [20] Al igual que KNF, este también se basó en documentos de estilo AT&T y a veces se lo denomina Bill Joy Normal Form. [21] La directriz de SunOS se publicó en 1996; se analiza brevemente ANSI C. La corrección de la sangría de una lista de archivos fuente se puede verificar con el programa cstyle escrito por Bill Shannon. [20] [21] [22]
En este estilo, el tabulador duro (ts en vi ) se mantiene en ocho columnas, mientras que un tabulador suave se define a menudo como un auxiliar también (sw en vi) y se establece en cuatro. Los tabuladores duros se utilizan para sangrar bloques de código, mientras que un tabulador suave (cuatro espacios) de sangría adicional se utiliza para todas las líneas continuas que deben dividirse en varias líneas.
Además, las llamadas a funciones no utilizan un espacio antes del paréntesis, aunque las instrucciones nativas del lenguaje C como if
, while
, y do
sí lo hacen (en el caso de que where se use con paréntesis). Las funciones que no declaran variables locales en su bloque de nivel superior también deben dejar una línea vacía después de la llave de apertura del bloque.switch
return
return
Ejemplos:
mientras ( x == y ) { algo (); algo_más (); } cosa_final ();
si ( datos != NULL && res > 0 ) { si ( JS_DefineProperty ( cx , o , "datos" , STRING_TO_JSVAL ( JS_NewStringCopyN ( cx , datos , res )), NULL , NULL , JSPROP_ENUMERATE ) != 0 ) { QUEUE_EXCEPTION ( "¡Error interno!" ); goto err ; } PQfreemem ( datos ); } de lo contrario { si ( JS_DefineProperty ( cx , o , "datos" , OBJECT_TO_JSVAL ( NULL ), NULL , NULL , JSPROP_ENUMERATE ) != 0 ) { QUEUE_EXCEPTION ( "¡Error interno!" ); goto err ; } }
pgresult_constructor JSBool estático ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval ) { QUEUE_EXCEPTION ( "La clase PGresult no puede ser instanciada por el usuario" ); devolver ( JS_FALSE ); }
El estilo Allman recibe su nombre de Eric Allman . También se lo denomina a veces estilo BSD , ya que Allman escribió muchas de las utilidades para BSD Unix (aunque no debe confundirse con el estilo "BSD KNF"; consulte más arriba).
Este estilo coloca la llave asociada con una declaración de control en la siguiente línea, con la misma sangría que la declaración de control. Las declaraciones dentro de las llaves tienen la sangría del siguiente nivel. [12]
mientras ( x == y ) { algo (); algo_más (); } cosa_final ();
Este estilo es similar a la sangría estándar utilizada por los lenguajes Pascal y Transact-SQL , donde las llaves son equivalentes a las palabras clave begin
y end
.
(*Ejemplo de estilo de sangría de código Allman en Pascal*) procedimiento dosomething ( x , y : Integer ) ; begin while x = y do begin something () ; some_else () ; end ; end ;
Las consecuencias de este estilo son que el código sangrado se distingue claramente de la declaración que lo contiene mediante líneas que son casi todas espacios en blanco y la llave de cierre se alinea en la misma columna que la llave de apertura. Algunas personas creen que esto facilita la búsqueda de llaves coincidentes. El estilo de bloqueo también delimita el bloque de código de la declaración de control asociada. Comentar o eliminar una declaración de control o un bloque de código, o refactorizar el código , tienen menos probabilidades de introducir errores de sintaxis a través de llaves colgantes o faltantes. Además, es coherente con la ubicación de las llaves para el bloque de función externa.
Por ejemplo, lo siguiente sigue siendo sintácticamente correcto:
// mientras (x == y) { algo (); algo_más (); }
Así es esto:
// para (int i=0; i < x; i++) // mientras (x == y) si ( x == y ) { algo (); algo_más (); }
Incluso así, con compilación condicional:
int c ; #ifdef HAS_GETCH mientras (( c = getch ()) != EOF ) #else mientras (( c = getchar ()) != EOF ) #endif { hacer_algo ( c ); }
Allman-8 utiliza las tabulaciones de sangría de 8 espacios y el límite de 80 columnas de la variante Linux Kernel de K&R. El estilo supuestamente ayuda a mejorar la legibilidad en los proyectores. Además, el tamaño de la sangría y la restricción de columnas ayudan a crear una señal visual para identificar la anidación excesiva de bloques de código. Estas ventajas se combinan para ayudar a proporcionar a los desarrolladores y estudiantes más nuevos una guía implícita para gestionar la complejidad del código. [ cita requerida ]
El estilo Whitesmiths, también denominado a veces estilo Wishart, se utilizó originalmente en la documentación del primer compilador comercial de C, el Whitesmiths Compiler. También fue popular en los primeros días de Windows, ya que se utilizó en tres libros influyentes de programación de Windows: Programmer's Guide to Windows de Durant, Carlson & Yao, Programming Windows de Petzold y Windows 3.0 Power Programming Techniques de Norton & Yao.
El Jargon File afirmó que los Whitesmiths, junto con los Allman, fueron los estilos de refuerzo más comunes en 1991 , con una popularidad aproximadamente igual en ese momento. [12] [23]
Este estilo coloca la llave asociada a una declaración de control en la siguiente línea, con sangría. Las declaraciones dentro de las llaves tienen la misma sangría que las llaves.
Al igual que en el estilo Ratliff, la llave de cierre tiene la misma sangría que las declaraciones dentro de las llaves. [24]
mientras ( x == y ) { algo (); algo_más (); } cosa_final ();
Las ventajas de este estilo son similares a las del estilo Allman. Los bloques se distinguen claramente de las sentencias de control. La alineación de las llaves con el bloque enfatiza que el bloque completo es conceptualmente y programáticamente una sentencia compuesta. La sangría de las llaves enfatiza que están subordinadas a la sentencia de control. La llave final ya no se alinea con la sentencia, sino con la llave de apertura.
Un ejemplo:
si ( datos != NULL && res > 0 ) { si ( ! JS_DefineProperty ( cx , o , "datos" , STRING_TO_JSVAL ( JS_NewStringCopyN ( cx , datos , res )), NULL , NULL , JSPROP_ENUMERATE )) { QUEUE_EXCEPTION ( "¡Error interno!" ); goto err ; } PQfreemem ( datos ); } de lo contrario si ( ! JS_DefineProperty ( cx , o , "datos" , OBJECT_TO_JSVAL ( NULL ), NULL , NULL , JSPROP_ENUMERATE )) { QUEUE_EXCEPTION ( "¡Error interno!" ); goto err ; }
else if
se tratan como una declaración, de forma muy similar a la #elif
declaración del preprocesador.
Al igual que los estilos Allman y Whitesmiths, el estilo GNU coloca llaves en una línea por sí solas, sangradas por dos espacios, excepto cuando se abre una definición de función, donde no están sangradas. [25] En cualquier caso, el código contenido está sangrado por dos espacios desde las llaves.
Popularizado por Richard Stallman , el diseño puede estar influenciado por su experiencia como escritor de código Lisp . [26] En Lisp, el equivalente a un bloque (un progn) es una entidad de datos de primera clase, y darle su propio nivel de sangría ayuda a enfatizar eso, mientras que en C, un bloque es solo sintaxis. Este estilo también se puede encontrar en algunos libros de texto de lenguaje de programación ALGOL y XPL de los años 1960 y 1970. [27] [28] [ discutir ]
Aunque no es una sangría en sí, el estilo de codificación GNU también incluye un espacio después del nombre de una función, antes del paréntesis izquierdo de una lista de argumentos. [25]
char estático * concat ( char * s1 , char * s2 ) { mientras ( x == y ) { algo (); algo_más (); } cosa_final (); }
Este estilo combina las ventajas de Allman y Whitesmiths, eliminando así la posible desventaja de Whitesmiths de que las llaves no sobresalgan del bloque. Una desventaja es que la llave final ya no se alinea con la declaración a la que pertenece conceptualmente. Otra posible desventaja es que podría desperdiciar espacio al usar dos niveles visuales de sangrías para un nivel conceptual, pero en realidad esto es poco probable porque, en sistemas con sangría de un solo nivel, cada nivel suele tener al menos 4 espacios, lo mismo que 2 * 2 espacios en el estilo GNU.
Los estándares de codificación GNU recomiendan este estilo, y casi todos los mantenedores del software del proyecto GNU lo utilizan. [ cita requerida ]
El editor de texto GNU Emacs y el comando indent de los sistemas GNU reformatearán el código de acuerdo con este estilo de forma predeterminada. [29] Aquellos que no utilicen GNU Emacs, o editores extensibles/personalizables similares, pueden encontrar que las configuraciones de sangría automática de su editor no son útiles para este estilo. Sin embargo, muchos editores que usan el estilo KNF de forma predeterminada se adaptan bien al estilo GNU cuando el ancho de tabulación se establece en dos espacios; de la misma manera, GNU Emacs se adapta bien al estilo KNF simplemente estableciendo el ancho de tabulación en ocho espacios. En ambos casos, el reformateo automático destruye el espaciado original, pero la sangría de línea automática funcionará correctamente.
Steve McConnell , en su libro Code Complete , desaconseja el uso de este estilo: marca un ejemplo de código que lo utiliza con un icono de "Horror de codificación", que simboliza un código especialmente peligroso, y afirma que impide la legibilidad. [24] La documentación del estilo de codificación del núcleo de Linux también desaconseja este estilo, instando a los lectores a grabar una copia de los estándares de codificación de GNU como un "gran gesto simbólico". [11]
La edición de 1997 de Computing Concepts with C++ Essentials de Cay S. Horstmann adapta Allman colocando la primera declaración de un bloque en la misma línea que la llave de apertura. Este estilo también se utiliza en ejemplos del Manual de usuario y reporte de Pascal de Jensen y Wirth . [30]
mientras ( x == y ) { algo (); algo_más (); //... si ( x < 0 ) { printf ( "Negativo" ); negativo ( x ); } más { printf ( "No negativo" ); no negativo ( x ); } } cosa_final ();
Este estilo combina las ventajas del estilo Allman, ya que conserva la alineación vertical de las llaves para facilitar la lectura y permite identificar fácilmente los bloques, además de ahorrar una línea del estilo K&R. Sin embargo, la edición de 2003 ahora utiliza el estilo Allman en todo el texto. [31]
Este es el estilo que utilizan con más frecuencia los diseñadores del lenguaje Pico . Pico carece de declaraciones de retorno y utiliza puntos y coma como separadores de declaraciones en lugar de terminadores. Esto produce esta sintaxis: [32]
cosa(n):{ x: 3 * n; y: hacer_cosas(x); y + x }
Las ventajas y desventajas son similares a las de ahorrar espacio en la pantalla con el estilo K&R. Una ventaja adicional es que las llaves de inicio y cierre son consistentes en la aplicación (ambas comparten espacio con una línea de código), en comparación con el estilo K&R, donde una llave comparte espacio con una línea de código y la otra tiene una línea sola.
En el libro Programmers at Work , [33] C. Wayne Ratliff, el programador original detrás de los populares lenguajes de programación de cuarta generación dBase -II y -III , discutió un estilo que es como 1TBS pero la llave de cierre se alinea con la sangría del bloque anidado. Indicó que el estilo fue documentado originalmente en material de Digital Research Inc. Este estilo a veces se ha denominado estilo banner , [34] posiblemente por la semejanza con un banner colgado de un poste. En este estilo, que es a Whitesmiths lo que K&R es a Allman, el control de cierre está sangrado igual que el último elemento de la lista (y por lo tanto pierde prominencia apropiadamente) [24] El estilo puede hacer que el escaneo visual sea más fácil para algunos, ya que los encabezados de cualquier bloque son lo único que se extiende a ese nivel (la teoría es que el control de cierre del bloque anterior interfiere con el flujo visual del siguiente encabezado de bloque en los estilos K&R y Allman). Kernighan y Plauger utilizan este estilo en el código Ratfor en Herramientas de software . [35]
// En C para ( i = 0 ; i < 10 ; i ++ ) { si ( i % 2 == 0 ) { hacer_algo ( i ); } de lo contrario { hacer_algo_más ( i ); } }
Los siguientes estilos son comunes para varios lenguajes derivados de C que son significativamente similares y diferentes. Y también se pueden adaptar a C. Se pueden aplicar a código C escrito como parte de un proyecto escrito principalmente en uno de estos otros lenguajes, donde mantener una apariencia consistente con el código central del proyecto prevalece sobre las consideraciones de usar un estilo C más convencional.
Aunque el estilo GNU se caracteriza a veces como código C sangrado por un programador Lisp, uno podría incluso llegar al extremo de insertar llaves de cierre juntas en la última línea de un bloque. Este estilo hace que la sangría sea la única forma de distinguir bloques de código, pero tiene la ventaja de no contener líneas que no proporcionen información. Esto podría fácilmente llamarse el estilo Lisp porque es muy común en el código Lisp. En Lisp, la agrupación de llaves idénticas al final de los árboles de expresión tiene como objetivo indicar que no es tarea del usuario realizar un seguimiento visual de los niveles de anidación, sino solo comprender la estructura del árbol.
La variante tradicional de Lisp de este estilo prefiere niveles de sangría extremadamente estrechos (normalmente dos espacios) porque el código de Lisp suele estar anidado muy profundamente, ya que Lisp solo presenta expresiones , sin una clase distinta de declaraciones ; los argumentos de función suelen estar sangrados al mismo nivel para ilustrar su estado compartido dentro de la expresión que los contiene. Esto también se debe a que, dejando de lado las llaves, Lisp es convencionalmente un lenguaje muy conciso, que omite incluso formas comunes de código repetitivo simple por considerarlas poco informativas, como la else
palabra clave en un if : then | else
bloque, y en su lugar las presenta de manera uniforme como (if expr1 expr2 expr3)
.
// C para ( i = 0 ; i < 10 ; i ++ ) { si ( i % 2 == 0 ) { hacer_algo ( i );} de lo contrario { hacer_algo_más ( i ); hacer_una_tercera_cosa ( i );}}
;; Lisp ( dotimes ( i 10 ) ( if ( = ( rem i 2 ) 0 ) ( hacer-algo i ) ( progn ( hacer-algo-más i ) ( hacer-tercera-cosa i ))))
Nota: progn
es un procedimiento para evaluar múltiples subexpresiones de forma secuencial para efectos , mientras se descartan todos los valores de retorno excepto el último (n-ésimo). Si se desean todos los valores de retorno, values
se utilizaría el procedimiento.
El diseño de Haskell puede hacer que la colocación de llaves sea opcional, aunque las llaves y los puntos y comas están permitidos en el lenguaje. [36] Los dos segmentos siguientes son igualmente aceptables para el compilador:
sin llaves = hacer texto <- obtenerContenidos dejar primeraPalabra = cabeza $ palabras texto palabraGranDelta = mapear aUpper primeraPalabra putStrLn palabraGranDelta braceful = do { texto <- getContents ; let { firstWord = head $ words texto ; bigWord = map toUpper firstWord } ; putStrLn bigWord }
En Haskell, el diseño puede reemplazar las llaves. Por lo general, las llaves y los puntos y comas se omiten en las secciones de procedimientos do
y en el texto del programa en general, pero el estilo se usa comúnmente para listas, registros y otros elementos sintácticos compuestos por algún par de paréntesis o llaves, que se separan con comas o puntos y comas. [37] Si el código que sigue a las palabras clave where
, let
, o of
omite las llaves y los puntos y comas, entonces la sangría es importante. [38]
Para ver un ejemplo de lo conciso que suele ser APL, aquí está la implementación de la función de paso para el Juego de la Vida:
vida ← { ⊃ 1 ⍵ ∨ . ∧ 3 4 =+ / + ⌿ ¯1 0 1 ∘. ⊖ ¯1 0 1 ⌽ ¨ ⊂ ⍵ }
El estilo C de APL se asemeja al estilo conciso del código APL y se usa comúnmente en sus implementaciones. [39] Este estilo fue iniciado por Arthur Whitney y se usa mucho en la implementación de K , el propio proyecto de Arthur. El lenguaje de programación J también se implementa en este estilo. Cabe destacar que no todas las implementaciones de APL usan este estilo de C, a saber: GNU APL y Dyalog APL.
Además de la sangría del estilo APL C, normalmente los nombres se acortan a caracteres simples o dobles: para reducir la cantidad de sangría y expresiones que abarcan varias líneas. [40]
Python no utiliza llaves. La sangría define los bloques en lo que se denomina la regla del lado opuesto .
para i en rango ( 10 ): si i % 2 == 0 : hacer_algo ( i ) de lo contrario : hacer_algo_más ( i ) hacer_tercera_cosa ( i )
Por lo general, la sangría es de cuatro espacios. También se pueden utilizar tabulaciones. [41]
Normalmente, los programadores utilizan el mismo ancho de espacio para sangrar cada bloque de código; los anchos comúnmente utilizados varían de 1 a 4 espacios.
Un experimento realizado en código PASCAL en 1983 descubrió que el tamaño de la sangría afectaba significativamente la comprensión. Los tamaños de sangría entre 2 y 4 caracteres resultaron óptimos. [42]
Aunque ambos afectan el diseño general del código, el tamaño de la sangría es independiente del estilo de sangría analizado aquí.
Por lo general, un programador utiliza un editor de texto que proporciona tabulaciones a intervalos fijos (una cantidad de espacios) para ayudar a mantener los espacios en blanco de acuerdo con un estilo. El intervalo se denomina ancho de tabulación . A veces, el programador almacena el código con caracteres de tabulación (uno por cada pulsación de tecla de tabulación) o almacena una secuencia de espacios igual en número al ancho de tabulación.
El almacenamiento de caracteres de tabulación en el código puede provocar una desalineación visual cuando se visualizan en diferentes contextos, lo que contrarresta el valor del estilo de sangría.
Los programadores no están de acuerdo en almacenar caracteres de tabulación. Los defensores de almacenar caracteres de tabulación citan la facilidad de escritura y los archivos de texto más pequeños, ya que un solo carácter de tabulación sirve para el propósito de múltiples espacios. Los oponentes, como Jamie Zawinski , afirman que el uso de espacios en su lugar aumenta la portabilidad entre plataformas . [43] Otros, como los autores de los estándares de codificación de WordPress , afirman lo contrario: que las tabulaciones duras aumentan la portabilidad. [44] Una encuesta de los 400.000 repositorios principales en GitHub descubrió que los espacios son más comunes. [45]
Muchos editores de texto, incluidos Notepad++ , TextEdit , Emacs , vi y nano , pueden configurarse para almacenar caracteres de tabulación cuando se ingresan mediante la tecla de tabulación o para convertirlos en espacios (según el ancho de tabulación configurado) de modo que los caracteres de tabulación no se agreguen al archivo cuando se presiona la tecla de tabulación. Algunos editores pueden convertir caracteres de tabulación en espacios y viceversa.
Algunos paginadores de archivos de texto , como less , se pueden configurar para un ancho de tabulación. Algunas herramientas, como expandir / desampliar, pueden convertir sobre la marcha mediante filtros.
Una herramienta puede automatizar el formato de código según un estilo de sangría, por ejemplo, el comando Unix . indent
Emacs proporciona comandos para modificar la sangría, incluyendo pulsar Tab
sobre una línea determinada. M-x indent-region
sangra el código.
Las tabulaciones elásticas son un estilo de tabulación que requiere soporte del editor de texto, donde bloques enteros de texto se mantienen alineados automáticamente cuando cambia la longitud de una línea en el bloque.
En códigos más complejos, el programador puede perder de vista los límites de los bloques mientras lee el código. Esto suele ocurrir en secciones extensas de código que contienen muchas sentencias compuestas anidadas en muchos niveles de sangría. A medida que el programador se desplaza hasta el final de un conjunto enorme de sentencias anidadas, puede perder de vista el contexto, como la estructura de control en la parte superior del bloque.
Las declaraciones compuestas largas pueden ser un código con olor a complejidad excesiva que se puede solucionar mediante refactorización .
Los programadores que dependen del recuento de las llaves de apertura pueden tener dificultades con estilos de sangría como K&R, donde la llave de inicio no está separada visualmente de su declaración de control . Los programadores que dependen más de las sangrías obtendrán más beneficios de los estilos que son verticalmente compactos, como K&R, porque los bloques son más cortos.
Para evitar perder el rastro de las instrucciones de control como for
, se puede utilizar una sangría grande, como una tabulación dura de 8 unidades de ancho, además de dividir las funciones grandes en funciones más pequeñas y más legibles. Linux lo hace de esta manera, mientras utiliza el estilo K&R.
Algunos editores de texto permiten al programador saltar entre las dos llaves correspondientes de un bloque. Por ejemplo, vi salta a la llave que encierra el mismo bloque que el que está bajo el cursor al presionar la %
tecla. Dado que la next
tecla del cursor de texto (es decir, la n
tecla) retuvo la información de posicionamiento direccional (si la tecla up
o down
se presionó anteriormente), la macro de punto (la .
tecla) podría usarse para colocar el cursor de texto en la siguiente llave, [46] dado un estilo de codificación adecuado. En cambio, la inspección de los límites de bloque usando la %
tecla se puede utilizar para aplicar un estándar de codificación.
Otra forma de mantener la conciencia de los bloques es utilizar comentarios después de la llave de cierre. Por ejemplo:
para ( int i = 0 ; i < total ; i ++ ) { foo (); } //para (i)
si ( x < 0 ) { barra (); } //si (x < 0)
Una desventaja es mantener el mismo código en múltiples ubicaciones, encima y debajo del bloque.
Algunos editores ofrecen soporte para mantener la conciencia de los bloques. Un editor plegable puede ocultar (plegar) y revelar (desplegar) bloques por nivel de sangría. Algunos editores resaltan las llaves coincidentes cuando el cursor se coloca junto a una de ellas.
El estilo K&R evita el error común que se produce al insertar una línea de código después de una sentencia de control, antes de la llave de apertura. La línea insertada hace que el bloque se desasocie de la sentencia de control.
Dado este código de inicio:
para ( int i = 0 ; i < 10 ; i ++ ) { hacer_algo (); } //para (i)
do_something
Se llamará 10 veces. Luego se modifica agregando una segunda línea nueva:
para ( int i = 0 ; i < 10 ; i ++ ) hacer_algo_más ();{ do_something (); //¡llamado una vez! } //para (i)
El bloque original (líneas 3 a 5) ya no es el cuerpo del for
bucle y se ejecuta solo una vez. Además, el comentario de la línea 5 se vuelve incorrecto.
El estilo K&R evita este problema manteniendo la declaración de control y la llave de apertura en la misma línea.
Original:
para ( int i = 0 ; i < 10 ; i ++ ) { hacer_algo ();} //para (i)
Agregar una nueva segunda línea no afecta la cantidad de veces do_something
que se llama ni la validez del comentario final.
para ( int i = 0 ; i < 10 ; i ++ ) { hacer_algo_más (); hacer_algo ();} //para (i)
Se aceptan llaves "egipcias" o llaves de estilo C.
humorístico [
sic
] para el estilo de sangría de K&R, que hace referencia a la pose de "una mano arriba al frente, otra abajo detrás".
Las llaves siguen el estilo Kernighan y Ritchie ("corchetes egipcios") para bloques no vacíos y construcciones similares a bloques
emacs --no-init-file
.