2009-02-12 24 views
14

En el lenguaje de programación C, entiendo que las variables solo se pueden definir al comienzo de un bloque de código, y la variable tendrá el alcance del bloque en el que se declaró. Con eso en mente, me preguntaba si se considera una mala práctica para crear artificialmente un nuevo ámbito como en este ejemplo:¿Es correcto (VERDADERO) una buena idea en C?

void foo() 
{ 
    ... Do some stuff ... 

    if(TRUE) 
    { 
     char a; 
     int b; 

     ... Do some more stuff ... 
    } 

    ... Do even more stuff ... 
} 

Suponiendo TRUE se pone a 1 en una definición de macro, sería este código se considera 'buena código' o se hacen los programadores experimentados se encogen ¿Solo con pensarlo?

¡Gracias por su contribución!

EDITAR: En respuesta a algunas de las respuestas, el código con el que estoy trabajando necesita trabajar con algunos sistemas antiguos muy antiguos. Si bien sería bueno operar con una suposición de C99, realmente no podemos garantizar que lo tendrán.

+0

afaik, {} tiene su propio alcance sine ansi C (alrededor de 1990) – George

+0

El caso de uso típico para esto es la depuración, donde puede cambiar fácilmente entre if (42) y if (0) en lugar de comentar. – ypnos

+0

Su título realmente no describe la pregunta en absoluto. Parece como si estuvieras preguntando si es una buena práctica definir VERDADERO. – BobbyShaftoe

Respuesta

49

Ni siquiera necesita una instrucción if. Puede crear bloques con {}

Sin embargo, esa debería ser una función independiente.

Ejemplo aquí:

#include <stdio.h> 

int 
main(int argc, char **argv) { 
    int i = 0; 
    { 
     int i = 10; 
     printf("%d\n", i); 
    } 
    printf("%d\n", i); 
} 
+0

¿Se ha utilizado alguna vez en el código de producción? Mi idea es que quiero tener acceso a todas las variables en la función existente, pero algunas variables nuevas se aplican solo a una sección pequeña. Una función significaría que tendría que pasar un montón de variables, y agregar las variables a la función principal ... – Tim

+0

... saturaría las variables existentes de la función – Tim

+0

. Mi empresa usa esto extensivamente. Solía ​​estar realmente en contra cuando comencé a trabajar aquí, pero ahora me gusta. Sin embargo, todavía no me gusta la forma en que lo usamos, que generalmente consiste en dividir fragmentos de funciones de 1000 líneas que deberían ser su propia función ... – rmeador

7

Probablemente desee crear una nueva función para ese alcance.
Si realmente necesita tener su propio alcance, es probable que sea una función lógica separada de todos modos.

+2

No necesariamente. A menudo he encontrado una necesidad de una variable altamente local (con un buen nombre mnemónico) para mantener un valor intermedio de solo unas pocas líneas. Al usar un ámbito anidado, deja claro su uso previsto (restringido). –

3

No me llamaría sazonado, pero estoy un poco encogido.

Mi problema es que la declaración if llevaría a alguien a creer que algo realmente se está evaluando ... pero en el tiempo de ejecución, la macro es verdadera o falsa, no hay cambio de que sea otra cosa. Debe incluir el código o no.

Si lo que quiere decir que hacer es algo así como DEBUG #ifdef entonces usted debe hacer eso para indicar al lector que se trata de depurar el código ...

+0

La macro se evalúa en tiempo de compilación, no en tiempo de ejecución. –

2

No creo que necesite el caso de (verdadero) parte.

Solo se necesita {} para delimitar las variables.

2

Mi respuesta es la siguiente:

Esto hace que los programadores experimentados estremecen con la sola idea de ella.

6

Ya que puede simplemente hacer el bloque de alcance sin el if, esa es una mejor idea.

void foo() { 
    ... Do some stuff ... 
    { 
     char a; 
     int b; 
     ... Do some more stuff ... 
    } 
    ... Do even more stuff ... 
} 
16

Por lo que sé, puede crear un alcance sin if.

Use sólo las llaves como esta:

{ 
    int x; 

} 

y recomiendo contra

if (TRUE) 

ya que dificulta la legibilidad.

+6

especialmente si #define TRUE 0 –

4

Se puede quitar el

if(TRUE) 

y acaba de salir de las llaves, que por sí mismos a definir un nuevo bloque sintáctico - un compound statement.

Esto es definitivamente más limpio que el falso si lo había hecho antes, pero aún podría preguntarse por qué quiere crear un nuevo bloque: ¿sería mejor definir una subrutina?

5

Antes que nada, un bloque nuevo no necesita ser un bloque if. Podría ser simplemente una sección de código entre llaves, como esto:

void foo() { 
... Do some stuff ... 

{ 
    char a; 
    int b; 

    ... Do some more stuff ... 
} 

... Do even more stuff ... 
} 

En segundo lugar, en cualquier moderna compilador de C que cumple con el estándar C (creo C99), puede declarar variables en cualquier parte del bloquear, por lo que no es necesario crear un nuevo bloque en absoluto.

3

dejando la puerta abierta para algunas personas creativas:

#define TRUE 0 
#define FALSE 1 

sólo tiene que utilizar los frenos para declarar el alcance.

1

C99 le permite declarar variables en casi cualquier lugar. Sin embargo, absténgase de hacerlo sin una muy buena razón. Intenta primero dividir tu función en funciones más pequeñas (posiblemente en línea).

El único lugar donde tal cosa podría tener sentido es cuando tiene una variable que se inicializa en el medio de su función, p. similar a crear un objeto en C++.

+0

No estoy seguro de por qué dices que te abstengas de hacerlo. Si necesito un simple int o char, parece más limpio declararlo cerca del código que va a usarlo, en lugar de enviarlo a la parte superior de la función. ¿A qué me rindo haciendo esto? – rtperson

+0

Declarar variables en el punto de primer uso se considera una buena práctica en C++. ¿Por qué no en C99? –

+0

@David Thornley: C generalmente permite al programador escribir funciones muy largas, más que C++ debido a la falta de características de lenguaje OOP. Tener muchas variables al inicio de una función es una buena señal de que es demasiado largo. La práctica puede ser un hábito. Pero declarar justo antes del primer uso puede ser legítimo –

1

Creo que estás trabajando con algunas suposiciones obsoletas. He estado codificando C directamente usando GCC durante algunos meses, y no necesita declarar variables al principio de un bloque, aunque la Segunda edición de K & R dice que debe hacerlo. Se puede declarar su dondequiera variables, al igual que como en este ejemplo no muy útil:

char* palstring; 
palstring = malloc(LARGEST_STRING); 
memset(palstring, 0, sizeof palstring); 
fgets(palstring, LARGEST_STRING, fin); 

char* cur = palstring; 
char letter; 
letter = *cur; 

Así que no hay necesidad de hacer lo que sugieres. El lenguaje ha avanzado.

Otra buena adición al lenguaje C es Arrays de longitud variable, que le permiten pasar una matriz a una función junto con su tamaño. En los viejos tiempos, todo lo que podías hacer era pasar un puntero.

+0

Las matrices de longitud variable de gcc cuidadosas no son C99 estándar –

+0

Ah, es bueno saberlo. Gracias. Lo uso principalmente para tontear por mi cuenta, así que no estoy demasiado preocupado, pero si alguna vez tengo que usarlo profesionalmente, te debo una cerveza. :) – rtperson

4

Como ya han dicho muchas respuestas, no necesita las cosas "si". Solo crea el bloque desnudo. Pero quiero llegar a otro punto. En C, puede crear declaraciones de variables en cualquier lugar de un bloque, no solo al comienzo. En C89, tuviste esa restricción. Comenzando con C99 (eso es 10 años ahora), ya no tienes esa restricción, aunque algunos compiladores se quejarán de todos modos. Sin embargo, GCC no lo hará si le dice que use el estándar C más reciente con la opción -std = c99.

Como todavía existen compiladores que se quejan por defecto, no me gustaría mezclar declaraciones y código. Seguiría poniendo declaraciones al comienzo de los bloques por razones de compatibilidad.

+0

Sí, creo que esta mala práctica en C. Si compilas con -Wall -ansi -pedantic, recibirás advertencias. Mi regla de oro es que si no pasa esas banderas limpias, generalmente es incorrecto. – BobbyShaftoe

+0

BobbyShaftoe. bueno, ese es un punto válido pero no creo que sea una mala práctica Evito usar -Werror precisamente porque a veces el compilador puede advertir erróneamente. entonces, si advierte de "... {...} ..." que se comenta correctamente, es un falso positivo para mí. –

6

Tenga en cuenta que en C99 se permite declarar variables locales en el medio de bloques.

C99 es la versión del estándar C del año 1999; la mayoría de los compiladores de C modernos lo soportan.

1

Suponiendo que utiliza un compilador antiguo (como yo, es para hardware antiguo), que omita el if (TRUE) como otros han sugerido, y que tiene una función realmente ENORME (que no debería tener en el primer lugar), entonces creo que está algo bien. Lo he hecho pero no me sentía bien ...

1

Aparentemente soy una minoría, pero me parece mucho más difícil leer "llaves" porque se desvía del patrón habitual. En las ocasiones (la verdad poco frecuentes) en el que necesito un bloque de ámbito sin definir otra función, prefiero incluir el "si", pero sin ninguna macro y con un comentario que explique por qué:

if(1) // just to establish scope 
{ 
    // do stuff here 
} 
2

apenas define sus variables al comienzo del bloque o usa otra función. Agregar un ámbito artificial con {} s vacías o cualquiera de las alternativas no es una buena práctica.

Cuestiones relacionadas