设为首页 加入收藏

TOP

4.1.1 基本概念
2013-10-07 16:27:59 来源: 作者: 【 】 浏览:103
Tags:4.1.1 基本 概念

4.1.1  基本概念

C++(www.cppentry.com)定义了一元运算符(unary operator)和二元运算符(binary operator)。作用于一个运算对象的运算符是一元运算符,如取地址符(&)和解引用符(*);作用于两个运算对象的运算符是二元运算符,如相等运算符(==)和乘法运算符(*)。除此之外,还有一个作用于三个运算对象的三元运算符。函数调用也是一种特殊的运算符,它对运算对象的数量没有限制。

一些符号既能作为一元运算符也能作为二元运算符。以符号*为例,作为一元运算符时执行解引用操作,作为二元运算符时执行乘法操作。一个符号到底是一元运算符还是二元运算符由它的上下文决定。对于这类符号来说,它的两种用法互不相干,完全可以当成两个不同的符号。

组合运算符和运算对象

对于含有多个运算符的复杂表达式来说,要想理解它的含义首先要理解运算符的优先级(precedence)、结合律(associativity)以及运算对象的求值顺序(order of eva luation)。例如,下面这条表达式的求值结果依赖于表达式中运算符和运算对象的组合方式:

  1. 5 + 10 * 20/2; 

乘法运算符(*)是一个二元运算符,它的运算对象有4种可能:10和20、10和20/2、15和20、15和20/2。下一节将介绍如何理解这样一条表达式。

运算对象转换

在表达式求值的过程中,运算对象常常由一种类型转换成另外一种类型。例如,尽管一般的二元运算符都要求两个运算对象的类型相同,但是很多时候即使运算对象的类型不相同也没有关系,只要它们能被转换(参见2.1.2节,第35页)成同一种类型即可。

类型转换的规则虽然有点复杂,但大多数都合乎情理、容易理解。例如,整数能转换成浮点数,浮点数也能转换成整数,但是指针不能转换成浮点数。让人稍微有点意外的是,小整数类型(如bool、char、short等)通常会被提升(promoted)成较大的整数类型,主要是int。4.11节(第159页)将详细介绍类型转换的细节。

重载运算符

C++(www.cppentry.com)语言定义了运算符作用于内置类型和复合类型的运算对象时所执行的操作。当运算符作用于类类型的运算对象时,用户可以自行定义其含义。因为这种自定义的过程事实上是为已存在的运算符赋予了另外一层含义,所以称之为重载运算符(overloaded operator)。IO库的>>和<<运算符以及string对象、vector对象和迭代器使用的运算符都是重载的运算符。

我们使用重载运算符时,其含义,包括运算对象的类型和返回值的类型,都是由该运算符定义的;但是运算对象的个数、运算符的优先级和结合律都是无法改变的。

左值和右值

C++(www.cppentry.com)的表达式要不然是右值(rvalue,读作"are-value"),要不然就是左值(lvalue,读作"ell-value")。这两个名词是从C语言继承过来的,原本是为了帮助记忆:左值可以位于赋值语句的左侧,右值则不能。

在C++(www.cppentry.com)语言中,二者的区别就没那么简单了。一个左值表达式的求值结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象。此外,虽然某些表达式的求值结果是对象,但它们是右值而非左值。可以做一个简单的归纳:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。

不同的运算符对运算对象的要求各不相同,有的需要左值运算对象、有的需要右值运算对象;返回值也有差异,有的得到左值结果、有的得到右值结果。一个重要的原则(参见13.6节,第531页将介绍一种例外的情况)是在需要右值的地方可以用左值来代替,但是不能把右值当成左值(也就是位置)使用。当一个左值被当成右值使用时,实际使用的是它的内容(值)。到目前为止,已经有几种我们熟悉的运算符是要用到左值的。

赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。

取地址符(参见2.3.2节,第52页)作用于一个左值运算对象,返回一个指向该运算对象的指针,这个指针是一个右值。

内置解引用运算符、下标运算符(参见2.3.2节,第53页和参见3.5.2节,第116页)、迭代器解引用运算符、string和vector的下标运算符(参见3.4.1节,第106页;参见3.2.3节,第93页;参见3.3.3节,第102页)的求值结果都是左值。

内置类型和迭代器的递增递减运算符(参见1.4.1节,第12页和参见3.4.1节,第107页)作用于左值运算对象,其前置版本(本书之前章节所用的形式)所得的结果也是左值。

接下来在介绍运算符的时候,我们将会注明该运算符的运算对象是否必须是左值以及其求值结果是否是左值。

使用关键字decltype(参见2.5.3节,第70页)的时候,左值和右值也有所不同。如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型。举个例子,假定p的类型是int*,因为解引用运算符生成左值,所以decltype(*p)的结果是int&。另一方面,因为取地址运算符生成右值,所以decltype(&p)的结果是int**,也就是说,结果是一个指向整型指针的指针。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇3.6 多维数组(3) 下一篇4.1.2 优先级与结合律

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Sphinx : 高性能SQL (2025-12-24 10:18:11)
·Pandas 性能优化 - (2025-12-24 10:18:08)
·MySQL 索引 - 菜鸟教 (2025-12-24 10:18:06)
·Shell 基本运算符 - (2025-12-24 09:52:56)
·Shell 函数 | 菜鸟教 (2025-12-24 09:52:54)