En informática , un operador relacional es una construcción u operador de lenguaje de programación que prueba o define algún tipo de relación entre dos entidades . Estos incluyen igualdad numérica ( por ejemplo , 5 = 5 ) y desigualdades ( por ejemplo , 4 ≥ 3 ).
En los lenguajes de programación que incluyen un tipo de datos booleano distinto en su sistema de tipos , como Pascal , Ada o Java , estos operadores generalmente evalúan como verdadero o falso, dependiendo de si la relación condicional entre los dos operandos se cumple o no. En lenguajes como C , los operadores relacionales devuelven los números enteros 0 o 1, donde 0 significa falso y cualquier valor distinto de cero significa verdadero.
Una expresión creada usando un operador relacional forma lo que se denomina expresión relacional o condición . Los operadores relacionales pueden verse como casos especiales de predicados lógicos .
Igualdad
Uso
La igualdad se utiliza en muchos tipos de datos y construcciones de lenguajes de programación. Se utiliza para probar si un elemento ya existe en un conjunto , o para acceder a un valor a través de una clave. Se utiliza en declaraciones de conmutación para enviar el flujo de control a la rama correcta y durante el proceso de unificación en la programación lógica.
Un posible significado de igualdad es que "si a es igual a b , entonces a o b pueden usarse indistintamente en cualquier contexto sin notar ninguna diferencia". Pero esta afirmación no es necesariamente válida, especialmente cuando se tiene en cuenta la mutabilidad junto con la igualdad de contenido.
Igualdad de ubicación frente a igualdad de contenido
A veces, particularmente en la programación orientada a objetos , la comparación plantea preguntas sobre tipos de datos y herencia , igualdad e identidad . A menudo es necesario distinguir entre:
- dos objetos diferentes del mismo tipo, por ejemplo, dos manos
- dos objetos iguales pero distintos, por ejemplo, dos billetes de $ 10
- dos objetos son iguales pero tienen una representación diferente, por ejemplo, un billete de $ 1 y una moneda de $ 1
- dos referencias diferentes al mismo objeto, por ejemplo, dos apodos para la misma persona
En muchos lenguajes de programación modernos, se accede a los objetos y estructuras de datos a través de referencias . En tales lenguajes, se hace necesario probar dos tipos diferentes de igualdad:
- Igualdad de ubicación (identidad): si dos referencias (A y B) hacen referencia al mismo objeto. Las interacciones con el objeto a través de A son indistinguibles de las mismas interacciones a través de B y, en particular, los cambios en el objeto a través de A se reflejan a través de B.
- Igualdad de contenido: si los objetos referenciados por dos referencias (A y B) son equivalentes en algún sentido:
- Igualdad estructural (es decir, sus contenidos son los mismos). que puede ser superficial (probar solo subpartes inmediatas) o profundo (probar la igualdad de las subpartes de forma recursiva). Una forma sencilla de conseguirlo es mediante la igualdad de representación: comprobando que los valores tengan la misma representación.
- Alguna otra igualdad a medida, preservando el comportamiento externo. Por ejemplo, 1/2 y 2/4 se consideran iguales cuando se ven como un número racional. Un posible requisito sería que "A = B si y solo si todas las operaciones sobre los objetos A y B tendrán el mismo resultado", además de la reflexividad , simetría y transitividad .
El primer tipo de igualdad generalmente implica el segundo (a excepción de cosas como no un número ( NaN ) que son desiguales entre sí), pero lo contrario no es necesariamente cierto. Por ejemplo, dos objetos de cadena pueden ser objetos distintos (desiguales en el primer sentido) pero contienen la misma secuencia de caracteres (iguales en el segundo sentido). Consulte identidad para obtener más información sobre este tema.
Los números reales, incluidas muchas fracciones simples , no se pueden representar exactamente en aritmética de punto flotante y puede ser necesario probar la igualdad dentro de una tolerancia dada. Sin embargo, dicha tolerancia puede romper fácilmente propiedades deseadas como la transitividad, mientras que la reflexividad también se rompe: el estándar de punto flotante IEEE requiere que NaN ≠ NaN se mantenga.
Otros elementos de programación, como las funciones computables, pueden no tener un sentido de igualdad o una igualdad que no se puede calcular. Por estas razones, algunos lenguajes definen una noción explícita de "comparable", en la forma de una clase base, una interfaz, un rasgo o un protocolo, que se usa explícitamente, por declaración en el código fuente, o implícitamente, a través de la estructura. del tipo involucrado.
Comparando valores de diferentes tipos
En JavaScript , PHP , VBScript y algunos otros lenguajes tipados dinámicamente , el operador de igualdad estándar se evalúa como verdadero si dos valores son iguales, incluso si tienen diferentes tipos, haciendo que el número 4 se compare con la cadena de texto "4", por ejemplo. . Un operador de igualdad escrito a menudo también está disponible, en dichos lenguajes, devolviendo verdadero solo para valores con tipos idénticos o equivalentes (en PHP, 4 === "4"
es falso aunque 4 == "4"
es verdadero). [1] [2] Para lenguajes donde el número 0 puede interpretarse como falso , este operador puede simplificar cosas como verificar cero (como x == 0
sería cierto si x es 0 o "0" usando el operador de igualdad de tipo agnóstico).
Ordenando
La comparación mayor que y menor que de datos no numéricos se realiza de acuerdo con una convención de clasificación (tal como, para cadenas de texto, orden lexicográfico ) que puede ser incorporada en el lenguaje de programación y / o configurable por un programador.
Cuando se desea asociar un valor numérico con el resultado de una comparación entre dos elementos de datos, por ejemplo un y b , la convención habitual es asignar -1 si a b. ,>Por ejemplo, la función C strcmp
realiza una comparación de tres vías y devuelve -1, 0 o 1 de acuerdo con esta convención, y qsort espera que la función de comparación devuelva valores de acuerdo con esta convención. En los algoritmos de clasificación , la eficiencia del código de comparación es fundamental, ya que es uno de los principales factores que contribuyen al rendimiento de la clasificación.
La comparación de tipos de datos definidos por el programador ( tipos de datos para los que el lenguaje de programación no tiene un conocimiento incorporado) puede llevarse a cabo mediante funciones de biblioteca o escritas personalizadas (como las strcmp
mencionadas anteriormente) o, en algunos lenguajes, sobrecargando una comparación operador, es decir, asignar un significado definido por el programador que depende de los tipos de datos que se comparan. Otra alternativa es utilizar alguna convención, como la comparación por miembros.
Equivalencia lógica
Aunque quizás no sean obvios al principio, como los operadores lógicos booleanos XOR, AND, OR y NOT, los operadores relacionales pueden diseñarse para tener equivalencia lógica , de modo que todos puedan definirse en términos entre sí. Los siguientes cuatro sentencias condicionales todos tienen la misma equivalencia lógica E (ya sea todo cierto o todas falsas) para cualquier dado x y Y valores:
Esto depende de que el dominio esté bien ordenado .
Operadores relacionales estándar
Los operadores relacionales numéricos más comunes utilizados en lenguajes de programación se muestran a continuación.
Convención | igual a | no igual a | mas grande que | menos que | mayor o igual a | menor o igual a |
---|---|---|---|---|---|---|
En la impresión | = | ≠ | > | < | ≥ | ≤ |
FORTRAN [nota 1] | .EQ. | .NE. | .GT. | .LT. | .GE. | .LE. |
ALGOL 68 [nota 2] | = | ≠ | > | < | ≥ | ≤ |
/= | >= | <= | ||||
eq | ne | gt | lt | ge | le | |
APL | = | ≠ | > | < | ≥ | ≤ |
BÁSICO , ML , Pascal [nota 3] | = | <> | > | < | >= | <= |
PAPERAS | = | '= | > | < | '< | '> |
Lua | == | ~= | > | < | >= | <= |
Similar a C [nota 4] | == | != | > | < | >= | <= |
Erlang | == | /= | > | < | >= | =< |
=:= | =/= | |||||
Conchas tipo Bourne [nota 5] | -eq | -ne | -gt | -lt | -ge | -le |
Archivo por lotes | EQU | NEQ | GTR | LSS | GEQ | LEQ |
MATLAB [nota 6] | == | ~= | > | < | >= | <= |
eq(x,y) | ne(x,y) | gt(x,y) | lt(x,y) | ge(x,y) | le(x,y) | |
Fortran 90 , [nota 7] Haskell | == | /= | > | < | >= | <= |
Mathematica [3] | == | != | > | < | >= | <= |
Equal[x,y] | Unequal[x,y] | Greater[x,y] | Less[x,y] | GreaterEqual[x,y] | LessEqual[x,y] |
- ^ Incluyendo FORTRAN II, III, IV, 66 y 77.
- ^ ALGOL 68 : losregímenes de restricción se usan en el código en plataformas con juegos de caracteres limitados ( por ejemplo , use
>=
o enGE
lugar de≥
), plataformas sinbold
énfasis (use'ge'
) o plataformas con solo MAYÚSCULAS (use.GE
o'GE'
). - ^ Incluyendo ALGOL , Simula , Modula-2 , Eiffel , SQL , fórmulas de hoja de cálculo y otros.
- ^ Incluyendo C , C ++ , C # , Go , Java , JavaScript , Perl (sólo comparación numérica), PHP , Python , Rubí , y R .
- ^ Incluyendo Bourne shell , Bash , KornShell y Windows PowerShell . Los símbolos
<
y>
generalmente se usan en un shell para la redirección , por lo que se deben usar otros símbolos. Sin el guión, se utiliza en Perl para la comparación de cadenas. - ^ MATLAB, aunque en otros aspectos usa una sintaxis similar a la de C, no la usa
!=
, ya que!
en MATLAB envía el siguiente texto como una línea de comando al sistema operativo . La primera forma también se usa en Smalltalk , con la excepción de la igualdad, que es=
. - ^ Incluyendo FORTRAN 95, 2003, 2008 y 2015.
Otras convenciones son menos comunes: Common Lisp y Macsyma / Maxima usan operadores similares a los de Basic excepto por la desigualdad, que está /=
en Common Lisp y #
en Macsyma / Maxima. Mayores Lisps utilizarse equal
, greaterp
y lessp
; y los negó usando not
para los operadores restantes.
Sintaxis
Los operadores relacionales también se utilizan en la literatura técnica en lugar de palabras. Los operadores relacionales generalmente se escriben en notación infija , si son compatibles con el lenguaje de programación, lo que significa que aparecen entre sus operandos (las dos expresiones están relacionadas). Por ejemplo, una expresión en Python imprimirá el mensaje si x es menor que y :
si x < y : print ( "x es menor que y en este ejemplo" )
Otros lenguajes de programación, como Lisp , usan la notación de prefijo , de la siguiente manera:
( > = X Y )
Encadenamiento de operadores
En matemáticas, es una práctica común encadenar operadores relacionales, como en 3
Sin embargo, muchos lenguajes de programación recientes verían una expresión como 3 (3 < x) < y
. Si decimos que x = 4, obtenemos (3 < 4) < y
, y la evaluación dará, lo true < y
que generalmente no tiene sentido. Sin embargo, se compila en C / C ++ y algunos otros lenguajes, produciendo un resultado sorprendente (como verdadero estaría representado por el número 1 aquí).
Es posible darle a la expresión x < y < z
su significado matemático familiar, y algunos lenguajes de programación como Python y Raku lo hacen. Otros, como C # y Java, no lo hacen, en parte porque diferiría de la forma en que la mayoría de los otros operadores infijos funcionan en lenguajes similares a C. El lenguaje de programación D no hace eso ya que mantiene cierta compatibilidad con C, y "Permitir expresiones en C pero con semánticas sutilmente diferentes (aunque posiblemente en la dirección correcta) agregaría más confusión que conveniencia". [4]
Algunos lenguajes, como Common Lisp , utilizan predicados de múltiples argumentos para esto. En Lisp (<= 1 x 10)
es verdadero cuando x está entre 1 y 10.
Confusión con los operadores de asignación
El primer FORTRAN (1956–57) estaba limitado por conjuntos de caracteres muy restringidos donde =
era el único operador relacional disponible. No hubo <
o >
(y ciertamente no ≤
o ≥
). Esto obligó a los diseñadores para definir símbolos tales como .GT.
, .LT.
, .GE.
, .EQ.
etc, y posteriormente se hizo sentir la tentación de utilizar los restantes =
caracteres para copiar, a pesar de la incoherencia evidente con el uso matemática ( X=X+1
debería ser imposible).
El Lenguaje Algebraico Internacional (IAL, ALGOL 58 ) y ALGOL (1958 y 1960) así introducidos :=
para asignación, dejando =
disponible el estándar para la igualdad, una convención seguida por CPL , ALGOL W , ALGOL 68 , Lenguaje de Programación Combinado Básico ( BCPL ), Simula , SET Language ( SETL ), Pascal , Smalltalk , Modula-2 , Ada , Standard ML , OCaml , Eiffel , Object Pascal ( Delphi ), Oberon , Dylan , VHSIC Hardware Description Language ( VHDL ) y varios otros idiomas.
B y C
Este uniforme de estándar de facto entre la mayoría de los lenguajes de programación fue finalmente cambiado, de manera indirecta, por un minimalista compilado llamado lenguaje B . Su única aplicación prevista fue como vehículo para un primer puerto de Unix (entonces muy primitivo) , pero también evolucionó hacia el lenguaje C muy influyente .
B comenzó como una variante sintácticamente modificada del lenguaje de programación de sistemas BCPL , una versión simplificada (y sin tipo) de CPL . En lo que se ha descrito como un proceso de "eliminación", los operadores and
y or
de BCPL [5] fueron reemplazados por &
y |
(que luego se convertirían en &&
y ||
, respectivamente. [6] ). En el mismo proceso, el estilo ALGOL :=
de BCPL fue reemplazado por =
en B. Se desconoce la razón de todo esto. [7] Como las actualizaciones de variables no tenían una sintaxis especial en B (como let
o similar) y estaban permitidas en las expresiones, este significado no estándar del signo igual significaba que la semántica tradicional del signo igual ahora tenía que asociarse con otro símbolo. Ken Thompson usó la ==
combinación ad hoc para esto.
A medida que se introdujo más tarde un sistema de tipos pequeños, B se convirtió en C. La popularidad de este lenguaje, junto con su asociación con Unix, llevó a Java, C # y muchos otros lenguajes a seguir su ejemplo, sintácticamente, a pesar de este conflicto innecesario con el significado matemático de el signo igual.
Idiomas
Las asignaciones en C tienen un valor y dado que cualquier valor escalar distinto de cero se interpreta como verdadero en las expresiones condicionales , [8] el código if (x = y)
es legal, pero tiene un significado muy diferente de if (x == y)
. El fragmento de código anterior significa "asignar y a x , y si el nuevo valor de x no es cero, ejecutar la siguiente instrucción". El último fragmento significa " si y solo si x es igual ay , ejecute la siguiente instrucción". [9]
int x = 1 ; int y = 2 ; if ( x = y ) { / * Este código siempre se ejecutará si y es cualquier cosa menos 0 * / printf ( "x es% d e y es% d \ n " , x , y ); }
Aunque Java y C # tienen los mismos operadores que C, este error generalmente causa un error de compilación en estos lenguajes, porque la condición if debe ser de tipo boolean
y no hay una forma implícita de convertir otros tipos ( por ejemplo , números) en boolean
s. Entonces, a menos que la variable asignada tenga un tipo boolean
(o tipo contenedor Boolean
), habrá un error de compilación.
En lenguajes similares a ALGOL como Pascal, Delphi y Ada (en el sentido de que permiten definiciones de funciones anidadas ), y en Python , y muchos lenguajes funcionales, entre otros, los operadores de asignación no pueden aparecer en una expresión (incluidas las if
cláusulas), por lo que excluyendo esta clase de error. Algunos compiladores, como GNU Compiler Collection (GCC), proporcionan una advertencia al compilar código que contiene un operador de asignación dentro de una instrucción if, aunque hay algunos usos legítimos de una asignación dentro de una condición if. En tales casos, la asignación debe incluirse explícitamente entre paréntesis extra, para evitar la advertencia.
De manera similar, algunos lenguajes, como BASIC, usan solo el =
símbolo tanto para la asignación como para la igualdad, ya que están separados sintácticamente (como con Pascal, Ada, Python, etc., los operadores de asignación no pueden aparecer en las expresiones).
Algunos programadores se acostumbran a escribir comparaciones con una constante en el orden inverso al habitual:
if ( 2 == a ) { / * El uso equivocado de = versus == sería un error en tiempo de compilación * / }
Si =
se usa accidentalmente, el código resultante no es válido porque 2 no es una variable. El compilador generará un mensaje de error, en el que se puede sustituir el operador adecuado. Este estilo de codificación se denomina comparación a la izquierda o condiciones de Yoda .
Esta tabla enumera los diferentes mecanismos para probar estos dos tipos de igualdad en varios idiomas:
Idioma | Igualdad fisica | Igualdad estructural | Notas |
---|---|---|---|
ALGOL 68 | a :=: b o a is b | a = b | cuando a y b son punteros |
C , C ++ | a == b | *a == *b | cuando a y b son punteros |
C# | object.ReferenceEquals(a, b) | a.Equals(b) | El == operador tiene como valor predeterminado ReferenceEquals , pero puede sobrecargarse para realizar en su Equals lugar. |
Lisp común | (eq a b) | (equal a b) | |
Erlang | a =:= b | a == b | cuando ayb son números |
Ir | a == b | reflect.DeepEqual(*a, *b) | cuando ayb son punteros |
Java | a == b | a.equals(b) | |
JavaScript | a === b | a == b | cuando ayb son dos objetos de cadena que contienen caracteres equivalentes, el operador === seguirá devolviendo verdadero. |
OCaml , Smalltalk | a == b | a = b | |
Pascal | a^ = b^ | a = b | |
Perl | $a == $b | $$a == $$b | cuando $a y $b son referencias a escalares |
PHP | $a === $b | $a == $b | cuando $a y $b son objetos |
Pitón | a is b | a == b | |
Rubí | a.equal?(b) | a == b | |
Esquema | (eq? a b) | (equal? a b) | |
Rápido | a === b | a == b | cuando ayb tienen tipo de clase |
Visual Basic .NET [desigualdad 1] | a Is b o object.ReferenceEquals(a, b) | a = b o a.Equals(b) | Igual que C # |
Objective-C ( Cocoa , GNUstep ) | a == b | [a isEqual:b] | cuando a y b son punteros a objetos que son instancias deNSObject |
- ^ Solicitud de patente: el 14 de mayo de 2003, solicitud estadounidense 20,040,230,959"NO ES OPERADOR" fue presentado para el
ISNOT
operador por empleados de Microsoft . Esta patente fue concedida el 18 de noviembre de 2004.
Ruby a === b
suele significar "b es un miembro del conjunto a", aunque los detalles de lo que significa ser miembro varían considerablemente dependiendo de los tipos de datos involucrados. ===
se conoce aquí como el operador de "igualdad de casos" o "subsunción de casos".
Ver también
- Relación binaria
- Notación de operador común
- Condicional (programación informática)
- Igualdad (matemáticas)
- Signo de igual
- Operador lógico
- Operación (matemáticas)
- Operador (matemáticas)
- Operador (programación de computadoras)
- Operador de nave espacial
- Relación triádica
notas y referencias
- ^ Colaboradores . "Comparación de objetos" . Manual de PHP . Grupo PHP . Consultado el 29 de junio de 2014 .
- ^ "PHP: Operadores de comparación - Manual" . Consultado el 31 de julio de 2008 .
- ^ Operadores relacionales y lógicos de Mathematica
- ^ Alexandrescu, Andrei. El lenguaje de programación D . Addison Wesley. pag. 58. ISBN 978-0-321-63536-5.
- ^ Se usa no solo en lenguajes similares a ALGOL, sino también en FORTRAN y BASIC
- ^ Como algunos programadores estaban confundidos por los significados duales (operador bit a bit y conectivo lógico) de estos nuevos símbolos (según Dennis Ritchie ). Sólo el significado bit a bit de & y | fueron retenidos.
- ^ Aunque Dennis Ritchie ha sugerido que esto puede haber tenido que ver con la "economía de tipeo", ya que las actualizaciones de variables pueden ser más frecuentes que las comparaciones en ciertos tipos de programas.
- ^ Un valor escalar cero se interpreta como falso, mientras que cualquier valor escalar distinto de cero se interpreta como verdadero; esto se usa típicamente con tipos enteros, similar a losmodismos del lenguaje ensamblador .
- ^ Brian Kernighan y Dennis Ritchie (1988) [1978]. El lenguaje de programación C (segunda ed.). Prentice Hall., 19