Relační operátor - Relational operator
v počítačová věda, a relační operátor je programovací jazyk postavit nebo operátor který testuje nebo definuje nějaký druh vztah mezi dvě entity. Patří mezi ně numerické rovnost (např., 5 = 5) a nerovnosti (např., 4 ≥ 3).
V programovacích jazycích, které obsahují odlišné boolovský datový typ v jejich typový systém, jako Pascal, Ada nebo Jáva, tito operátoři obvykle vyhodnotí na true nebo false, v závislosti na tom, zda je mezi nimi podmíněný vztah operandy drží nebo ne. V jazycích, jako je C, relační operátory vracejí celá čísla 0 nebo 1, kde 0 znamená false a jakákoli nenulová hodnota znamená true.
An výraz vytvořené pomocí relačního operátoru tvoří to, co se nazývá a relační výraz nebo a stav. Relační operátory lze považovat za speciální logické případy predikáty.
Rovnost
Používání
Rovnost se používá v mnoha konstrukcích a datových typech programovacích jazyků. Používá se k testování, zda prvek již existuje v soubor, nebo pro přístup k hodnotě pomocí klíče. Používá se v příkazy switch odeslat řídicí tok do správné větve a během procesu sjednocení v logickém programování.
Jedním z možných významů rovnosti je, že „pokud A rovná se b, pak buď A nebo b lze použít zaměnitelně v jakémkoli kontextu, aniž by si všiml jakéhokoli rozdílu. “Toto tvrzení však nutně neplatí, zvláště když vezmeme v úvahu proměnlivost spolu s rovností obsahu.
Stejnost (identita objektu) vs. rovnost obsahu
Někdy, zejména v objektově orientované programování, srovnání vyvolává otázky typy dat a dědictví, rovnost, a identita. Často je nutné rozlišovat mezi:
- dva různé objekty stejného typu, např., dvě ruce
- dva objekty jsou stejné, ale odlišné, např., dvě bankovky v hodnotě 10 $
- dva objekty jsou stejné, ale mají různé zastoupení, např., účet v hodnotě 1 $ a 1 $ mince
- dva různé odkazy na stejný objekt, např., dvě přezdívky pro stejnou osobu
V mnoha moderních programovacích jazycích se k objektům a datovým strukturám přistupuje prostřednictvím Reference. V takových jazycích je potřeba testovat dva různé typy rovnosti:
- Fyzická rovnost: pokud dva odkazy (A a B) odkazují na stejný objekt. Interakce s objektem prostřednictvím A jsou nerozeznatelné od stejných interakcí prostřednictvím B a zejména změny objektu prostřednictvím A se odrážejí prostřednictvím B. Fyzická identita není použitelná, když mluvíme o hodnotách místo o objektech.
- Sémantická rovnost: pokud jsou objekty, na které odkazují dva odkazy, nebo jsou-li dvě hodnoty, v určitém smyslu ekvivalentní:
- Strukturální rovnost (tj., jejich obsah je stejný). který může být buď mělký (testování pouze okamžitých částí), nebo hluboký (testování rovnosti částí součástí rekurzivně). Jednoduchého způsobu, jak toho dosáhnout, je reprezentativní rovnost: kontrola, zda mají hodnoty stejnou reprezentaci.
- Některé další rovnosti šité na míru, zachování vnějšího chování. Například 1/2 a 2/4 jsou považovány za rovnocenné, pokud jsou považovány za racionální číslo. Možným požadavkem by bylo, že „A = B právě tehdy, když všechny operace s objekty A a B budou mít stejný výsledek“, kromě reflexivita, symetrie, a tranzitivita.
První typ rovnosti obvykle implikuje druhý (kromě věcí jako ne číslo (NaN ), které jsou pro sebe nerovné), ale obrácení nemusí být nutně pravdivé. Například dva tětiva objekty mohou být odlišné objekty (v prvním smyslu nerovné), ale obsahují stejnou posloupnost znaků (v druhém smyslu stejné). Vidět identita pro více tohoto čísla.
Skutečná čísla, včetně mnoha jednoduchých zlomky, nelze přesně reprezentovat v aritmetika s plovoucí desetinnou čárkou a může být nutné otestovat rovnost v rámci dané tolerance. Taková tolerance však může snadno narušit požadované vlastnosti, jako je tranzitivita, zatímco reflexivita se také rozbije: IEEE s plovoucí desetinnou čárkou standard to vyžaduje NaN ≠ NaN drží.
Jiné programovací prvky, jako jsou vypočítatelné funkce, nemusí mít žádný smysl pro rovnost nebo rovnost, která je nepočítatelná. Z těchto důvodů definují některé jazyky výslovný pojem „srovnatelný“ ve formě základní třídy, rozhraní, znaku nebo protokolu, který se používá buď explicitně, deklarací ve zdrojovém kódu, nebo implicitně prostřednictvím struktury příslušného typu.
Porovnání hodnot různých typů
v JavaScript, PHP, VBScript a několik dalších dynamicky zadáno jazyky, vyhodnotí operátor standardní rovnosti skutečný jsou-li dvě hodnoty stejné, i když mají různé typy, je například porovnání čísla 4 rovné textovému řetězci „4“. Zadaný operátor rovnosti je často k dispozici také v těchto jazycích a vrací true pouze pro hodnoty se stejnými nebo ekvivalentními typy (v PHP, 4 === "4"
je nepravdivé 4 == "4"
je pravda).[1][2] Pro jazyky, kde lze číslo 0 interpretovat jako Nepravdivé, tento operátor může zjednodušit věci, jako je kontrola nuly (jako x == 0
by platilo pro x, které je buď 0 nebo "0" pomocí operátoru agnostické rovnosti typu).
Objednávání
Větší než a méně než porovnání nečíselných dat se provádí podle konvence řazení (například pro textové řetězce, lexikografický řád ), které mohou být zabudovány do programovacího jazyka a / nebo konfigurovatelné programátorem.
Když je žádoucí přidružit číselnou hodnotu k výsledku srovnání mezi dvěma datovými položkami, řekněme A a b, obvyklá konvence je přiřadit −1 pokud a b. Například funkce C. strcmp
provádí a třícestné srovnání a vrací -1, 0 nebo 1 podle této konvence a qsort očekává, že porovnávací funkce vrátí hodnoty podle této konvence. v třídicí algoritmy, účinnost srovnávacího kódu je zásadní, protože je to jeden z hlavních faktorů přispívajících k výkonu řazení.
Porovnání definováno programátorem typy dat (datové typy, pro které programovací jazyk nemá vestavěné porozumění) lze provádět pomocí vlastních písemných nebo knihovních funkcí (například strcmp
výše), nebo v některých jazycích přetížení operátor porovnání - tj. přiřazení významu definovaného programátorem, který závisí na porovnávaných datových typech. Další alternativou je použití nějaké konvence, jako je členské srovnání.
Logická rovnocennost
I když možná zpočátku nezvyklý, jako booleovský logické operátory XOR, AND, OR a NOT mohou být navrženy tak, aby měly relační operátory logická ekvivalence, takže je lze všechny navzájem definovat. Následující čtyři podmíněné příkazy mají stejnou logickou ekvivalenci E (buď všechny pravdivé, nebo všechny nepravdivé) pro jakýkoli daný X a y hodnoty:
To závisí na bytí domény dobře objednané.
Standardní relační operátoři
Níže jsou uvedeny nejběžnější numerické relační operátory používané v programovacích jazycích.
Konvence | rovná | nerovná se | větší než | méně než | větší než nebo rovno | méně než nebo rovno |
---|---|---|---|---|---|---|
V tisku | = | ≠ | > | < | ≥ | ≤ |
FORTRAN[poznámka 1] | .EQ. | .NE. | . GT. | .LT. | .GE. | .LE. |
ALGOL 68[poznámka 2] | = | ≠ | > | < | ≥ | ≤ |
/= | >= | <= | ||||
ekv | ne | gt | lt | ge | le | |
APL | = | ≠ | > | < | ≥ | ≤ |
ZÁKLADNÍ, ML, Pascal[Poznámka 3] | = | <> | > | < | >= | <= |
PŘÍUŠNICE | = | '= | > | < | '< | '> |
Lua | == | ~= | > | < | >= | <= |
C-jako[poznámka 4] | == | != | > | < | >= | <= |
Erlang | == | /= | > | < | >= | =< |
=:= | =/= | |||||
Jako Bourne mušle[poznámka 5] | -ekv | -ne | -gt | -lt | -ge | -le |
Dávkový soubor | EQU | NEQ | GTR | LSS | GEQ | LEQ |
MATLAB[poznámka 6] | == | ~= | > | < | >= | <= |
eq (x, y) | ne (x, y) | gt (x, y) | lt (x, y) | ge (x, y) | le (x, y) | |
Fortran 90[poznámka 7], Haskell | == | /= | > | < | >= | <= |
Mathematica[3] | == | != | > | < | >= | <= |
Rovné [x, y] | Nerovné [x, y] | Větší [x, y] | Méně [x, y] | GreaterEqual [x, y] | LessEqual [x, y] |
- ^ Včetně FORTRAN II, III, IV, 66 a 77.
- ^ ALGOL 68: stropping režimy se používají v kódu na platformách s omezenými znakovými sadami (např., použijte
>=
neboGE
namísto≥
), platformy s čtučně
důraz (použití'ge'
), nebo platformy pouze s VELKÁ KASA (použití.GE
nebo'GE'
). - ^ Počítaje v to ALGOL, Simula, Modula-2, Eiffelova, SQL, tabulkové vzorce, a další.
- ^ Počítaje v to C, C ++, C#, Jít, Jáva, JavaScript, Perl (pouze číselné srovnání), PHP, Krajta, Rubín, a R.
- ^ Počítaje v to Bourneova skořápka, Bash, KornShell, a Windows PowerShell. Symboly
<
a>
se obvykle používají v prostředí pro přesměrování, takže je nutné použít jiné symboly. Bez pomlčky se používá v Perl pro porovnání řetězců. - ^ MATLAB, i když v jiných ohledech používá podobnou syntaxi jako C, nepoužívá
!=
, tak jako!
v MATLABu odešle následující text jako příkazový řádek do operační systém. První forma se také používá v Pokec, s výjimkou rovnosti, která je=
. - ^ Včetně FORTRAN 95, 2003, 2008 a 2015.
Ostatní konvence jsou méně časté: Společný Lisp a Macsyma /Maxima použijte operátory typu Basic s výjimkou nerovnosti, což je /=
ve společných Lisp a #
v Macsyma / Maxima. Starší Lispy použitý rovnat se
, větší
, a méně
; a negoval je pomocí ne
pro zbývající operátory.
Syntax
Relační operátory se také používají v technické literatuře místo slov. Relační operátoři jsou obvykle zapsáni infixová notace, pokud je podporován programovacím jazykem, což znamená, že se objevují mezi svými operandy (dva výrazy jsou příbuzné). Například výraz v Pythonu vytiskne zprávu, pokud X je méně než y:
-li X < y: tisk(„x je v tomto příkladu menší než y“)
Jiné programovací jazyky, jako např Lisp, použijte prefixový zápis, jak následuje:
(>= X Y)
Řetězení operátora
V matematice je běžnou praxí řetězit relační operátory, například v 3
Mnoho nedávných programovacích jazyků by však vidělo výraz jako 3 (3 <4)
true
Je možné uvést výraz x
Některé jazyky, jako Společný Lisp, použijte k tomu více predikátů argumentů. V Lispu (<= 1 x 10)
platí, když x je mezi 1 a 10.
Zmatek s operátory přiřazení
Brzy FORTRAN (1956–1957) byl omezen silně omezenými znakovými sadami =
byl jediným dostupným relačním operátorem. Nebyly žádné <
nebo >
(a rozhodně ne ≤
nebo ≥
). To donutilo designéry definovat symboly jako např . GT.
, .LT.
, .GE.
, .EQ.
atd. a následně bylo lákavé použít zbývající =
znak pro kopírování, navzdory zjevné nesoudržnosti s matematickým využitím (X = X + 1
by mělo být nemožné).
Mezinárodní algebraický jazyk (IAL, ALGOL 58 ) a ALGOL (1958 a 1960) :=
pro přiřazení, opuštění standardu =
k dispozici pro rovnost, konvence následovaná CPL, ALGOL W, ALGOL 68, Základní kombinovaný programovací jazyk (BCPL ), Simula, NASTAVIT jazyk (SETL ), Pascal, Pokec, Modula-2, Ada, Standardní ML, OCaml, Eiffelova, Objekt Pascal (Delphi ), Oberon, Dylan, VHSIC Hardware Description Language (VHDL ) a několik dalších jazyků.
B a C.
Tento jednotný de facto standard mezi většinou programovacích jazyků byl nakonec nepřímo změněn minimalistickým kompilovaným jazykem s názvem B. Jeho jedinou zamýšlenou aplikací bylo jako vozidlo pro první přístav (tehdy velmi primitivní) Unix, ale také se vyvinul do velmi vlivného C Jazyk.
B začínal jako syntakticky změněná varianta programovacího jazyka systémů BCPL, zjednodušená (a bez typická) verze CPL. V procesu, který byl popsán jako „strip-down“ proces, a
a nebo
provozovatelé BCPL[5] byly nahrazeny &
a |
(který by se později stal &&
a ||
, resp.[6]). Ve stejném procesu styl ALGOL :=
BCPL bylo nahrazeno =
v B. Důvod, proč je to všechno neznámé.[7] Protože aktualizace proměnných neměly v B žádnou speciální syntaxi (např nechat
nebo podobné) a byly povoleny ve výrazech, tento nestandardní význam znaménka rovnosti znamenal, že tradiční sémantika znaménka rovnosti nyní musela být spojena s jiným symbolem. Ken Thompson použil ad hoc ==
kombinace pro toto.
Když byl později zaveden malý typ systému, B se poté stal C. Popularita tohoto jazyka spolu s jeho spojením s Unixem vedla k tomu, že Java, C # a mnoho dalších jazyků následovaly, syntakticky, navzdory tomuto zbytečnému konfliktu s matematickým významem znaménko rovná se.
Jazyky
Přiřazení v jazyce C mají a hodnota a protože jakákoli nenulová skalární hodnota je interpretována jako skutečný v podmíněné výrazy,[8] kód if (x = y)
je legální, ale má velmi odlišný význam od if (x == y)
. Bývalý fragment kódu znamená „přiřadit y na X, a pokud nová hodnota X není nula, proveďte následující příkaz ". Druhý fragment znamená"kdyby a jen kdyby X je rovný y, proveďte následující příkaz ".[9]
int X = 1; int y = 2; -li (X = y) { / * Tento kód se provede vždy, když y je něco jiného než 0 * / printf("x je% d a y je% d n", X, y); }
Ačkoli Jáva a C# mají stejné operátory jako C, tato chyba obvykle místo toho způsobí chybu kompilace v těchto jazycích, protože podmínka if musí být typu booleovský
, a neexistuje žádný implicitní způsob převodu z jiných typů (např., čísla) do booleovský
s. Takže pokud proměnná, která je přiřazena, nemá typ booleovský
(nebo typ obalu Booleovský
), dojde k chybě kompilace.
V jazycích podobných ALGOL, jako jsou Pascal, Delphi a Ada (v tom smyslu, že to umožňují) definice vnořených funkcí ) a v Krajta a mnoho funkčních jazyků, mimo jiné, operátoři přiřazení se nemohou objevit v výraz (počítaje v to -li
klauzule), což vylučuje tuto třídu chyb. Někteří kompilátoři, jako např Sbírka překladačů GNU (GCC), poskytují varování při kompilaci kódu obsahujícího operátor přiřazení uvnitř příkazu if, i když existují určitá legitimní použití přiřazení uvnitř podmínky if. V takových případech musí být přiřazení explicitně zabaleno do dvojice závorek, aby se zabránilo varování.
Podobně i některé jazyky, například ZÁKLADNÍ použijte pouze =
symbol pro oba úkoly a rovnost, protože jsou syntakticky oddělené (jako u Pascal, Ada, Python atd., operátory přiřazení se ve výrazech nemohou objevit).
Někteří programátoři mají ve zvyku psát srovnání s konstantou v opačném pořadí, než je obvyklé:
-li (2 == A) { / * Chybné použití = versus == by byla chyba při kompilaci * / }
Li =
je použit omylem, výsledný kód je neplatný, protože 2 není proměnná. Kompilátor vygeneruje chybovou zprávu, kterou lze nahradit správným operátorem. Tento styl kódování se nazývá levostranné srovnání, nebo Podmínky Yoda.
Tato tabulka uvádí různé mechanismy pro testování těchto dvou typů rovnosti v různých jazycích:
Jazyk | Fyzická rovnost | Strukturální rovnost | Poznámky |
---|---|---|---|
ALGOL 68 | a: =: b nebo A je b | a = b | když A a b jsou ukazatele |
C, C ++ | a == b | * a == * b | když A a b jsou ukazatele |
C# | object.ReferenceEquals (a, b) | a. Rovnice (b) | The == operátor má výchozí nastavení ReferenceEquals , ale může být přetížený vystupovat Rovná se namísto. |
Společný Lisp | (ekv a b) | (rovná se b) | |
Erlang | a =: = b | a == b | když a a b jsou čísla |
Jít | a == b | reflect.DeepEqual (* a, * b) | když a a b jsou ukazatele |
Jáva | a == b | a. rovná se (b) | |
JavaScript | a === b | a == b | když a a b jsou dva řetězcové objekty obsahující ekvivalentní znaky, operátor === stále vrátí true. |
OCaml, Pokec | a == b | a = b | |
Pascal | a ^ = b ^ | a = b | |
Perl | $ a == $ b | $$ a == $$ b | když $ a a $ b jsou odkazy na skaláry |
PHP | $ a === $ b | $ a == $ b | když $ a a $ b jsou objekty |
Krajta | a je b | a == b | |
Rubín | a. rovný? (b) | a == b | |
Systém | (ekv. a b) | (stejné? a b) | |
Rychlý | a === b | a == b | když a a b mají typ třídy |
Visual Basic .NET[nerovnost 1] | a je b nebo object.ReferenceEquals (a, b) | a = b nebo a. Rovnice (b) | Stejné jako C # |
Cíl-C (Kakao, GNUstep ) | a == b | [a isEqual: b] | když A a b jsou ukazatele na objekty, které jsou instancemi NSObject |
- ^ Patentová přihláška: 14. května 2003, Americká přihláška 20 040 230 959 „IS NOT OPERATOR“ byl podán pro
NENÍ
provozovatel zaměstnanci společnosti Microsoft. Tento patent byl udělen 18. listopadu 2004.
Ruby používá a === b
znamená „b je členem množiny a“, ačkoli podrobnosti toho, co to znamená být členem, se značně liší v závislosti na použitých datových typech. ===
je zde známý jako operátor „rovnost případů“ nebo „subsumpce případu“.
Viz také
- Binární relace
- Běžná notace operátora
- Podmíněné (počítačové programování)
- Rovnost (matematika)
- Znaménko rovná se
- Logický operátor
- Provoz (matematika)
- Operátor (matematika)
- Operátor (počítačové programování)
- Provozovatel kosmické lodi
- Triadický vztah
Poznámky a odkazy
- ^ Přispěvatelé. „Porovnávání objektů“. Manuál PHP. Skupina PHP. Citováno 29. června 2014.
- ^ "PHP: Porovnávací operátoři - manuální". Citováno 31. července 2008.
- ^ Relační a logické operátory z Mathematica
- ^ Alexandrescu, Andrei. Programovací jazyk D.. Addison Wesley. str. 58. ISBN 978-0-321-63536-5.
- ^ Používá se nejen v jazycích podobných ALGOLU, ale také ve FORTRANU a BASICU
- ^ Protože někteří programátoři byli zmateni dvojím významem (bitový operátor a logická spojka) těchto nových symbolů (podle Dennis Ritchie ). Pouze bitový význam & a | byly uchovány.
- ^ Ačkoli Dennis Ritchie navrhl, že to mohlo mít co do činění s „ekonomikou psaní“, protože aktualizace proměnných mohou být častější než srovnání v určitých typech programů
- ^ Nulová skalární hodnota je interpretována jako false, zatímco jakákoli nenulová skalární hodnota je interpretována jako true; toto se obvykle používá s celočíselnými typy, podobně jako montážní jazyk idiomy.
- ^ Brian Kernighan a Dennis Ritchie (1988) [1978]. Programovací jazyk C. (Druhé vydání.). Prentice Hall., 19