热门问题
时间线
聊天
视角
值 (電腦科學)
電腦科學中無法進一步評估的表達式 来自维基百科,自由的百科全书
Remove ads
在計算機科學中,值(英語:Value)是一無法進一步求值的表達式。[1]例如,表達式「1 + 2」不是一個值,因為它可以被化簡為表達式「3」。表達式「3」不能夠繼續化簡,因此它是一個值。表達式既有類型(type)屬性,又有值分類(value categories)屬性。兩種屬性彼此獨立。[2]也就是說,對每一種類型的表達式,都有各種值分類。
此條目需要補充更多來源。 (2013年2月11日) |
大多數編程語言支持幾種常見的值。
賦值:左值和右值
一些語言使用左值(l-value)和右值(r-value)的概念。左值具有確定的、可以被獲得的內存地址。這意味着左值可以是變量,也可以是對指向特定內存地址的指針解引用(dereference)的結果。例如C語言的表達式(4 + 9)
,在執行時,計算機生成一個整數值13,但因為程序沒有明確指定這個13如何在計算機中存儲,所以這個表達式產生一個右值。另一方面,如果一個C程序聲明了一個變量x並將x賦值為13,那麼表達式(x)
的值是13,並且是一個左值。
在C語言中,術語「左值」最初表示可以被賦值(即位於賦值運算符左側)的對象,但由於「const」被加入到語言中,這類對象現在被稱作「可更改的左值」。C++中,左值和右值是表達式的分類,一個表達式必然是左值或右值之一。C++11把上述左值性(lvalueness)擴充為更複雜的值類別(value category),包含左值(lvalue),純右值(prvalue)和臨終值(xvalue)三個基本分類(fundamental classification),一個表達式必然是三者之一。
左值和右值的概念最早由CPL程序語言的一篇論文引入。[3]這時定義的左值是可以放在賦值號左側賦予新值的對象;[4]右值是可以放在賦值號右側讀出其值的對象。在B語言中,左值和右值作為文法的元素被明確。在C語言中,文法不再出現左值和右值的區別,左值的概念被保留在語義規則中,而「右值」在ISO C中被視為「值」的同義詞。
C++語言引入了const限定的對象。const對象可以取地址,但是不能被賦值;而一些右值對象也可以出現在賦值號的左邊被賦值。[5]因此,截至C++03標準,把具有標識(identity)的表達式規定為左值,不具有標識的表達式規定為右值。因而,名字、指針、引用等是左值,是命名對象,具有確定的內存地址;字面量、臨時對象等為右值,右值僅在創建它的表達式中可以被訪問。函數名字是左值(在C語言中規定它既不是左值也不是右值),數組名是常量左值,但是在大多數表達式中函數名字與數組名字自動隱式轉換為右值。右值的生存期短暫,所以需要用左值去捕捉右值。把右值複製(copy)到左值上是常見操作。
C++11標準引入了右值引用數據類型與移動語義,因而左值與右值的定義發生了很大變化。右值引用變量綁定到右值上,延長了右值對應的臨時對象的生存期。移動語義把臨時對象的內容移動(move)到左值對象上。因而在C++11,對於值的分類,要考慮標識(identity)與可移動性(movability),二者的組合產生了五種分類:
- 基礎值類型
- 左值lvalue:可以用取地址運算符&獲取地址的表達式。也可定義為非臨時對象或非成員函數。具有標識,但不可移動。這也是C++03的經典左值。可用於初始化左值引用。可以有不完備類型(incomplete type)。包括:
- 作用域中的變量名與函數名,不論其類型。因此,具名的右值引用,即具有右值引用類型的變量,也是左值表達式,這符合一般規律,不是特例。
- 函數調用表達式或重載運算符表達式,如果其返回類型為左值引用或者是到函數類型的右值引用。 [6]
- 內建的先增(前綴++)、先減(前綴--)、解引用(dereference)、賦值、複合賦值、下標(除了數組臨終值)、成員訪問(除了臨終值的非靜態非引用成員、成員枚舉值、非靜態成員函數),通過數據成員指針的訪問且左端操作數為左值、逗號運算符且右端的操作數為左值、三元條件運算符(ternary conditional)且第二與第三操作數為左值。
- 到左值引用類型的類型轉換表達式。
- 字符串字面量(string literal)
- 類型轉換表達式,轉換為到函數的右值引用
- 臨終值xvalue(expiring value):具有標識,並且可以移動。對應的對象接近生存期結束,但其內容尚未被移走。可以多態;非類對象可以cv限定。包括:
- 純右值prvalue:不具有標識,但可以移動。對應臨時對象或不對應任何對象的值。純右值不能是多態的;臨時對象的動態類型是表達式類型;非類且非數組的純右值不能是const限定的;不能有不完備類型(除了void)。包括:
- 字面量(除了字符串字面量)。
- 函數調用或重載的運算符表達式,如果返回類型不是引用。[6]
- 內建後增、後減、算術與邏輯運算符、比較運算符、取地址運算符、訪問成員枚舉值、訪問非靜態成員函數、訪問右值的非靜態非引用數據成員、訪問右值的數據成員指針或非靜態函數成員指針、逗號運算符且右端操作數為右值、三元條件運算符且第二或第三操作數不是左值。
- 類型轉換表達式,轉換為非引用類型。
- Lambda表達式
- 左值lvalue:可以用取地址運算符&獲取地址的表達式。也可定義為非臨時對象或非成員函數。具有標識,但不可移動。這也是C++03的經典左值。可用於初始化左值引用。可以有不完備類型(incomplete type)。包括:
- 廣義左值glvalue:具有標識。包括左值與臨終值。可以多態、動態類型。
- 右值rvalue:可以移動。包括瀕死值與純右值。不能通過&運算符取地址。
C++的非靜態成員函數調用表達式(obj.func與ptr->func),非靜態成員函數指針調用表達式(obj.*mfp與ptr->*mfp)被當作純右值,但是不能用於初始化引用,不能做函數實參,僅僅能用作函數調用表達式左邊的操作數,如(pobj->*ptr)(args)。
返回void的函數調用表達式、到void的類型轉換表達式、throw表達式被當作純右值。但是不能用於初始化引用,不能做函數實參。可用於某些上下文環境中(如單獨作為一行語句、逗號操作符的左端表達式等),或返回void的函數的return語句中。此外,throw表達式可用作三元條件操作符的第二或第三操作數。
位元欄(bit field)表達式是左值,但不能用&運算符取地址,不能綁定到非常量左值引用。常量左值引用可以用位域左值初始化,但實際上是另行分配綁定了一個對象。
Remove ads
匯編語言
值可以是一個給定的數據類型,例如一個字符串,一個數字,一個單一的字母等幾乎任何類型的數據。
有些處理器支持多種尺寸的立即數,例如8位或16位,每一種指令形式採用獨特的操作碼和助記符。如果一個程序員提供的數據值不適合,匯編器將會出現「超出範圍」的錯誤消息。大多數匯編器允許一個立即數被表示為ASCII,十進制,十六進制,八進制或二進制數據。因此,ASCII字符'A'和65、0x41是一樣的。字符串的字節序在不同處理器之間可能不同,取決於匯編器和計算機體系結構。
參考資料
外部連結
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads