stringtranslate.com

Operador relacional

En informática , un operador relacional es una construcción u operador de un 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 se 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 representa falso y cualquier valor distinto de cero representa verdadero.

Una expresión creada utilizando 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 muchas construcciones de lenguajes de programación y tipos de datos. 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 cambio para enviar el flujo de control a la rama correcta y durante el proceso de unificación en 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 necesariamente se cumple, particularmente cuando se tiene en cuenta la mutabilidad junto con la igualdad de contenido.

Igualdad de ubicación versus igualdad de contenido

A veces, particularmente en la programación orientada a objetos , la comparación plantea cuestiones de tipos de datos y herencia , igualdad e identidad . A menudo es necesario distinguir entre:

En muchos lenguajes de programación modernos, se accede a objetos y estructuras de datos a través de referencias . En tales lenguajes, surge la necesidad de probar dos tipos diferentes de igualdad:

  • Igualdad estructural (es decir, sus contenidos son iguales). que puede ser superficial (probar sólo subpartes inmediatas) o profundo (probar la igualdad de subpartes de forma recursiva). Una forma sencilla de lograrlo es mediante la igualdad representacional: comprobando que los valores tengan la misma representación.
  • Alguna otra igualdad hecha a medida, preservando el comportamiento exterior. Por ejemplo, 1/2 y 2/4 se consideran iguales cuando se consideran números racionales. Un posible requisito sería que "A = B si y sólo si todas las operaciones sobre los objetos A y B tendrán el mismo resultado", además de la reflexividad , la simetría y la transitividad .

El primer tipo de igualdad suele implicar el segundo (excepto cosas como no es un número ( NaN ) que no son iguales a sí mismos), pero lo contrario no es necesariamente cierto. Por ejemplo, dos objetos de cadena pueden ser objetos distintos (desiguales en el primer sentido) pero contener la misma secuencia de caracteres (iguales en el segundo sentido). Consulte la 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 determinada. 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 cumpla. Por el contrario, el estándar privado (2022) para la aritmética positiva (los defensores de la posición pretenden reemplazar los flotadores IEEE) tiene un concepto similar, NaR (Not a Real), donde NaR = NaR se cumple. [1]

Otros elementos de programación, como las funciones computables, pueden no tener ningún sentido de igualdad o tener una igualdad que no sea computable. Por estas razones, algunos lenguajes definen una noción explícita de "comparable", en forma de clase base, interfaz, rasgo o protocolo, que se utiliza explícitamente, mediante declaración en el código fuente, o implícitamente, a través de la estructura. del tipo involucrado.

Comparar valores de diferentes tipos

En JavaScript , PHP , VBScript y algunos otros lenguajes de escritura dinámica , el operador de igualdad estándar se evalúa como verdadero si dos valores son iguales, incluso si tienen tipos diferentes, lo que hace que el número 4 se compare con la cadena de texto "4", por ejemplo. . En dichos lenguajes también suele estar disponible un operador de igualdad escrito, que devuelve verdadero solo para valores con tipos idénticos o equivalentes (en PHP, 4 === "4"es falso aunque 4 == "4"es verdadero). [2] [3] Para idiomas donde el número 0 puede interpretarse como falso , este operador puede simplificar cosas como verificar cero (como x == 0sería cierto si x fuera 0 o "0" usando el operador de igualdad independiente del tipo).

Realizar pedidos

La comparación mayor que y menor que de datos no numéricos se realiza de acuerdo con una convención de clasificación (como, para cadenas de texto, orden lexicográfico ) que puede estar integrada en el lenguaje de programación y/o ser configurable por un programador.

Cuando se desea asociar un valor numérico con el resultado de una comparación entre dos elementos de datos, digamos a y b , la convención habitual es asignar −1 si a < b, 0 si a = b y 1 si a > b. Por ejemplo, la función C strcmprealiza una comparación de tres vías y devuelve −1, 0 o 1 según esta convención, y qsort espera que la función de comparación devuelva valores según 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 cuales el lenguaje de programación no tiene comprensión incorporada) se puede llevar a cabo mediante funciones escritas a medida o de biblioteca (como las strcmpmencionadas 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 entre 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 que tengan equivalencia lógica , de modo que todos puedan definirse en términos de otros. Los siguientes cuatro enunciados condicionales tienen la misma equivalencia lógica E (todas verdaderas o todas falsas) para cualquier valor x e y dado :

Esto depende de que el dominio esté bien ordenado .

Operadores relacionales estándar

A continuación se muestran los operadores relacionales numéricos más comunes utilizados en los lenguajes de programación. El SQL estándar utiliza los mismos operadores que el BASIC, mientras que muchas bases de datos lo permiten !=además <>del estándar. SQL sigue un álgebra booleana estricta , es decir, no utiliza evaluación de cortocircuito , que es común a la mayoría de los lenguajes siguientes. Por ejemplo, PHP lo tiene, pero por lo demás tiene estos mismos dos operadores definidos como alias, como muchas bases de datos SQL.

  1. ^ Incluyendo FORTRAN II, III, IV, 66 y 77.
  2. ^ ALGOL 68 : los regímenes de ajuste se utilizan en el código en plataformas con conjuntos de caracteres limitados ( p. ej. , use >=o GEen lugar de ), plataformas sin bold énfasis (use 'ge') o plataformas con solo MAYÚSCULAS (use .GE o 'GE' ).
  3. ^ Incluyendo ALGOL , Simula , Modula-2 , Eiffel , SQL , fórmulas de hoja de cálculo y otros.
  4. ^ Modula-2 también reconoce#
  5. ^ Incluyendo C , C++ , C# , Go , Java , JavaScript , Perl (solo comparación numérica) , PHP , Python , Ruby y R.
  6. ^ Incluyendo Bourne Shell , Bash , KornShell y Windows PowerShell . Los símbolos <y >generalmente se usan en un shell para redirección , por lo que se deben usar otros símbolos. Sin guión, se utiliza en Perl para comparar cadenas.
  7. ^ MATLAB, aunque en otros aspectos usa una sintaxis similar a la de C, no 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 igualdad, que es =.
  8. ^ Incluyendo FORTRAN 95, 2003, 2008 y 2015.

Otras convenciones son menos comunes: Common Lisp y Macsyma / Maxima usan operadores similares a los básicos excepto la desigualdad, que está /=en Common Lisp y #en Macsyma/Maxima. Los Lisps más antiguos usaban equal, greaterpy lessp; y los negó usando notpara 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 el lenguaje de programación los admite, lo que significa que aparecen entre sus operandos (estando relacionadas las dos expresiones). 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 , utilizan 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 < x < y < 20 (es decir, 3 < x y x < y e y < 20). La sintaxis es clara ya que estos operadores relacionales en matemáticas son transitivos.

Sin embargo, muchos lenguajes de programación recientes verían una expresión como 3 < x < y compuesta por dos operadores asociativos izquierdo (o derecho), interpretándola como algo así (3 < x) < y. Si decimos que x=4, obtenemos (3 < 4) < yy la evaluación dará, true < ylo que generalmente no tiene sentido. Sin embargo, se compila en C/C++ y algunos otros lenguajes, lo que produce resultados sorprendentes (como verdadero estaría representado aquí por el número 1).

Es posible darle a la expresión x < y < zsu 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 funcionan la mayoría de los otros operadores infijos en lenguajes tipo C. El lenguaje de programación D no hace eso ya que mantiene cierta compatibilidad con C, y "Permitir expresiones C pero con una semántica sutilmente diferente (aunque posiblemente en la dirección correcta) agregaría más confusión que conveniencia". [5]

Algunos lenguajes, como Common Lisp , utilizan múltiples predicados de argumentos para esto. En Lisp (<= 1 x 10)es cierto cuando x está entre 1 y 10.

Confusión con los operadores de asignación

Los primeros FORTRAN (1956–57) estaban limitados por conjuntos de caracteres muy restringidos donde =era el único operador relacional disponible. No hubo <ni >(y ciertamente no hubo ni ). Esto obligó a los diseñadores a definir símbolos como .GT., .LT., .GE., .EQ.etc. y posteriormente hizo tentador usar el =carácter restante para copiar, a pesar de la obvia incoherencia con el uso matemático ( X=X+1debería ser imposible).

Se introdujeron así el lenguaje algebraico internacional (IAL, ALGOL 58 ) y ALGOL (1958 y 1960) :=para su asignación, dejando el estándar =disponible para la igualdad, convención seguida por CPL , ALGOL W , ALGOL 68 , lenguaje de programación combinado básico ( BCPL ), Simula , Lenguaje SET ( SETL ), Pascal , Smalltalk , Modula-2 , Ada , Standard ML , OCaml , Eiffel , Object Pascal ( Delphi ), Oberon , Dylan , VHSIC Lenguaje de descripción de hardware ( VHDL ) y varios otros lenguajes.

B y C

Este estándar uniforme de facto entre la mayoría de los lenguajes de programación finalmente fue cambiado, indirectamente, por un lenguaje compilado minimalista llamado B. Su única aplicación prevista era como vehículo para una primera adaptación de Unix (entonces muy primitivo) , pero también evolucionó hasta convertirse en el muy influyente lenguaje C.

B comenzó como una variante sintácticamente modificada del lenguaje de programación de sistemas BCPL , una versión simplificada (y sin tipos) de CPL . En lo que se ha descrito como un proceso de "desmontaje", los operadores andy orde BCPL [6] fueron reemplazados por &y |(que luego se convertirían en &&y ||, respectivamente. [7] ). En el mismo proceso, el estilo ALGOL :=de BCPL fue reemplazado por =B. Se desconoce el motivo de todo esto. [8] Como las actualizaciones de variables no tenían una sintaxis especial en B (como leto similar) y estaban permitidas en las expresiones, este significado no estándar del signo igual significó que la semántica tradicional del signo igual ahora tenía que asociarse con otro símbolo. Ken Thompson utilizó la combinación ad hoc ==para esto.

A medida que más tarde se introdujo un pequeño sistema de tipos, B se convirtió en C. La popularidad de este lenguaje junto con su asociación con Unix, llevó a que Java, C# y muchos otros lenguajes siguieran 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 expresiones condicionales , [9] el código if (x = y)es legal, pero tiene un significado muy diferente al de if (x == y). El fragmento de código anterior significa "asigne y a x , y si el nuevo valor de x no es cero, ejecute la siguiente instrucción". El último fragmento significa " si y sólo si x es igual a y , ejecute la siguiente declaración". [10]

 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 %dy 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 booleany no hay una forma implícita de convertir de otros tipos ( por ejemplo , números) a booleans. Entonces, a menos que la variable asignada tenga tipo boolean(o tipo contenedor Boolean), habrá un error de compilación.

En lenguajes tipo 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 iflas cláusulas), por lo tanto 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 declaración if, aunque existen 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 un par de paréntesis adicionales 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 sintácticamente separados (como ocurre con Pascal, Ada, Python, etc., los operadores de asignación no pueden aparecer en las expresiones).

Algunos programadores adquieren el hábito de escribir comparaciones con una constante en el orden inverso al habitual:

 if ( 2 == a ) { /* El uso incorrecto 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 podrá 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:

  1. ^ Solicitud de patente: El 14 de mayo de 2003, los empleados de Microsoft presentaron la solicitud estadounidense 20.040.230.959 "NO ES OPERADOR" para el operador . Esta patente fue concedida el 18 de noviembre de 2004. ISNOT

Ruby suele a === bsignificar "b es 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 operador de "igualdad de casos" o "subsunción de casos".

Ver también

notas y referencias

  1. ^ Estándar para aritmética positiva (2022)
  2. ^ Colaboradores. "Comparación de objetos". Manual PHP . Grupo PHP . Consultado el 29 de junio de 2014 . {{cite web}}: |author=tiene nombre genérico ( ayuda ) ; Enlace externo en |author=( ayuda )
  3. ^ "PHP: Operadores de comparación - Manual" . Consultado el 31 de julio de 2008 .
  4. ^ Operadores lógicos y relacionales de Mathematica
  5. ^ Alexandrescu, Andrei (2010). El lenguaje de programación D. Addison Wesley. pag. 58.ISBN 978-0-321-63536-5.
  6. ^ Se utiliza no solo en lenguajes similares a ALGOL, sino también en FORTRAN y BASIC.
  7. ^ 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.
  8. ^ Aunque Dennis Ritchie ha sugerido que esto puede haber tenido que ver con la "economía de mecanografía", ya que las actualizaciones de variables pueden ser más frecuentes que las comparaciones en ciertos tipos de programas.
  9. ^ 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 de números enteros, similar a los modismos del lenguaje ensamblador .
  10. ^ Brian Kernighan y Dennis Ritchie (1988) [1978]. El lenguaje de programación C (Segunda ed.). Prentice Hall., 19