C++学习(第二篇)//最详细C++运算符经验
c++运算符
//少年遥想得山田,请赶在日落下山前。
定义:运算符是一种告诉编译器执行特定的数学或逻辑操作的符号,C++ 内置了丰富的运算符。
目录
基础知识
- 基本概念
- 组合运算符和运算对象
- 重载运算符
- 左值和右值
- 求值顺序,优先级,结合律
算数运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
条件运算符
sizeof运算符
成员访问运算符
逗号运算符
类型转换
运算符的优先级
1.基础知识
1.1基本概念:
- C++定义了单目运算符,双目运算符和三目运算符,作用于一个运算对象的叫单目运算符,例如:解引用(*)和去地址符(&),以此类推。函数调用也是一种特殊的运算符,它对对象的数量没有什么要求。
- 有些符号既能做单目运算符也能做双目运算符,例如 * 作为单目运算符执行解引用操作,作为双目运算符执行乘法运算操作。对于这种符号,两种操作毫不相干,完全可以当做两个不同的符号。
1.2组合运算符和运算对象
- 对于含有多个运算符的表达式,要明白它的含义,首先要学习运算符优先级,结合律以及运算对象的求值顺序。
1.3重载运算符
- c++语言定义了运算符作用于内置类型和复合类型的运算对象,当运算符作用于类类型的运算对象时,用户可以自行定义其含义,用为这种自定义过程事实上是为已存在的运算符赋予另外一层含义,所以称为重载运算符。IO库的>>和<<就是重载运算符.
1.4左值和右值
- C++的表达式要么是左值要么是右值.例:左值可以位于赋值语句的左侧,右值则不可以。归纳:当一个对象被用做右值,用的是对象的值(内容),当对象被用于左值得时候,用的是对象的身份(在内存中的位置);
- 不同的运算符对运算对象的要求各不相同,有的需要左值运算对象,有的则需要右值运算对象,返回值也各有差异。一个重要的原则是:在需要右值的时候可以用左值来替代,但是不能把右值当做左值(也就是位置)使用,实际使用的是他的内容(值)。
1.5求值顺序,优先级,结合律
1.5.1复合表达式
- 复合表达式是指含有两个或者多个运算符的表达式,求解复合表达式首先要把运算符和运算对象合理的组合起来,优先级和结合律决定了运算对象的组合方式,有括号的表达式可以忽略上述规则。
- 一般来说表达式最终的值依赖于其子表达式的组合方式,高优先级运算符的运算对象要比低优先级运算符的运算对象更紧密的组合在一起。如果优先级相同,则组合方式由结合律决定。例如乘法除法运算符的优先级高于加法减法,所以乘除法运算符的运算符的运算对象先组合再考虑加减法的运算对象,算术运算遵循左结合律,优先级相同时从左到右运算。
- 例如:2+3*4表达式的值是14而不是20。
- 例如:5-3-1表达式的值是1而不是3。
1.5.2括号无视优先级和结合律
- 括号无视其他的普通结合方式,先计算括号内的子表达式,然后在与其他子表达式按照优先级组合。
1.5.3优先级和结合律的影响
- 优先级会影响程序的正确性。
- 例如:
#include<iostream>
using namespace std;int main()
{int arr[] = { 0,2,4,6,8 };//含有五个整数的数组int last = *(arr + 4);//把last初始化为8last = *arr + 4;//last=4,等价于arr[0]+4return 0;
}
- 结合律对程序的影响的例子是输入输出运算:(输入输入运算符是重载运算符)
#include<iostream>
using namespace std;int main()
{int v1, v2;cin >> v1 >> v2;//先读入v1再读入v2return 0;
}
1.5.4求值顺序
- 优先级规定了运算对象的组合方式,但是没有说明运算对象按照什么顺序求值。
- 在大多数情况下,不会明确的指定求值顺序。
- 例如
int a=f1()+f2()
,我们知道调用函数要在乘法运算之前,但是我们不知道两个函数哪一个先调用。 - 如果表达式指向并且修改同一个对象,即一个子表达式改变了某个对象的值,另一个子表达式又要调用该值得话,就会引发错误并产生未定义的行为。
- 例如
int i = 1; cout << i << " " << i++ << endl;//未定义的
有四种运算符规定了求值顺序,分别是:逻辑或运算符,逻辑与运算符,条件运算符(三目运算符)和逗号运算符。
在调用函数的时候,如果函数是无关函数,既不改变同一对象的状态也不执行IO操作,则函数的调用顺序不受限制,反之,它就是一条错误的表达式,产生未定义的行为。
1.算术运算符
概念:进行加减乘除等的算术运算,满足左结合律。
- 加法运算符(+)
- 减法运算符(-)
- 乘法运算符(*)
- 除法运算符(/)
- 取模运算符(%)
- 自增运算符(++)
- 自减运算符(–).
2.关系运算符
概念:关系运算符比较运算对象的大小并且返回布尔值。
- 相等运算符(==)
- 不等于运算符(!=)
- 大于运算符(>)
- 小于运算符(<)
- 大于等于运算符(>=)
- 小于等于运算符(<=)
关系运算符的计算结果一般是布尔值(真或假)。
3.逻辑运算符
- 逻辑与运算符(&&)
- 逻辑或运算符(||)
注:短路求值:当且仅当左侧左侧运算对象无法确定表达式的结果时才计算右侧运算对象的值。
- 逻辑非运算符(!)
4.位运算符
- 位运算符作用于整数运算对象,并把运算对象看成是二进制位的集合。位运算符提供检查和设置二进制位的功能。
1.~ 位求反
2.<< 左移
3.>> 右移
4.& 位与
5.^ 位异或
6.|位或
5.赋值运算符
- 赋值运算符的左侧必须是一个可修改的左值。
- 赋值运算符满足右结合律。
- 赋值运算符的优先级比较低。
- 不要混淆相等运算符和赋值运算符。
- 复合赋值运算符,例:a+=3等价于a=a+3;
6.条件运算符
- 条件运算符(? :)允许我们把简单的if-else逻辑嵌入到单个的表达式中
- 条件运算符可以嵌套使用
- 条件运算符可以在输出表达式中使用。
7.sizeof运算符
- sizeof运算符返回一个表达式或者一个类型的名字所占的字节数。满足右结合律,其所得到的值是一个size_t类型的常量表达式。
- 运算符的运算对象有两种形式
sizeof(type);sizeof(expr);
在第二个形式中计算表达式结果类型的大小,与众不同的是sizeof并不实际计算其运算对象的值。
- 指针中,sizeof不用真正解引用指针也能知道所指向对象的类型。
例:sizeof *p
首先,因为sizeof满足右结合律并且与*优先级相同,所以表达式按照从右向左的顺序组合,等价于sizeof(*p);
,其次因为sizeof不会实际求运算对象的值,所以即使是一个无效的(未初始化)指针也不会有什么影响。 - sizeof运算符的结果部分的依赖于其作用的类型:
例如:对于char或者类型为char的表达式执行sizeof运算结果为1。
8.成员访问运算符
- 点运算符和箭头运算符都可以访问成员,箭头运算符和点运算符有关。
- 例如:
ptr->men
和(*ptr).men
等效。
string s1 = "hello world";string *p = &s1;auto n = s1.size();//运行string对象s1的size成员n = (*p).size();//运行p所指向的对象的size成员n = p->size();//等价于上一行代码
9.逗号运算符
- 含有两个运算对象,按照从左到右的顺序依次计算。
- 首先对左侧表达式求值,然后将求值结果丢弃,逗号运算符的结果是右侧表达式的值,如果右侧运算对象是左值,那么最终的求值结果也是左值。
10.类型转换
注: 在C++中,如果两种类型有关联,那么当程序需要其中一种类型的运算对象时,可以用另一种关联类型的对象或者值来替代,意思是说,如果两种类型可以相互转换,那么它们就是关联的。
1.例如:
int a = 3.14 + 3;
此时加法的两个运算对象类型不同,C++不会将两个不同类型的数值相加,而是先根据类型转换规则设法将运算对象的类型统一后再求值,上述类型转换是自动执行的,所以叫做隐式转换。2.例如:
int a = 3.14 + 3;
此时加法的两个运算对象类型不同,C++不会将两个不同类型的数值相加,而是先根据类型转换规则设法将运算对象的类型统一后再求值,上述类型转换是自动执行的,所以叫做隐式转换。算数转换:把一种算数类型转换成另外一种算数类型。算数转换规则定义了一套类型转换的层次,其中运算符的运算对象将转换成最宽的类型。
显式转化:有时候我们希望显式的将运算对象强制转换为另一种类型
例:以下方法叫做强制类型转换
#include<iostream>
using namespace std;int main()
{int i, j;double a = i / j;//使用某种方法将i和/或j转换成double类型return 0;
}
11.运算符的优先级
定义:运算符的优先级指的是计算机运算的先后顺序,学习完具体的运算符及其使用方法,然后就应该学习运算符优先级,循序渐进。
以下是具体的运算符优先级表格:
注:虽然表格内容较多,但是只要在学习中不断接触到运算符优先级,你就会掌握的很厉害!
C++学习(第二篇)//最详细C++运算符经验相关推荐
- Elasticsearch学习第二篇--常用的几种搜索方式
Elasticsearch学习第二篇--常用的几种搜索方式 一.Query String Search 查询全部 条件查询 二.Query DSL 查询全部 条件查询 三.Query Filter 四 ...
- TLS协议学习-第二篇-握手协议
TLS协议学习第二篇,内容来自:https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-200 ...
- Android基础学习第二篇—Activity
写在前面的话: 1. 最近在自学Android,也是边看书边写一些Demo,由于知识点越来越多,脑子越来越记不清楚,所以打算写成读书笔记,供以后查看,也算是把自己学到所理解的东西写出来,献丑,如有不对 ...
- 网络安全学习第二篇【IP地址详解】
一.IP详解 局域网 局域网一般被称为内网,通常由交换机,网线和PC组成.交换机是组建内网的关键设备 IP地址 IP地址(Internet Protocol Address)是指互联网协议地址,又译为 ...
- JNI与NDK学习第二篇-----应用篇
2019独角兽企业重金招聘Python工程师标准>>> 1.安装配置NDK 1). 解压NDK的zip包到非中文目录(最好英文目录不要带空格) 2). 配置path : 解压 ...
- UI学习第二篇 (控件)
UIbutton 也是一个控件,它属于UIControl 用的最多的就是事件响应 1. //创建按钮对象 UIButton * _botton = [UIButton buttonWithType:U ...
- python学习[第二篇] 基础二
控制结构 if 语句 # only if blockif condition:if_true_block# if_else blockif condition:if_true_block else:i ...
- 【Vue】快乐学习第二篇
文章目录 前言 ♥️ 计算属性 computed
- scala学习第二篇之面向对象
一.类的基本操作 1.类的创建与对象的构造 定义scala中的类使用关键字class 1.定义scala中的任意一种结构,都不可以使用public关键字修饰,因为scala中没有public关键字不加 ...
最新文章
- Nature Plants:根系微生物可以远程提高植物应对地上部环境胁迫的能力
- Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题
- 加速静态内容访问速度的CDN
- phpmyadmin的安装部署
- getchar()到底怎么用_怎样才能真正发挥肥效,腐植酸水溶肥到底怎么用
- eclipselink_EclipseLink JPA-RS简介
- hp服务器raid一直显示同步,HP Netserver NetRAID 一致性检查常见问题解答(FAQ)
- django访问mysql数据库--模型(model)
- 替换过的mysql能找回来_MySQL 误操作后数据恢复(update,delete忘加where条件)
- Linux:CPU使用率100%排查方法
- 橡胶柱压缩_橡胶=汽车半条命:浅谈ABAQUS橡胶大变形仿真5大注意事项
- 利用HTML和浏览器16倍速刷网课
- 根据身份证号码计算年龄
- 解决虚拟机桥接模式ping不通主机
- 图像 去掉文字 python_opencv-python 去除图片文字
- 执行脚本错误:-bash: ./start.sh: /bin/bash^M: bad interpreter: No such file or directory
- js date日期格式化
- 如何把地址导航生成二维码?
- Git本地文件上传到远程仓库
- 【Java代码】MP3、flac歌曲批量生成同名的“xxx.lrc”歌词文件导入索尼黑砖二代