C++ Primer 第四章 表达式

基础

运算符根据运算对象的个数分为一元、二元、三元运算符,相同的符号可能表示不同的运算符,具体符号的含义根据上下文决定。一般运算对象可以自动转换为运算符所需的类型。根据运算对象的不同运算符可以表示不同的含义,称为运算符的重载。

左值表示能放在赋值运算符的左侧,右值则不能。当一个对象被用作右值时,用的是对象的内容,当一个对象被用作左值时,用的是对象的身份(内存位置)。某些运算符必须要求运算对象为左值,左值可以当成右值使用。

运算符拥有不同的优先级和结合律,括号拥有最高的优先级。

大部分运算符没有规定求值顺序,即运算符的多个运算数哪个先求值,如果表达式修改了同一个对象,将会引发未定义的错误行为。如:

int i = 0;
    cout << i << " " << ++i << endl;

这种情况是错误的,因为无法确定编译器先求i还是先求++i,返回的结果也是不确定的。有4种运算符明确规定了运算对象的求值顺序,&&, ||, ?:, 逗号运算符。

运算对象的求值顺序与优先级和结合律无关。

算数运算符

算数运算符的运算对象和求值结果都是右值,参与取余运算的运算对象必须是整数。

逻辑和关系运算符

值为0的运算对象表示假,否则表示真,对于这两类运算符,运算对象和求值结果都为右值。

赋值运算符

左侧必须是一个可修改的左值,运算结果为左侧对象,并且也是左值。赋值运算符满足右结合律,赋值运算符的优先级较低。使用复合赋值运算符时左侧的运算对象只求值一次,对性能有些许提升。

递增和递减运算符

分为前置版本和后置版本,前置版本将对象本身作为左值返回,后置版本将对象原始值的副本作为右值返回。除非必须,建议一直使用前置版本。

*pBegin++,这种写法是合适的,先对指针进行解引用操作,然后在对指针递增。

特别注意,运算对象可按任意顺序求值,*beg=toupper(*beg++),该条语句是错误的,将产生为定义的值,因为等号左侧和右侧的求值顺序是不确定的,如果左侧先求值,语句等价于*beg=toupper(*beg),如果右侧先求值,语句等价于*(beg+1)=toupper(*beg)。

成员访问运算符

点运算符用于访问对象的成员,如果对象是左值,则点运算符返回左值,如果对象是右值,则点运算符返回右值。箭头运算符作用于指针类型的对象,结果是一个左值。obj.member等价于(*pObj).member。

条件运算符

条件运算符只对两个表达式中的一个表达式求值。条件运算符的两个表达式都是左值或能转换成同一类型的左值时运算结果是左值,否则为右值。

条件运算符的优先级很低,因此使用时最好加括号,如cout<<(grade<60)?"fail":"pass";无法达到预想的结果,因为会把问好前面当做条件。

位运算符

位运算符作用于整数的运算对象,提供设置和检查二进制位的功能。位运算对于符号位的处理没有明确的规定,因此建议将位运算只用于无符号数。

左移位在右侧插入值为0的二进制,右移位根据左侧运算对象的不同插入的值不同,如果左侧为无符号整数,则插入0,如果为有符号整数,插入0或插入1具体由环境而定。

注意移位运算符将左侧对象的拷贝作为求值结果,移位过程可能会提升运算对象。

位求反运算符(~)把运算对象逐位求反,char类型的运算对象首先转换成int类型,然后求反。

位与、位或、位异或在两个运算对象上逐位执行相应的逻辑操作。

移位运算符满足左结合律。重载运算符的优先级与结合律都与它的内置版本一样。

sizeof运算符

返回一条表达式或类型名字所占的字节数,满足右结合律,其所得的值是一个类型为size_t的常量表达式。运算符使用的两种形式sizeof(type)或sizeof expr,返回表达式计算结果的大小,并不计算表达式。对引用类型执行sizeof得到被引用类型对象的大小,对数组执行sizeof得到整个数组所占空间大小。

逗号运算符

含有两个运算对象,按照从左向右的顺序依次求值,与三元运算符,逻辑与逻辑或运算符一样规定运算数的求值顺序。逗号运算符返回右侧表达式的值,如果右侧表达式为左值,则运算结果为左值。

类型转换

算数类型之间可以进行隐式类型转换,并且设计的尽量不损失精度。

无符号类型与带符号类型参与运算时,如果无符号类型不小于带符号类型,则带符号类型转换成无符号类型,这会产生副作用。如果无符号类型得所有值都能存储在带符号类型中,则无符号类型转换成带符号类型,否则带符号类型转换成无符号类型。

在大多数用到数组的表达式中,数组自动转换成指向第一个元素的指针。

字面值0和nullptr能转换成任意类型的指针。

如果指针或算数类型为0,则转换成false,否则转换成true。

指向非常量的指针或引用能转换成指向常量的指针或引用。

避免使用强制类型转换。

时间: 2024-08-07 08:18:04

C++ Primer 第四章 表达式的相关文章

《C++ Primer》读书笔记—第四章 表达式

声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程 1.表达式由一个或多个运算对象组成,对表达式求值将得到一个结果.字面值和变量是最简单的表达式,其结果就是字面值和变量的值.把一个运算符和一个或多个运算对象组合起来可以生成复杂的表达式. 2.指针不能转换成浮点数. 3.一个左值表达式的求职结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象. 4.在除法运算中,如果两个运

C++primer第四章 数组和指针

4.1. 数组 数组是由类型名.标识符和维数组成的复合数据类型(第 2.5 节),类型名规定了存放在数组中的元素的类型,而维数则指定数组中包含的元素个数. 数组定义中的类型名可以是内置数据类型或类类型:除引用之外,数组元素的类型还可以是任意的复合类型.没有所有元素都是引用的数组. 4.1.1. 数组的定义和初始化 数组的维数必须用值大于等于 1 的常量表达式定义(第 2.7 节). 此常量表达式只能包含整型字面值常量.枚举常量(第 2.7 节)或者用常量表达式初始化的整型 const 对象. /

C++Primer 第四章

//1.当我们对运算符进行重载的时候,其包括运算对象的类型和返回值的类型都是由该运算符定义的,但是运算对象的个数和优先级,结合律都是不能改变的 //2.当一个对象被用作右值的时候,用的是对象的值(内容).当对象被用作左值的时候,用的是对象的身份(在内存中的位置). //3.复合表达式:是指含有两个或多个运算符的表达式.求复合表达式的值需要首先将运算符和运算对象合理的组合在一起.优先级和结合律决定了运算对象的组合方式. // 括号无视普通的组合规则,在表达式中括号括起来的部分被当做一个单元来求值,

C++primer第五章 表达式

表达式由一个或多个操作数通过操作符组合而成.最简单的表达式仅包含一个字面值常量或变量.较复杂的表达式则由操作符以及一个或多个操作数构成. 每个表达式都会产生一个结果. 5.1. 算术操作符 表 5.1 按优先级来对操作符进行分组——一元操作符优先级最高,其次是乘.除操作,接着是二元的加.减法操作. 算术操作符 +.-.* 和 / 具有直观的含义:加法.减法.乘法和除法.对两个整数做除法,结果仍为整数,如果它的商包含小数部分,则小数部分会被截除: int ival1 = 21/6; // inte

javascript权威指南第四章表达式与运算符

表达式:包括常量,变量,数组访问表达式 data = [1, 2, 3]. 运算符是将简单表达式组成复杂表达式的常用方法. 原始表达式:常量或直接量,关键字和变量. 对象,数组的初始化表达式实际就是新创建的对象和数组,这些初始化表达式有时也叫”对象(数组)直接量“,数组初始化表达式中的元素初始化表达式也可以是数组初始化表达式(也就是嵌套)例子: var matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];数组直接量中元素可省略 即:var sparseArray

c++primer 第四章编程练习答案

4.13.1 #include<iostream> struct students { char firstname[20]; char lastname[20]; char grade; int age; }; int main() { using namespace std; students student1; cout << "What is your fistname? "; cin.get(student1.firstname, 20).get();

C++ Primer第四章课后编程题

1. 代码 #include<iostream> #include<string> int main() { using namespace std; string name; string lname; char grade; int age; cout << "What is your first name?"; getline(cin, name); cout << "What is your last name?&quo

C Primer Plus (第四章总结)

1.定义字符串可以直接在头文件下定义,如: #include <stdio.h> #define hello  "hello world!" 2.sizeof() 和 strlen() sizeof运算符是以字节为单位给出数据的大小,strlen()是以字符为单位给出长度. <string.h>包含许多与字符串相关的函数的原型,包括strlen() sizeof运算符提供的数据比肉眼直观的要大多一位,因为他把用来标志字符串的不可见的空字符也计算在内. 定义常量最

C++ Primer Plus学习:第四章

C++入门第四章:复合类型 1 数组 数组(array)是一种数据格式,能够存储多个同类型的值. 使用数组前,首先要声明.声明包括三个方面: 存储每个元素中值的类型 数组名 数组中的元素个数 声明的通用风格如下: typename arrayname[arrysize]; 注;arrysize指定元素数目,必须是整型常量,不能是变量. 数组的很多用途均基于这样一个事实:可以单独访问数组元素.方法是使用下表或索引对元素进行编号.C++数组从0开始编号,并使用带索引的方括号表示法来指定数组元素. 注