relacionales programacion operadores logicos asignacion aritmeticos c logical-operators

asignacion - operadores logicos en programacion



¿Por qué C no tiene un operador de asignación lógica? (4)

No puedo encontrar ninguna razón en particular, por qué los operadores no existen (en C99).

Así que la única razón por la que puedo encontrar es que no había ningún tipo booleano en C89, y que esos operadores booleanos estaban destinados a ser utilizados únicamente en if ''s.

Ejemplo:

int i = 5; /* This should not make any difference, since or''ing with false, shouldn''t change the value... dib di dib diddy...*/ i ||= 0; /* Actually: i = i || 0, which gives ''true'' */

i es ahora ''1'' '', que para la mayoría de las personas es bastante intuitivo.

Obviamente, este operador no aporta ninguna mejora de codificación o de depuración sin el tipo booleano, que haría que el sentimiento se combinara con otro.

En mi opinión, la implementación de a ||= b; como if(!a) a = b; sería bastante sencillo y ya se ha implementado por ejemplo por Lua.

Así que tu pregunta parece ser un poco, por qué C ha sido diseñado de la manera en que ha sido diseñado. Si esta pregunta era sobre C ++, podrías, por ejemplo, preguntarle a Bjarne Stroustrup y preguntarle qué fue de él. Ya que este no es el caso, me parece que es un callejón sin salida, porque el estándar ha sido escrito hace bastante tiempo y ya no se puede preguntar a la gente, ¿por qué?

Por otro lado, este conjunto de operadores incompleto debería (en mi opinión) haber sido completamente utilizado utilizando una notación similar a la suya, ya que en mi opinión, no hay ninguna razón en contra.

Espero poder ayudar un poco.

Tuve la necesidad de codificar una declaración del formulario.

a = a || expr;

donde se debe evaluar expr y el resultado debe asignarse a a iff a no se establece. esto se basa en las capacidades de cortocircuito lógico de OR.

La forma más corta de escribir lo anterior sería, por supuesto,

a ||= expr;

pero (para mi sorpresa) C no tiene operadores de asignación lógica.

Así que mi pregunta es doble. Primero, ¿hay una manera más corta de escribir la primera afirmación en el estándar C (el operador ternario es incluso peor - a = a ? a : expr requiere que deletree tres veces).

En segundo lugar, ¿por qué no hay asignaciones lógicas en C? Las posibles razones por las que podría pensar son:

  • hace la gramática más difícil de analizar?
  • ¿Existe alguna sutileza en el manejo de cortocircuitos para estos casos?
  • se consideró superfluo (¿pero no es un argumento en contra de TODAS las asignaciones de los operadores?)

EDITAR

Por favor desbloquea esta pregunta porque:

  • La pregunta a la que se ha vinculado (como un presunto duplicado de) NO HA SIDO RESPONDIDA. La respuesta (aceptada) a esa pregunta indica que ||= no está presente porque duplica la funcionalidad de |= . Esa es la respuesta incorrecta. |= no cortocircuito.

  • C y C ++ NO son los mismos idiomas. Deseo saber por qué C no lo tiene. De hecho, el hecho de que los lenguajes derivados como C ++ y, en particular, Java (que no sufrió los problemas del código heredado como se ha sugerido en la respuesta de Edmund) hace que la pregunta sea aún más interesante.

EDIT 2

Ahora parece que mi intención original fue incorrecta. En la declaración a = a || expr a = a || expr (donde a es integral y expr devuelve un valor integral, primero a y expr se convertirán implícitamente a "booleanos", y luego el valor "booleano" se asignará a. Esto será incorrecto; el valor integral será perdido. Gracias, Jens y Edmund.

Entonces, para la primera parte de la pregunta, las formas correctas, no alternativas :), para codificar mi intención serían:

if (!a) a = expr;

o

a = a ? a : expr;

deberían optimizarse igual (creo) aunque personalmente preferiría el primero (porque tiene uno menos para escribir).

Sin embargo, la segunda parte de la pregunta aún permanece. Los argumentos que Jens y Edmund han dado acerca de la ambigüedad en a ||= expr aplican igualmente bien a a = a || expr a = a || expr . El caso de asignación puede tratarse simplemente como el normal:

  • convertir a booleano
  • si es verdadero, el valor de la expresión completa se vuelve igual al valor booleano de a
  • de lo contrario evalúe expr , convierta el resultado a booleano, asigne a y devuélvalo

Los pasos anteriores parecen ser los mismos tanto para la asignación como para el caso normal.


Porque el tipo de retorno de los operadores || y && no es lo mismo que el tipo de su argumento de la izquierda.

El tipo de retorno de || y && siempre es int 1 , mientras que el argumento de la izquierda puede ser de tipo integral, punto flotante o tipo puntero. Los operandos tampoco tienen que ser del mismo tipo. Por lo tanto, definiendo x ||= y como x = x || y x = x || y y x &&= y as x = x && y como sería consistente con otras asignaciones aumentadas no podrían almacenar el resultado en el argumento para la mayoría de los tipos.

Podrías encontrar otras definiciones, por ejemplo x ||= y como if(!x) x = y y x &&= y como if(!y) x = y , pero eso no sería exactamente obvio y no es eso Útil, por lo que no fue incluido.

1 En C ++ es bool .


Supongo que la respuesta simple es que || es un operador booleano: y en C, un "booleano" es 0 o 1. Los operandos se convierten implícitamente a booleanos (no he comprobado que eso es lo que realmente dice la especificación, pero es cómo se comporta C), y el resultado es una booleano

Es posible que sea factible alterar la semántica para apoyar este patrón, hasta que alguien confíe || haciendo lo que siempre se hace.


a ||= expr es problemático debido a la evaluación de cortocircuito de su equivalente a = a || expr a = a || expr .

Para tener a ||= expr como a = a || expr a = a || expr considere la afirmación de OP:

"En el enunciado a = a || expr ..., primero a y expr se convertirán implícitamente a" booleanos ","

Esto no es muy correcto. expr no se convertirá si se evalúa como true . Esto marcaría la diferencia debería ser algo así como scanf() o rand() o alguna función que afectara el estado del programa.

Código como a ||= scanf("%d", &i) != 1; solo intentaría escanear datos con un valor falso en a archivo. Aunque sería posible ampliar el idioma de esta manera, operadores de cortocircuitos adicionales al conjunto actual de || y && probablemente causaría más problemas de codificación que simplificaciones claras.

Por otro lado: una manera rápida, si bien ofuscada, de escribir código donde las funciones devuelven códigos que no son cero en caso de error.

// Perform functions until an error occurs. bool error = foo1(); error &&= foo2(); // Only valid if C was extended with &&= error &&= foo3();