Supongamos que quiero escribir una función que concatene dos cadenas en C. La forma en que lo escribiría es:
void concat(char s[], char t[]){
int i = 0;
int j = 0;
while (s[i] != '\0'){
i++;
}
while (t[j] != '\0'){
s[i] = t[j];
i++;
j++;
}
s[i] = '\0';
}
Sin embargo, K&R en su libro lo implementó de manera diferente, particularmente incluyendo tanto en la parte de condición del ciclo while como sea posible:
void concat(char s[], char t[]){
int i, j;
i = j = 0;
while (s[i] != '\0') i++;
while ((s[i++]=t[j++]) != '\0');
}
¿Qué camino se prefiere? ¿Se recomienda o desaconseja escribir código como lo hace K&R? Creo que mi versión sería más fácil de leer por otras personas.
programming-practices
coding-style
Richard Smith
fuente
fuente
while (*s++ = *t++);
(Mi C está muy oxidada, ¿necesito padres allí para la precedencia del operador?) ¿K&R lanzó una nueva versión de su libro? Su libro original tenía un código extremadamente conciso e idiomático.'\0'
det
(laswhile
salidas primero). Esto dejará las
cadena resultante sin terminar'\0'
(a menos que la ubicación de la memoria ya esté puesta a cero). El segundo bloque de código hará la copia de la terminación'\0'
antes de salir delwhile
bucle.Respuestas:
Siempre prefiera la claridad sobre la inteligencia. En antaño, el mejor programador era aquel cuyo código nadie podía entender. "No puedo entender su código, debe ser un genio" , dijeron. Hoy en día, el mejor programador es aquel cuyo código cualquiera puede entender. El tiempo de la computadora es más barato ahora que el tiempo del programador.
Entonces, sin duda, iría por la opción A. Y esa es mi respuesta definitiva.
fuente
if (a=b)
puede confundirse fácilmente con esoif (a==b)
.while ((c = fgetc(file)) != EOF)
como el primero que me viene a la mente.La regla de oro, igual que en la respuesta de Tulains Córdova, es asegurarse de escribir un código inteligible. Pero no estoy de acuerdo con la conclusión. Esa regla de oro significa escribir código que pueda entender el programador típico que terminará manteniendo su código. Y usted es el mejor juez sobre quién es el programador típico que terminará manteniendo su código.
Para los programadores que no comenzaron con C, la primera versión es probablemente más fácil de entender, por razones que ya saben.
Para aquellos que crecieron con ese estilo de C, la segunda versión puede ser más fácil de entender: para ellos, es igualmente comprensible lo que hace el código, para ellos, deja menos preguntas de por qué está escrito de la manera en que está, y para ellos , menos espacio vertical significa que se puede mostrar más contexto en la pantalla.
Tendrás que confiar en tu buen sentido común. ¿Para qué audiencia desea que su código sea más fácil de entender? ¿Este código está escrito para una empresa? Entonces el público objetivo es probablemente los otros programadores de esa compañía. ¿Es este un proyecto de pasatiempo personal en el que nadie trabajará excepto usted? Entonces eres tu propio público objetivo. ¿Es este código que quieres compartir con otros? Entonces esos otros son su público objetivo. Elija la versión que coincida con esa audiencia. Desafortunadamente, no hay una sola forma preferida de alentar.
fuente
EDITAR: La línea
s[i] = '\0';
se agregó a la primera versión, corrigiéndola como se describe en la variante 1 a continuación, por lo que esto ya no se aplica a la versión actual del código de la pregunta.La segunda versión tiene la ventaja distintiva de ser correcta , mientras que la primera no lo es: no termina la cadena objetivo correctamente.
La "asignación en condición" permite expresar el concepto de "copiar cada carácter antes de verificar el carácter nulo" de manera muy concisa y de una manera que hace que la optimización para el compilador sea algo más fácil, aunque muchos ingenieros de software en estos días encuentran que este estilo de código es menos legible . Si insiste en usar la primera versión, tendría que
fuente
Las respuestas de Tulains Córdova y hvd cubren bastante bien los aspectos de claridad / legibilidad. Permítanme incluir el alcance como otra razón a favor de las asignaciones en condiciones. Una variable declarada en la condición solo está disponible en el alcance de esa declaración. No puede usar esa variable después por accidente. El ciclo for ha estado haciendo esto por siglos. Y es lo suficientemente importante como para que el próximo C ++ 17 introduzca una sintaxis similar para if y switch :
fuente
No. Es un estilo C muy estándar y normal. Su ejemplo es malo, porque debería ser un bucle for, pero en general no hay nada de malo en
por ejemplo (o con while).
fuente
!= NULL
.(x != NULL) != 0
. Después de todo, eso es lo que C realmente está comprobando, ¿verdad?En los días de K&R
while ((s[i++]=t[j++]) != '\0')
se asignarían a una instrucción en la mayoría de las CPU (espero que el VAC de diciembre)Hay dias
(Una nota sobre el uso de llaves siempre: el primer conjunto de código ocupa más espacio debido a que tiene algunos "innecesarios"
{}
, en mi experiencia, a menudo evitan que el código se haya fusionado mal del compilador y permiten errores con ubicaciones incorrectas ";" detectado por herramientas.)Sin embargo, en los viejos tiempos la segunda versión del código habría leído. (¡Si lo hice bien!)
fuente
Incluso poder hacer esto es una muy mala idea. Se le conoce coloquialmente como "El último error del mundo", así:
Si bien es probable que no cometa un error que es tan grave, es muy fácil equivocarse accidentalmente y causar un error difícil de encontrar en su base de código. La mayoría de los compiladores modernos insertarán una advertencia para las asignaciones dentro de un condicional. Están allí por una razón, y harías bien en prestarles atención y simplemente evitar esta construcción.
fuente
CODE_RED = alert
para que se produjera un error de compilación.Ambos estilos están bien formados, son correctos y apropiados. Cuál es más apropiado depende en gran medida de las pautas de estilo de su empresa. Los IDE modernos facilitarán el uso de ambos estilos mediante el uso de la sintaxis en vivo que resalta explícitamente áreas que de otro modo podrían haberse convertido en una fuente de confusión.
Por ejemplo, Netbeans resalta la siguiente expresión :
por motivos de "asignación accidental".
Para decirle explícitamente a Netbeans que "sí, realmente tenía la intención de hacer eso ...", la expresión puede estar entre paréntesis.
Al final del día, todo se reduce a las pautas de estilo de la empresa y la disponibilidad de herramientas modernas para facilitar el proceso de desarrollo.
fuente