[c++primer][05]表达式

5.1 算术操作符

算术类型具有有限的长度,要注意计算后溢出的现象

求模操作(%)的操作数必须为整型

当两个操作数只有一个为负数时,操作结果的正负取决于机器。

5.2 关系操作符和逻辑操作符

关系、逻辑操作符是使用算术或指针类型的操作数,并返回bool类型的值。

短路求值

&& 和 || 总是在仅靠左操作数无法确定结果时,再计算右操作数。

5.3 位操作符

用于整型和bitset类型

输入输出标准库(IO library)分别重载了位操作符>>和<<用于输入和输出,IO操作符为左结合

5.4 赋值操作符

数组名是不可修改的左值,因此不可用作赋值操作符号的目标。

一个优化的例子

谨防混淆

if(i == 42) 特别容易疏忽而写成 if(i=42),这类错误很难发现,故写作if (42 == i) 为好,可以及时报错

符合赋值操作符

a op= b; op=可以是以下10个操作符

5.5 自增和自减操作符

只有在必要时才使用后置操作符

前置操作只需加1(或减1)后返回结果即可;后置操作则必须先保存操作数原来的值,一遍返回未加1(或减1)之前的值作为操作的结果,对于复杂迭代器类型,这种额外工作可能会花费更大代价。

5.6 箭头操作符

获取所指向的类对象的成员

5.7 条件操作符

避免深度嵌套

==>  

5.8 sizeof操作符

sizeof ( expr )

将sizeof用于expr时,并没有计算表达式expr的值。若sizeof *p,并没有对p做解引用

对指针做sizeof操作返回存放指针所需内存大小;对数组做sizeof操作等效于将对其元素类型做sizeof操作的结果乘上数组元素的个数

5.9 逗号操作符

从左向右计算,返回最右边表达式的值

5.10 复合表达式的求值

优先级:子表达式分组

粗略地,算术>移位>关系>逻辑>条件>赋值

结合性:操作符分组

右结合有,! ~ ++ -- + - * & (类型) sizeof new delete ?: 赋值与复合赋值

求值顺序

除了&&、||、(?:)、(,)规定了计算顺序,其它操作符都未指定操作数的求值顺序。

一个表达式里,不要在两个或更多的子表达式中对同一对象做自增或自减操作。

5.11 new和delete表达式

不提供显式初始化时,动态创建的对象与在函数内定义的变量初始化规则相同。

在类型名后面使用一对空圆括号,对动态创建的对象做值初始化。

对内置类型或没有定义默认构造函数的类型,采用不同初始化式有显著区别

删除0值指针是安全的,但没有任何意义;在delete指针之后,指针变成悬垂指针,应当立即将指针置0。

三种与动态内存分配相关的错误:

1)删除指向动态分配内存的指针失败,无法回收,造成内存泄露;

2)读写已删除的对象。

3)对同一个内存空间使用两次delete表达式。

5.12 类型转换

1、隐式转换

何时发生隐式转换

1)混合类型表达式中,操作数被转换为相同类型

2)用作条件的表达式被转换为 bool类型

3)用表达式初始化某个变量,该表达式转换为该变量类型

算术转换

整型提升:对于所有比int小的整型,包括char、signed char、unsigned char、short和unsigned short,都会被提升为int,否则就会提升为unsigned int

无符号数所定义的转换规则需保护操作数的精度

不将数组名转换为指针的情况:数组名用作取地址操作符的操作数或sizeof操作符的操作数,或数组对数组的引用进行初始化时

2、显式转换(强制类型转换)

cast-name<type> ( expression );  //type为目标类型,expression是被强制转换的值

强制转换的类型指定了在expression上执行某种特定类型的转换。

dynamic_cast

运行时识别指针或引用所指向的对象

const_cast

添加或删除const特性

static_cast

编译器隐式执行的转换或编译器不提供自动转换

reinterpret_cast

为操作数的位模式提供较低层次的重新解释,依赖于机器。

强制类型转换关闭或挂起了正常的类型检查,强烈建议程序员避免使用强制类型转换。

3、旧式强制类型转换

在引入命名的强制类型转换之前,显式强制转换用圆括号将类型括起来实现。

时间: 2024-11-27 04:52:15

[c++primer][05]表达式的相关文章

【足迹C++primer】表达式求值

表达式求值 /** * 功能:表达式求值(0到9) * 时间:2014年6月15日08:02:31 * 作者:cutter_point */ #include<stdlib.h> #include<stack> #include<iostream> #include<string> using namespace std; stack<int> intStack; //存放数值的栈 stack<char> charStack; //存

读书笔记:C++ Primer系列(11)—— 表达式

定义: 表达式(expression)是由一个或多个操作数(operand)通过操作符(operator)组合而成. 1. 操作符--除法(/)和求模(%) 注意: 除法和求模两种运算,操作数都必须是整型,包括:bool.char.short.int和long类型,以及对应的unsigned类型 如果两个操作数为正,除法和求模操作的结果也是正数或为零: 如果两个操作数为负,除法操作的结果为正数或为零,而求模的结果为负数或为零: 如果两个操作数,一个为正一个为负,除法和求模的结果取决于机器:如果求

《C++primer》v5 第4章 表达式 读书笔记 习题答案

4.1 105 4.2 *vec.begin()=*(vec.begin())//先调用点运算符,再解引用 *vec.begin()+1=(*vec.begin())+1//先解引用,再加一 4.3略? 4.4 (12/3*4)+(5*15)+(24%4/2)=91 4.5 (a)-86(b)-16 (c)0 (d)0 4.6 n%2 4.7 溢出:计算结果超出该数据类型所能表示的范围 2147483647+1 1U-2 ... 4.8 比较低.. 4.9 首先判断cp是否为空指针,若非空指针则

委托、Lambda表达式、事件系列05,Action委托与闭包

来看使用Action委托的一个实例: static void Main(string[] args) { int i = 0; Action a = () => i++; a(); a(); Console.WriteLine(i); } 结果是期望能的2.但令人好奇的是:栈上的变量i是如何传递给Action委托的? 反编译进行查看,首先看Main方法对应的IL代码: 再看c_DisplayClass1的IL代码: 从中可以看出:→在托管堆上创建了一个名为c_DisplayClass1的实例→把

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

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

《C++ Primer 4th》读书笔记 第5章-表达式

原创文章,转载请注明出处: http://www.cnblogs.com/DayByDay/p/3912114.html <C++ Primer 4th>读书笔记 第5章-表达式

《C++primer(第五版)》学习之路-第四章:表达式

[ 声明:版权所有,转载请标明出处,请勿用于商业用途.  联系信箱:[email protected]] 4.1 基础 1.表达式由一个或多个运算对象(operand)组成,对表达式求值将得到一个结果(result).字面值和变量是最简单的表达式(expression),其结果就是字面值和变量的值.把一个运算符(operator)和一个或多个运算对象组合起来可以生成较复杂的表达式. 2.C++定义了一元运算符(unary operator)和二元运算符(binary operator).作用于一

【C语言学习】《C Primer Plus》第5章 运算符、表达式和语句

学习总结 1.有了一定的语言基础,运算符和表达式这些都大同小异,无外乎赋值运算符(=).算术运算符(+.-.*./.%.++.--)和其他的一下运算符(sizeof.(type)). 2.声明一个参数就创建了一个被称为形式参数(formal argument)或形式参量(formal parameter).我们称函数调用传递一个值,这个值被称为实际参数(actual argument)或实际参量(actual parameter). 3.编程练习(题8): 1 #include <stdio.h

C++ Primer 学习笔记与思考_9 表达式中过的那些容易忽略的地方

(一)移位操作符用于IO 输入输出标准库分别重载了位操作符>>和<<用于输入和输出.并且像其他的二元操作符一样,移位操作符也是左结合的,这也正好说明了我们为什么可以把多个输入输出操作连接为单个语句: cout<<"hi"<<"there "<<endl; 将其执行为: ( (cout<<"hi")<<"there" )<<endl;