值 (電腦科學)

在计算机科学中，值（）是一无法进一步求值的表达式。例如，表达式“1 + 2”不是一个值，因为它可以被化简为表达式“3”。表达式“3”不能够继续化简，因此它是一个值。表达式既有类型（type）属性，又有值分类（value categories）属性。两种属性彼此独立。也就是说，对每一种类型的表达式，都有各种值分类。

大多数编程语言支持几种常见的值。

賦值：左值和右值 
一些语言使用左值（）和右值（）的概念。左值具有确定的、可以被获得的内存地址。这意味着左值可以是变量，也可以是对指向特定内存地址的指针解引用（dereference）的结果。例如C语言的表达式(4 + 9)，在执行时,计算机生成一个整数值13，但因为程序没有明确指定这个13如何在计算机中存储，所以这个表达式产生一个右值。另一方面，如果一个C程序声明了一个变量x并将x赋值为13，那么表达式(x)的值是13，并且是一个左值。

在C语言中，术语“左值”最初表示可以被赋值（即位于赋值运算符左侧）的对象，但由于“const”被加入到语言中，这类对象现在被称作“可更改的左值”。C++中，左值和右值是表达式的分类，一个表达式必然是左值或右值之一。C++11把上述左值性(lvalueness)扩充为更复杂的值类别(value category)，包含左值（），纯右值（）和临终值（）三个基本分类(fundamental classification)，一个表达式必然是三者之一。

左值和右值的概念最早由CPL程序语言的一篇论文引入。 这时定义的左值是可以放在赋值号左侧赋予新值的对象；右值是可以放在赋值号右侧读出其值的对象。在B语言中，左值和右值作为文法的元素被明确。在C语言中，文法不再出现左值和右值的区别，左值的概念被保留在语义规则中，而“右值”在ISO C中被视为“值”的同义词。

C++语言引入了const限定的对象。const对象可以取地址，但是不能被赋值；而一些右值对象也可以出现在赋值号的左边被赋值。因此，截至C++03标准，把具有标识（identity）的表达式规定为左值，不具有标识的表达式规定为右值。因而，名字、指针、引用等是左值，是命名对象，具有确定的内存地址；字面量、临时对象等为右值，右值仅在创建它的表达式中可以被访问。函数名字是左值（在C语言中规定它既不是左值也不是右值），数组名是常量左值，但是在大多数表达式中函数名字与数组名字自动隐式转换为右值。右值的生存期短暂，所以需要用左值去捕捉右值。把右值复制（copy）到左值上是常见操作。

C++11标准引入了右值引用数据类型与移动语义，因而左值与右值的定义发生了很大变化。右值引用变量绑定到右值上，延长了右值对应的临时对象的生存期。移动语义把临时对象的内容移动（move）到左值对象上。因而在C++11，对于值的分类，要考虑标识（identity）与可移动性（movability），二者的组合产生了五种分类：
基础值类型
左值lvalue：可以用取地址运算符&获取地址的表达式。也可定义为非临时对象或非成员函数。具有标识，但不可移动。这也是C++03的经典左值。可用于初始化左值引用。可以有不完备类型（incomplete type）。包括：
作用域中的变量名与函数名，不论其类型。因此，具名的右值引用，即具有右值引用类型的变量，也是左值表达式，这符合一般规律，不是特例。
函数调用表达式或重载运算符表达式，如果其返回类型为左值引用或者是到函数类型的右值引用。 
内建的先增（前缀++）、先减（前缀--）、解引用（dereference）、赋值、复合赋值、下标（除了数组临终值）、成员访问（除了临终值的非静态非引用成员、成员枚举值、非静态成员函数），通过数据成员指针的访问且左端操作数为左值、逗号运算符且右端的操作数为左值、三元条件运算符（ternary conditional）且第二与第三操作数为左值。
到左值引用类型的类型转换表达式。
字符串字面量（string literal）
类型转换表达式，转换为到函数的右值引用
临终值xvalue（expiring value）：具有标识，并且可以移动。对应的对象接近生存期结束，但其内容尚未被移走。可以多态；非类对象可以cv限定。包括：
函数调用或重载的运算符表达式，如果返回类型是到对象的右值引用。
类型转换表达式，转换为右值引用，如static_cast<T&&>(val)或(T&&)val
访问xvalue的非静态类成员。
指向数据成员的指针表达式，第一操作数是xvalue
纯右值prvalue：不具有标识，但可以移动。对应临时对象或不对应任何对象的值。纯右值不能是多态的；临时对象的动态类型是表达式类型；非类且非数组的纯右值不能是const限定的；不能有不完备类型（除了void）。包括：
字面量（除了字符串字面量）。
函数调用或重载的运算符表达式，如果返回类型不是引用。
内建后增、后减、算术与逻辑运算符、比较运算符、取地址运算符、访问成员枚举值、访问非静态成员函数、访问右值的非静态非引用数据成员、访问右值的数据成员指针或非静态函数成员指针、逗号运算符且右端操作数为右值、三元条件运算符且第二或第三操作数不是左值。
类型转换表达式，转换为非引用类型。
Lambda表达式
广义左值glvalue：具有标识。包括左值与临终值。可以多态、动态类型。
右值rvalue：可以移动。包括濒死值与纯右值。不能通过&运算符取地址。

C++的非静态成员函数调用表达式（obj.func与ptr->func），非静态成员函数指针调用表达式（obj.*mfp与ptr->*mfp）被当作纯右值，但是不能用于初始化引用，不能做函数实参，仅仅能用作函数调用表达式左边的操作数，如(pobj->*ptr)(args)。

返回void的函数调用表达式、到void的类型转换表达式、throw表达式被当作纯右值。但是不能用于初始化引用，不能做函数实参。可用于某些上下文环境中（如单独作为一行语句、逗号操作符的左端表达式等），或返回void的函数的return语句中。此外，throw表达式可用作三元条件操作符的第二或第三操作数。

位元欄（bit field）表达式是左值，但不能用&运算符取地址，不能绑定到非常量左值引用。常量左值引用可以用位域左值初始化，但实际上是另行分配绑定了一个对象。

汇编语言 
值可以是一个给定的数据类型，例如一个字符串，一个数字，一个单一的字母等几乎任何类型的数据。

有些处理器支持多种尺寸的立即数，例如8位或16位，每一种指令形式采用独特的操作码和助记符。如果一个程序员提供的数据值不适合，汇编器将会出现“超出范围”的错误消息。大多数汇编器允许一个立即数被表示为ASCII，十进制，十六进制，八进制或二进制数据。因此，ASCII字符'A'和65、0x41是一样的。字符串的字节序在不同处理器之间可能不同，取决于汇编器和计算机体系结构。

参考资料

外部链接
Value Object
Transfer Object Pattern 

编程语言概念
電腦數據
类型论