A menudo veo en el código C y C ++ la siguiente convención:
some_type val;
val = something;
some_type *ptr = NULL;
ptr = &something_else;
en lugar de
some_type val = something;
some_type *ptr = &something_else;
Inicialmente supuse que este era un hábito que quedaba de los días en que tenía que declarar todas las variables locales en la parte superior del alcance. Pero he aprendido a no descartar tan rápidamente los hábitos de los desarrolladores veteranos. Entonces, ¿hay una buena razón para declarar en una línea y asignar después?
Respuestas:
C
En C89, todas las declaraciones tenían que estar al principio de un alcance (
{ ... }
), pero este requisito se eliminó rápidamente (primero con las extensiones del compilador y luego con el estándar).C ++
Estos ejemplos no son lo mismo.
some_type val = something;
llama al constructor de la copia mientrasval = something;
llama al constructor predeterminado y luego a laoperator=
función. Esta diferencia es a menudo crítica.Hábitos
Algunas personas prefieren declarar primero las variables y luego definirlas, en el caso de que vuelvan a formatear su código más tarde con las declaraciones en un lugar y la definición en otro.
Sobre los punteros, algunas personas simplemente tienen la costumbre de inicializar cada puntero
NULL
onullptr
, sin importar lo que hagan con ese puntero.fuente
some_type
constructor tomandosomething
como único argumento. Este es un caso marginal muy interesante e inusual en C ++ ... significa que existe una presunción sobre el significado semántico de estas operaciones.Ha etiquetado su pregunta C y C ++ al mismo tiempo, mientras que la respuesta es significativamente diferente en estos lenguajes.
En primer lugar, la redacción del título de su pregunta es incorrecta (o, más precisamente, irrelevante para la pregunta en sí). En ambos ejemplos, la variable se declara y define simultáneamente, en una línea. La diferencia entre sus ejemplos es que en el primero las variables se dejan sin inicializar o se inicializan con un valor ficticio y luego se le asigna un valor significativo más adelante. En el segundo ejemplo, las variables se inicializan de inmediato.
En segundo lugar, en lenguaje C ++, como señaló @nightcracker en su respuesta, estas dos construcciones son semánticamente diferentes. El primero se basa en la inicialización, mientras que el segundo, en la asignación. En C ++, estas operaciones son sobrecargables y, por lo tanto, pueden conducir a resultados diferentes (aunque se puede observar que producir sobrecargas no equivalentes de inicialización y asignación no es una buena idea).
En el lenguaje C estándar original (C89 / 90) es ilegal declarar variables en el medio del bloque, por lo que es posible que vea variables declaradas sin inicializar (o inicializadas con valores ficticios) al comienzo del bloque y luego asignadas significativas valores posteriores, cuando esos valores significativos estén disponibles.
En lenguaje C99 está bien declarar variables en el medio del bloque (al igual que en C ++), lo que significa que el primer enfoque solo es necesario en algunas situaciones específicas cuando el inicializador no se conoce en el punto de declaración. (Esto también se aplica a C ++).
fuente
some_type val;
inmediatamente la variable . Esto es lo que quise decir en mi respuesta.val
Creo que es un viejo hábito, sobrante de los tiempos de "declaración local". Y por lo tanto, como respuesta a su pregunta: No, no creo que haya una buena razón. Nunca lo hago yo mismo.
fuente
Dije algo sobre eso en mi respuesta a una pregunta de Helium3 .
Básicamente, digo que es una ayuda visual para ver fácilmente lo que ha cambiado.
y
fuente
Las otras respuestas son bastante buenas. Hay algo de historia en torno a esto en C. En C ++ existe la diferencia entre un constructor y un operador de asignación.
Me sorprende que nadie mencione el punto adicional: mantener las declaraciones separadas del uso de una variable a veces puede ser mucho más legible.
Hablando visualmente, al leer el código, los artefactos más mundanos, como los tipos y nombres de variables, no son lo que te llama la atención. Son las declaraciones las que generalmente te interesan más, pasas la mayor parte del tiempo mirando y, por lo tanto, hay una tendencia a echar un vistazo al resto.
Si tengo algunos tipos, nombres y tareas, todo en el mismo espacio reducido, es un poco de sobrecarga de información. Además, significa que algo importante está sucediendo en el espacio que generalmente miro.
Puede parecer un poco contradictorio decirlo, pero esta es una instancia en la que hacer que su fuente ocupe más espacio vertical puede mejorarlo. Veo esto como una razón por la que no deberías escribir líneas repletas que hacen cantidades locas de aritmética y asignación de punteros en un espacio vertical apretado, solo porque el lenguaje te permite salirte con la tuya no significa que debas hacerlo todo el tiempo :-)
fuente
En C, esta era la práctica estándar porque las variables debían declararse al comienzo de la función, a diferencia de C ++, donde podía declararse en cualquier parte del cuerpo de la función para ser utilizada posteriormente. Los punteros se establecieron en 0 o NULL, porque solo se aseguró de que el puntero no señalara basura. De lo contrario, no hay una ventaja significativa en la que pueda pensar, lo que obliga a cualquiera a hacer eso.
fuente
Pros para localizar definiciones de variables y su inicialización significativa:
Si a las variables se les asigna habitualmente un valor significativo cuando aparecen por primera vez en el código (otra perspectiva sobre lo mismo: retrasas su aparición hasta que un valor significativo esté disponible), entonces no hay posibilidad de que se usen accidentalmente con un valor sin sentido o sin inicializar ( lo que puede suceder fácilmente si se omite accidentalmente alguna inicialización debido a declaraciones condicionales, evaluación de cortocircuito, excepciones, etc.)
puede ser más eficiente
operator=
a veces puede ser menos eficiente y requerir un objeto temporalminimizar el alcance de las variables a su vez minimiza el número promedio de variables simultáneamente en el alcance : esto
a veces más conciso ya que no estás repitiendo el nombre de la variable en una definición que en una asignación inicial significativa
necesario para ciertos tipos, como referencias y cuando desea que el objeto sea
const
Argumentos para agrupar definiciones de variables:
a veces es conveniente y / o conciso factorizar el tipo de una serie de variables:
the_same_type v1, v2, v3;
(si la razón es solo que el nombre del tipo es demasiado largo o complejo, a
typedef
veces puede ser mejor)a veces es deseable agrupar variables independientemente de su uso para enfatizar el conjunto de variables (y tipos) involucrados en alguna operación:
type v1;
type v2;
type v3;
Esto enfatiza la similitud del tipo y hace que sea un poco más fácil cambiarlos, sin dejar de seguir una variable por línea que facilita copiar, pegar,
//
comentar , etc.Como suele ser el caso en la programación, si bien puede haber un beneficio empírico claro para una práctica en la mayoría de las situaciones, la otra práctica puede ser abrumadoramente mejor en algunos casos.
fuente