2010-11-21 9 views
6

Esta pregunta vino a la mente después de ver este simple trozo de código: (? K & R)¿Se deben omitir los métodos abreviados, la brevedad y la astucia rutinariamente a favor de la claridad?

if (!x%y) 
{ 
    // do something 
} 

Tal vez sea la influencia de los primeros libros de C, pero no es lo siguiente siempre se prefiere, si no tan linda ?

if (x%y != 0) 
{ 
    // do something 
} 
+3

Absolutamente, solo tenga cuidado de obtener la lógica correcta, ya que su primer ejemplo no es equivalente a su segundo ejemplo. –

+1

sí, tenga cuidado con el orden de las operaciones. –

+0

No hace ninguna diferencia para el compilador y el código generado será absolutamente idéntico. Por lo tanto, debes escribir tu fuente para que sea lo más clara posible para los humanos. –

Respuesta

7

This quote responde a su pregunta.

"La depuración es dos veces más duro que escribir el código en el primer lugar. Por lo tanto, si se escribe el código como inteligente posible, usted es, por definición, no lo suficientemente inteligente para depurarlo se " - Brian W. Kernighan

+0

No, no es así. El OP no está hablando de la codificación "tan hábilmente como sea posible", sino que está hablando de este caso específico de uso de '!' Contra '! = 0'. (Además, ¿hubiera sido demasiado difícil poner la cita aquí?) –

+0

Creo (debido al título) que el OP está hablando de inteligencia versus brevedad en general, y utilizando la expresión de módulo como ejemplo. –

+0

@Billy - Creo que sí. Al leer la pregunta en sí, está claro que está hablando de ser inteligente en general. El cuerpo de la publicación es solo un ejemplo específico. Aunque estoy de acuerdo en que debería simplemente poner la cita aquí, arreglada. –

2

Prefieren la claridad sobre la brevedad. El segundo ejemplo x % y != 0 es más claro.

Por supuesto, lo que constituye claridad es algo subjetivo, pero prefiero reservar el operador ! único para variables booleanas o funciones que devuelven booleano.

La forma en que generalmente trato de medir la claridad mientras escribo el código es preguntándome a mí mismo: ¿podría leer y entender fácilmente esta línea si 1) alguien más la escribió o 2) tuve que volver a leerla hace 2 años? abajo de la línea.

2

La astucia debe omitirse. No es inteligente ... o más importante es mantenible.

Los accesos directos y la brevedad pueden o no ser aceptables: todos tomamos atajos pero hay atajos casi "estándar de la industria" porque todos lo hacemos. Sin atajos inteligentes aunque

5

¿Estás seguro de ese código? !x%y significa (!x)%y porque ! se une más apretado que %.

(Sólo por esa razón, yo preferiría x % y != 0.)

1

Clarity gana sobre la brevedad todos los días, en mi opinión. A veces siento que escribir código como:

if(!(x = func(y)) && ++z == x) 

... es el equivalente a rayas más rápidas en un automóvil. Puede sentirse rápido, pero no lo es. Tampoco creo que usar nombres de variables incomprensibles (como en el ejemplo anterior) para ahorrar en tipeo sea una buena idea.

¿Cuál es mejor aquí:

for(int x(0) x < managers.size(); ++x) 
    managers[x]->initialise(); 

o:

for(int mgr(0); mgr < managers.size(); ++mgr) 
    managers[mgr]->initialise(); 

Ambos logran la misma cosa y se podría argumentar que no tiene sentido hacer mgr más clara (incluso hay otros argumentos para decir mgr debe ser más claro :)).Pero si alguna vez esta parte de la rutina se vuelve más complicado, que podría ser muy importante:

for(int mgr(0); mgr < managers.size(); ++mgr) 
{ 
    for(int dependentMgr(0); dependentMgr < managers[mgr].dependents().size(); ++dependentMgr) 
    { 
     // init these first 
    } 
} 

Obviamente, esto no es una discusión sobre la conveniencia de utilizar iteradores o no, simplemente si debemos usar nombres claros o no.

Cuando miro un código que no he visto antes, los nombres de las variables son todo. Me estremezco cuando veo tmp y tempt2 y vec2. No significan nada.

Hablando en serio, si te preocupa la cantidad que estás escribiendo, consiguen un IDE con autocompletar o ir criar pollos en Fiji :)

+1

+1 go-faster stripes. Me recuerda a los "agujeros de velocidad" de los Simpson cuando Homer recibía un disparo. – Konerak

1

En realidad, si usted quiere que su código sea auto-documentado (Martin Fowler estilo), se puede utilizar la más prolija:

every_player_gets_equal_points = x%y; 
if (!every_player_gets_equal_points) { //Some players get more: now base on completion time 
0

el primer fragmento de código que presente, ...

if (!x%y) 
{ 
    // do something 
} 

... no tiene sentido y, por tanto, más probable es incorrecta, dado que !x%y es equivalente a !x excepto en los casos de y es igual a -1, 0 o 1, y en el y es 0 caso es Comportamiento no definido (es decir, %y generalmente no tiene sentido).

Otros ya han comentado que el primer fragmento no es equivalente al segundo más detallado. Pero entonces uno podría preguntarse qué fragmento expresa la intención. Mi punto es que el primer fragmento no es equivalente a cualquier cosa que pueda ser correcta.

Y esto ilustra muy bien que la claridad es una buena idea.

Saludos & HTH,

5

En primer lugar, los apoyos a todos notar que (!x%y) no es equivalente a (!(x%y)), pero lo más importante, ninguno de ellos es equivalente a:.

if (x % y != 0) 

que tiene una mucho más agradable forma:

if (x % y) 

Personalmente no intento escribir ==0 cuando c un sustituto por el uso de ! sin introducir paréntesis excesivos, y yo nunca uso !=0, pero esta es una discusión que iniciará flamewars. :-)

+3

Esto. El cero es falso, todo lo demás verdadero semántico está * profundamente * incrustado en el lenguaje c derivado y * es * extremadamente claro, pero suelto '!' S analiza. – dmckee

+0

A veces uso "!!" como un pseudooperador para convertir valores distintos de cero y cero a los valores 1 y 0, respectivamente. Yo suelo "!!" a veces en lugares donde no es necesario, para enfatizar que una expresión numérica puede devolver algo distinto de 0 o 1, pero los valores distintos de cero se asignarán a 1. También lo uso cuando, p. Quiero una función que devuelve un 'int' para devolver un valor distinto de cero si un valor de tipo 'long' es distinto de cero (sin el "!!", el "int" puede devolver cero incluso si el largo fue distinto de cero ; en realidad, si el tipo de devolución está firmado, incluso podría desencadenar demonios nasales). – supercat

+0

@supercat: Sí, también lo hago. Las personas que están contentas de no ser compatibles con los compiladores anteriores a C99 podrían simplemente escribir '(bool)'. –

Cuestiones relacionadas