查看“︁關係運算子”︁的源代码
←
關係運算子
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{多個問題| {{refimprove|time=2019-05-27T18:29:36+00:00}} {{expand language|1=en|page=|time=2019-05-27T18:13:01+00:00}} {{copyedit|time=2019-05-27T18:13:49+00:00}} {{roughtranslation|time=2019-05-27T18:13:01+00:00}} }} {{NoteTA | G1 = IT }} '''關係運算子'''在計算機科學的[[編程語言]]中,是測試或定義兩個實體之間某種[[二元关系|關係]]的構造或操作符。一共有六种關係,分别为:<code>小于(<)</code>、<code>大于(>)</code>、<code>小于或等于(<=)</code>、<code>大于或等于(>=)</code>、<code>等于(==)</code>和<code>不等于(<>)</code>。在具備[[布爾_(數據類型)|布爾型別]]的編程語言中(如 Pascal,Ada 或 Java),這些運算符通常根據兩個[[運算數|操作變量]]之間的條件關係是否成立,判定為真(True)或假(False)。諸如 C 語言中關係運算子傳回整數 0 或 1,其中 0 表示假,任何非零值表示真。使用關係運算子創建的表達式,形成所謂的關係表達式或條件。 關係運算子可以被視為[[逻辑|謂詞邏輯]]的特殊情況。 == 相等性 == === 用法 === 許多編程語言的構造和[[類型系統|資料型別]]中都使用到相等性,用於測試元素是否已存在於[[集合_(计算机科学)|集合]]中,或者藉由鍵來存取值。它在切換(switch)語句,以及編程的邏輯併聯過程中,用於將控制流調度到正確的分支。相等性的可能含義之一是“如果 a 等於 b,那麼我們可以在任何情況下互換 a 或 b,而不會產生任何差異。”但這樣的聲明不一定成立,尤其在將可變性和內容等同性一起考慮時。 ===物件相等與內容等同性=== 有時,特別是在[[面向对象程序设计|物件導向編程]]中,對資料型別和繼承物件進行比對時,出現了相等性和辨別的問題。以下情況通常需要區別: * 相同型別的兩個不同物件,例如兩隻手 * 兩個物件相等但不同,例如兩張10元鈔票 * 兩個物件相等但有不同的呈現,例如$1元紙鈔和$1元硬幣 * 對同一物件的兩個不同參照,例如,同一人的兩個暱稱 在許多現代編程語言中會藉由[[參照]]來存取物件和資料結構。在這些語言中,需要測試兩種相等性質: * 實質同等性:如果有兩個參照A和B來自引用同一個物件,以A與物件進行的互動,跟藉由B與物件進行的互動,兩者其實就是相同作用而無法區別,特別是以A去改變物件的異動會反映在B之上。當討論為值而非物件時,實質同等性並不適用。 * 語義同等性:如果兩個參照物件或兩個值在某種意義上是等價的: ** 結構等式(即它們的內容是相同的),或淺薄地(僅測試目前部份)或深入地(遞歸地測試其所有部份的相等性)。實現這一點的簡易方法是通過代表等式:檢查參照的值是否有相同的代表式。 ** 其它特制的同等性,保留外部行為。例如將<math>\frac{1}{~{}2~{}}</math>和<math>\frac{2}{~{}4~{}}</math>視為有理數時,被判斷是相等的。除了[[自反關係|反射性]]、[[對稱關係|對稱性]]和[[遞移關係|傳遞性]]之外,對 A = B 特制的定義可能是“若且唯若對於物件A和物件B之上的所有操作,都將具有相同的結果時,則 A = B ”。 第一種同等性質通常蘊涵著第二種同等性質(除了[[NaN|非數字類]](not a number, NaN),它們不等於自身),但反向的同等性質並不一定成立。例如兩個字串物件可以是不同物件(第一種意義不相等),但它們包含相同的字元序列(第二種意義上相等)。有關此問題的更多信息,請參閱識別(identity)。 [[實數]]中包括許多簡[[分數]],無法以浮點算數精確地表示,所以需要在給定誤差範圍內來測試相等性。但這樣的誤差範圍將打破一些例如傳遞性、反身性的要求性質:[[IEEE 754|IEEE浮點標準]]是判斷 Nan ≠ NaN 成立(NaN不等於自身)。 其他編程元素例如可計算的函數,可能沒有相等性的意義,或者相等性是不能計算的。由於這些原因,一些語言以基礎類別、介面、特點(trait)或協定的形式,定義了“可比較”的明確概念,以源碼中的顯式聲明,被藉由型別的結構,來使用關係運算。 === 比較不同類型的值 === JavaScript,PHP 和一些其它動態型別的語言中,如果兩個值相等,等號運算符將計算為真,即使它們實際上為不同型別的物件,例如以數值4和字串"4"相比較,結果會是相等。在這類語言中通常也會提供型別相等運算子,僅對具有相同或等價型別的物件比較返回真(在PHP 5中 4 ==="4"為假,但 4 =="4" 為真)。而在將數值0也當作布爾值為假的編程語言中,該運算子可化簡為檢查物件是否為數值零(例如,對於數值0或字串"0"的x物件,使用型別相等運算子,則 x == 0 判斷傳回真值)。 ==次序比較== 非數值資料的次序比較(大於或小於)運算是根據排序慣例(例如字串依照編程語言內定的[[字典序|字典次序]],和/或可由開發人員設定的)。當兩個資料項 a 和 b 之間的比較結果,要和數值關聯時,通常慣例是如果 a < b 則結果賦值為 -1,如果 a = b 則為 0,如果 a > b 則為 1。例如C語言的函數<code>strcmp</code>執行三方向比較,並根據此慣例返回 -1, 0 或 1,而<code>qsort</code>預期比較函數依此慣例返回值。在排序演算法中比較方法源碼的效率至為關鍵,因為它是排序性能的主要因素之一。 開發人員定義的資料型別(不是編程語言內建的型別)的比較,可以編寫自訂的或使用函式庫的函數(如上文的<code>strcmp</code>)來執行,或者在某些語言中通過[[运算符重载|重載]]比較運算符-即以開發人員的定義指派給比較運算子,來比較特定資料型別。另一個選擇是使用某些慣例,例如成員比較。 == 邏輯等價 == 雖然一開始可能不那麼顯而易見,像布爾邏輯運算符 XOR,AND,OR 和 NOT,這些關係運算子可以設計為具有邏輯等同性,使得它們都可以相互定義。對於任何給定的 x 和 y 值,以下四個條件語句都有相同的邏輯等價性 E(全為真或全為假): :<math> E = \begin{cases} x < y \\ y > x \\ x \ngeq y \\ y \nleq x \end{cases}</math> 這依賴於域是[[良序关系|良好排序]]的。 == 標準關係運算符 == 在編程語言中最常見到的數值關係運算子如下所示。 {| class="wikitable" style="text-align: center;" |+ Common relational operators ! Convention ! ''equal to'' ! ''not equal to'' ! ''greater than'' ! ''less than'' ! ''greater than<br>or equal to'' ! ''less than<br>or equal to'' |- ! In print | = | ≠ | > | < | ≥ | ≤ |- ![[FORTRAN]]<ref group="note">Including FORTRAN II, III, IV, 66 and 77.</ref> | <code>.EQ.</code> | <code>.NE.</code> | <code>.GT.</code> | <code>.LT.</code> | <code>.GE.</code> | <code>.LE.</code> |- ! rowspan=3 | [[ALGOL 68]]<ref group="note">[[ALGOL 68]]: ''[[Stropping (syntax)|stropping]]'' regimes are used in code on platforms with limited character sets (''e.g.'', use <code>>=</code> or <code>GE</code> instead of <code>≥</code>), platforms with no <code>'''bold'''</code> [[Emphasis (typography)|emphasis]] (use <code>'ge'</code>), or platforms with only [[UPPERCASE]] (use <code>.GE</code> ''or'' <code>'GE'</code>).</ref> |rowspan=2| <code>=</code> | <code>≠</code> |rowspan=2| <code>></code> |rowspan=2| <code><</code> | <code>≥</code> | <code>≤</code> |- | <code>/=</code> | <code>>=</code> | <code><=</code> |- | <code>'''eq'''</code> | <code>'''ne'''</code> | <code>'''gt'''</code> | <code>'''lt'''</code> | <code>'''ge'''</code> | <code>'''le'''</code> |- ! [[APL (programming language)|APL]] | <code>=</code> | <code>≠</code> | <code>></code> | <code><</code> | <code>≥</code> | <code>≤</code> |- ! [[BASIC]]-like, [[spreadsheet]] formulas<ref group="note">Including [[Visual Basic .NET]], [[OCaml]], [[SQL]], [[Standard ML]], [[Microsoft Excel|Excel]], and others.</ref> | <code>=</code> | <code><></code> | <code>></code> | <code><</code> | <code>>=</code> | <code><=</code> |- ! [[MUMPS]] | <code>=</code> | <code>'=</code> | <code>></code> | <code><</code> | <code>'<</code> | <code>'></code> |- ! [[Lua (programming language)|Lua]] | <code>==</code> | <code>~=</code> | <code>></code> | <code><</code> | <code>>=</code> | <code><=</code> |- ! [[Pascal語言|Pascal-like]]<ref group="note">Including [[ALGOL]], [[Simula]], [[Modula-2]], [[Object Pascal]] ([[Delphi (programming language)|Delphi]]), [[OCaml]], [[Standard ML]], [[Eiffel (programming language)|Eiffel]], [[APL (programming language)|APL]], and others.</ref> | <code>=</code> | <code><></code> | <code>></code> | <code><</code> | <code>>=</code> | <code><=</code> |- ! [[C (programming language)|C-like]]<ref group="note">Including [[C语言|C]], [[C++]], [[C Sharp (programming language)|C#]], [[Go (programming language)|Go]], [[Java]], [[JavaScript]], [[Perl]] (numerical comparison only), [[PHP]], [[Python]], [[Ruby]], and [[R (programming language)|R]].</ref> | <code>==</code> | <code>!=</code> | <code>></code> | <code><</code> | <code>>=</code> | <code><=</code> |- ! [[Unix shell#Bourne shell compatible|Bourne-like]] [[Shell (computing)|shells]]<ref group="note">Including [[Bourne shell]], [[Bash (Unix shell)|Bash]], [[Korn shell]], and [[Windows PowerShell]]. The symbols <code><</code> and <code>></code> are usually used in a shell for [[Redirection (computing)|redirection]], so other symbols must be used. Without the hyphen, is used in [[Perl]] for string comparison.</ref> | <code>-eq</code> | <code>-ne</code> | <code>-gt</code> | <code>-lt</code> | <code>-ge</code> | <code>-le</code> |- ! [[Batch file]] | <code>EQU</code> | <code>NEQ</code> | <code>GTR</code> | <code>LSS</code> | <code>GEQ</code> | <code>LEQ</code> |- ! rowspan="2" |[[MATLAB]]<ref group="note">MATLAB, although in other respects using similar syntax as C, does not use <code>!=</code>, as <code>!</code> in MATLAB sends the following text as a command line to the [[operating system]]. The first form is also used in [[Smalltalk]], with the exception of equality, which is <code>=</code>.</ref> | <code>==</code> | <code>~=</code> | <code>></code> | <code><</code> | <code>>=</code> | <code><=</code> |- | <code>eq(x,y)</code> | <code>ne(x,y)</code> | <code>gt(x,y)</code> | <code>lt(x,y)</code> | <code>ge(x,y)</code> | <code>le(x,y)</code> |- ! [[Fortran 90]]<ref group="note">Including FORTRAN 95, 2003, 2008 and 2015.</ref> | <code>==</code> | <code>/=</code> | <code>></code> | <code><</code> | <code>>=</code> | <code><=</code> |- ! rowspan="2" |[[Mathematica]]<ref>[http://reference.wolfram.com/mathematica/tutorial/RelationalAndLogicalOperators.html Relational and Logical Operators] {{Wayback|url=http://reference.wolfram.com/mathematica/tutorial/RelationalAndLogicalOperators.html |date=20131227073010 }} of [[Mathematica]]</ref> | <code>==</code> | <code>!=</code> | <code>></code> | <code><</code> | <code>>=</code> | <code><=</code> |- | <code>Equal[x,y]</code> | <code>Unequal[x,y]</code> | <code>Greater[x,y]</code> | <code>Less[x,y]</code> | <code>GreaterEqual[x,y]</code> | <code>LessEqual[x,y]</code> |} {{Reflist|group="note"}} 其他較少見的:Common Lisp的不等關係運算子是 /=,Macsyma/Maxima 的不等關係運算子是 #。舊的Lisp使用equal,greaterp 和 lessp; 而以not運算子作邏輯否定。 == 語法 == 關係運算子也用於技術文獻而不是單詞,如果編程語言支援通常以[[中綴表示法]],亦即出現在其操作變量(兩個表達式是相關的)之間。 舉例而言如果 x 小於 y,在Python中的表達式將印出句子: <syntaxhighlight lang="python"> if x < y: print("x is less than y in this example") </syntaxhighlight> 其他編程語言如 Lisp 使用[[前綴表示法]],如下所示: <syntaxhighlight lang="lisp"> (>= X Y) </syntaxhighlight> === 操作符鏈接 === 鏈接關係在數學中是普遍的寫法,例如 3 < x < y < 20 表示 3 < x 而且 x < y 而且 y <20。語義是很清楚的,因為數學中這些關係運算是有傳遞性的。然而,許多最近的編程語言會把 3 < x < y 的表達式,看作兩個左(或右)關係運算子的組合,而解譯為<code>(3 < x ) < y</code>。如果我們設 x = 4 則得到<code>(3 < 4 )< y</code>,而運算式變成<code>true < y</code>,這是無意義的。但它卻可能通過 C/C++ 和一些其它語言的編譯(因為 true 會以數值1代表)。 有些編程語言如Python和Perl 6 能正確給出<code>x < y < z</code>表達式所代表的數學意義,其它種語言則不, 部份是因大多數運算符在C語言種類中,以中綴表示法的運作方式有所不同。D編程語言保持與C的一些兼容性,而“允許C語言表達式卻有微妙不同的語義(雖然可說是方向正確),與便利性比起來造成更多的混淆”。 有些語言如 Common Lisp,對此則使用多參數謂詞。當 ''x'' 在 1 和 10 之間時,評估比較運算式 <code>(<= 1 x 10)</code>結果為真。 === 與賦值運算子的混淆情況 === 早期(西元1956-57年)FORTRAN編程語言受限於有限的字集,其中等號“=”是唯一的關係運算子,沒有數學上通用的大於“<”或小於“>”關係符號(當然也就沒有不大於“≤”或不小於“≥”之類的關係符號),迫使設計者定義如<code>.GT.</code>、<code>.LT.</code>、<code>.GE.</code>、<code>.EQ.</code>這樣的關係符號,隨後等號“=”字符被人借用來執行複製,儘管此用法與數學意義明顯不一致(X = X + 1 在數理是不能成立的)。 因此國際代數語言(IAL,ALGOL 58)和 ALGOL(1958和1960)引入了“:=”表示賦值操作,留下等號“=”字符作為相等關係的標準,遵循這個慣例的編程語言有CPL,ALGOL W,ALGOL 68,BCPL,Simula,SET(SETL),Pascal,Smalltalk,Modula-2,Ada,Standard ML,OCaml,Eiffel,Object Pascal(Delphi),Oberon,Dylan,VHSIC(VHDL)等。 ====B 和 C 編程語言 ==== 大多數編程語言遵循的這種事實標準,後來被名為B的極簡編譯語言間接改變。它唯一的應用目標是作為(一個非常原始的)Unix的最初移植版本,但它也演變成非常有影響力的 C 編程語言。 B 最初是系統編程BCPL的語法變體,簡化(無型別)的CPL版本。在描述為 “拆解” 過程的情況下,BCPL的交集和聯集運算子被替換為<code>&</code>和<code>|</code>(後來變成<code>&&</code>和<code>||</code>)。 同樣的過程中,原來具有ALGOL風格在BCPL語言中表示賦值操作的<code>:=</code>符號,在B語言中被替換為<code>=</code>。導致這種演變過程的原因未知。由於變量賦值在B語言中沒有特殊語法(例如 let 或類似),而在表達式中允許這個操作,所以等號的傳統語義(相等關係)和非標準涵義(變量賦值)另外相關聯在一起。為了區分這兩種意義,因此[[肯·汤普逊|Ken Thompson]]使用了特別的雙等號<code>==</code>組合取代相等關係判斷。 一個小的型別系統後來被引入,B接著演變成C。C語言的普及與Unix的關聯,使Java,C#和許多其他語言沿用這種語法,雖然已經大不相同於等號的數學關係涵義。 ==== 編程語言 ==== C編程的賦值語句會有返回值,由於任何非零值在[[條件運算式]]中被解譯為真,源碼<code>if(x = y)</code>是合法的,但與<code>if(x == y)</code>的意義完全相異。前者語義為“將 y 賦值給 x,如果 x 的新值不為 0,則執行以下語句”;後者語義則為“如果僅當 x 等於 y,執行以下語句”。 <syntaxhighlight lang="c"> int x = 1; int y = 2; if (x = y) { /* This code will always execute if y is anything but 0*/ printf("x is %d and y is %d\n", x, y); } </syntaxhighlight> 雖然Java和C#具有與C相同的運算子,但這種錯誤通常會導致這些編程的編譯錯誤,因為條件式必須是布林型別,而且沒有隱式方法能從其它類型(如數值)轉為布林型別。 因此,除非被賦值的變量具有布林型別(或包裝為布林型別),否則會產生編譯錯誤。 ALGOL類的語言中例如Pascal,Delphi和Ada(允許其編程可定義嵌套函數),Python和許多函數語言中,賦值運算子不可出現在表達式中(包括if子句),排除了這種錯誤。一些編譯器如GNU編譯器集合(GCC),則在編譯<code>if</code>語句中包含賦值運算子的源碼時,提供了警告,雖然在if條件中可以有一些賦值的合法使用。在此情況下賦值語句必須對額外的括號特別聲明,以避免警告。 同樣地,一些語言如BASIC使用“=”等號同時代表賦值操作和相等關係兩者,因為在語法上它們是分開的(如Pascal,Ada,Python等,賦值運算子不能出現在表達式中)。 有些程序員習慣於逆向(一般從左到右條件判斷)寫一個常數的比較: <syntaxhighlight lang="c"> if (2 == a) { /* Mistaken use of = versus == would be a compile-time error */ } </syntaxhighlight> 如果意外使用了<code>=</code>,因為 2 不是變量則源碼的編譯無效,編譯器會產生一個錯誤訊息,指出在等號的位置應該以適當的運算子替換。這種編程寫法被稱為左手比較或[[尤達條件式]]。 下表列出了各種編程測試型別相等的不同機制: {| class="wikitable" |- ! Language !! Physical equality !! Structural equality !! Notes |- | [[ALGOL 68]] || <code>a :=: b</code> ''or'' <code>a ''is'' b</code> || <code>a = b</code> || when <code>a</code> and <code>b</code> are pointers |- | [[C语言|C]], [[C++]] || <code>a == b</code> || <code>*a == *b</code> || when <code>a</code> and <code>b</code> are pointers |- | [[C Sharp (programming language)|C#]] || <code>object.ReferenceEquals(a, b)</code> || <code>a.Equals(b)</code> || The <code>==</code> operator defaults to <code>ReferenceEquals</code>, but can be [[Operator overloading|overloaded]] to perform <code>Equals</code> instead. |- | [[Common Lisp]] || <code>(eq a b)</code> || <code>(equal a b)</code> || |- | [[Go (programming language)|Go]] || <code>a == b</code> || <code>reflect.DeepEqual(*a, *b)</code> || when a and b are pointers |- | [[Java]] || <code>a == b</code> || <code>a.equals(b)</code> || |- | [[JavaScript]] || <code>a === b</code> || <code>a == b</code> || when a and b are two string objects containing equivalent characters, the === operator will still return true. || |- | [[OCaml]], [[Smalltalk]] || <code>a == b</code> || <code>a = b</code> || |- | [[Pascal語言|Pascal]] || <code>a^ = b^</code> ||<code>a = b</code> || |- | [[Perl]] || <code>$a == $b</code> || <code>$$a == $$b</code> || when <code>$a</code> and <code>$b</code> are references to scalars |- | [[PHP]]5 || <code>$a === $b</code> || <code>$a == $b</code> || when <code>$a</code> and <code>$b</code> are objects |- | [[Python]] || <code>a is b</code> || <code>a == b</code> || |- | [[Ruby]] || <code>a.equal?(b)</code> || <code>a == b</code> || |- | [[Scheme (programming language)|Scheme]]|| <code>(eq? a b)</code> || <code>(equal? a b)</code> || |- | [[Swift (programming language)|Swift]]|| <code>a === b</code> || <code>a == b</code> || when a and b have class type |- | [[Visual Basic .NET]]<ref group="inequality">Patent application: On May 14, 2003, {{US patent application|20040230959}} "IS NOT OPERATOR" was filed for the <code>ISNOT</code> operator by employees of [[Microsoft]]. This patent was granted on November 18, 2004.</ref>|| <code>a Is b</code> or <code>object.ReferenceEquals(a, b)</code> || <code>a = b</code> or <code>a.Equals(b)</code> || Same as C# |- | [[Objective-C]] ([[Cocoa (API)|Cocoa]], [[GNUstep]]) || <code>a == b</code> || <code>[a isEqual:b]</code> || when <code>a</code> and <code>b</code> are pointers to objects that are instances of <code>NSObject</code> |} {{Reflist|group="inequality"}} == 另見 == *[[二元关系|二元關係]] *[[等于|等於(數學)]] *[[逻辑运算符|邏輯運算子]] *[[等号]] == 参考 == {{reflist}} [[Category:运算符 (编程)]] [[Category:二元運算]] [[Category:不等]] [[Category:带有C代码示例的条目]]
该页面使用的模板:
Template:NoteTA
(
查看源代码
)
Template:Reflist
(
查看源代码
)
Template:Wayback
(
查看源代码
)
Template:多個問題
(
查看源代码
)
返回
關係運算子
。
导航菜单
个人工具
登录
命名空间
页面
讨论
不转换
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
工具
链入页面
相关更改
页面信息