第四课 C++中的运算符


我们知道,运算符是进行运算实现数据处理的符号。C++内置了丰富的运算符,大致
可以分为以下几种类型:
算术运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
其它运算符
下面逐一介绍。
一、算术运算符及功能
1. C++算术运算符功能列表
下表列了了 C++支持的算术运算符。
假设变量 A 的值为 10,变量 B 的值为 18,则:
运算符 功能描述 实例
+ 求两数的和 A+B 值为 28
- 求两数的差 A-B 值为-8
* 求两数的积 A*B 值为 180
/
求商。若被除数和除数都是整数,则结果
为整数商;若两运算数有一个或两个都是
实数,则结果为一个实数。
B/A 值为 0
10.0/18 值为 0.555556
% 取模运算符,求两个整数相除后的余数 B%A 值为 8
++ 自增运算符(单目),整型变量值增加 1
A++值为 10,A 变为 11
++A 值为 11,A 变为 11
-- 自减运算符(单目),整型变量值减少 1
A--值为 10,A 变为 9
--A 值为 9,A 变为 9
2. 示例
下面的程序演示了算术运算符“/”、“%”、“++”、“--”的功能。
#include <iostream>
using namespace std;
int main(){
int a = 21,b = 18;
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 30
int c,d ;
c=a/b;
d=a%b;
cout<<a<<"/"<<b<<"="<<c<<"......"<<d<<endl;
c=a++;
d=++b;
cout<<"a="<<a<<" b="<<b<<endl;
cout<<"c="<<c<<" d="<<d<<endl;
float x,y,z;
x=21.0; y=18.0;
z=x/y;
cout<<"x/y="<<z<<endl;
return 0;
}
当上面的代码被编译和执行时,有下列输出:
21/18=1......3
a=22 b=19
c=21 d=19
x/y=1.16667
3. 算术运算符之间的相对优先级
1) 优先级
从高到低依次为:(++、--) -> (*、/、%)-> (+、-)
2) 结合律
除自增/自减运算外,同级运算均为“自左而右”结合。
二、*关系运算符
1. C++关系运算符功能列表
下表列出了 C++支持的关系运算符。
假设变量 A 的值为 10,变量 B 的值为 18,则:
运算符 功能描述 实例
== 判断两个操作数的值是否相等,如果相等则结果为
真 true(1),否则为假 false(0)。
(A==B)为假
!= 判断两个操作数的值是否不相等,如果不等则结果
为真 true(1),否则为假 false(0)。
(A!=B)为真
> 判断左操作数的值是否大于右操作数的值,如果是 (A>B)为假
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 31
运算符 功能描述 实例
则结果为真 true(1),否则为假 false(0)。
<
判断左操作数的值是否小于右操作数的值,如果是
则结果为真 true(1),否则为假 false(0)。
(A<B)为真
>= 判断左操作数的值是否大于或等于右操作数的值,
如果是则结果为真 true(1),否则为假 false(0)。
(A>=B)为假
<= 判断左操作数的值是否小于或等于右操作数的值,
如果是则结果为真 true(1),否则为假 false(0)。
(A<=B)为真
2. 示例
下面的程序演示了部分关系运算符的功能。
#include <iostream>
using namespace std;
main(){
int a,b,c;
cin>>a>>b;
if(a==b)cout<<"a is equal to b.";
else if(a>b) cout<<"a is bigger than b.";
else cout<<"a is smaller than b.";
c=a==b;
cout<<endl<<c<<endl;
return 0;
}
程序执行后,
输入 1:
6 6,
输出 1:
a is equal to b. 1
输入 2:
5 6
输出 2:
a is smaller than b. 0
其中的 if 语句是条件控制语句,见后面第六课“条件语句”。
3. 关系运算符之间的相对优先级
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 32
1) 优先级
>、>=、<、<= 四运算符优先级相同,较高;==、!= 两运算符优先级相同,较低。
2) 结合律
同级运算,均自左而右。
三、*逻辑运算符
1. 逻辑运算符功能列表
下表列出了 C++支持的关系逻辑运算符。
假设变量 A 的值为 10,变量 B 的值为 0,则:
运算符 描述 实例
&& “逻辑与”运算符。如果两个操作数都非零(都为真),
则结果为真。
A&&B 为假。
|| “逻辑或”运算符。如果两个操作数中有任意一个非
零(至少 1 个为真),则结果为真。
A||B 为真。
! “逻辑非”运算符。如果操作数为真(非零)则结果
为假(零);如果操作数为假(零)则结果为真。
!(A&&B)为真。
2. 实例
下列程序列举了 C++三种逻辑运算符的功能。
#include <iostream>
using namespace std;
int main(){
int a = 5;
int b = 20;
int c = 0,d = 0;
cout<<(a&&b)<<" "<<(a&&c)<<" "<<(a||c)<<" "<<(d||c)<<endl;
cout<<(a>b&&a>c)<<" "<<(a>b||a>c)<<endl;
cout<<!(c)<<" "<<!(a<b)<<endl;
return 0;
}
程序运行结果为:
1 0 1 0
0 1
1 0
说明:C++中,数据作为逻辑运算的运算对象,非零表示真(程序中的 a 和 b),零表
示假(程序中的 c 和 d)。
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 33
再看一例:
#include <iostream>
using namespace std;
int main(){
int a=56;
bool f;
f=a;
cout<<"a="<<a<<",f="<<f<<endl;
return 0;
}
该程序运行结果:
a=56,f=1
3. 逻辑运算符之间的相对优先级与结合性
1) 优先级
从高到低依次为 !-> && -> ||
2) 结合律
同级运算,自左而右。
四、*位运算符
位运算的运算对象是整型数据(包括字符)。运算对象按其二进制形式的“位”进行
相应的逻辑运算,有位与(&)、位或(|)、位异或(^)、左移位(<<)、右移位(>>)、
还包括单目运算位非(~)。
1. 位运算的含义
设 p、q 是两个二进制位(非 0 即 1),则有:
p q p&q p|q p^q ~p
0 0 0 0 0 1
0 1 0 1 1 1
1 0 0 1 1 0
1 1 1 1 0 0
从表中可以看出:
1)位与、位或、位非与逻辑运算:与、或、非对应,只不过它们是在运算对象的二进
制形式的相应位之间进行的运算。
2)位异或,两运算位相同,则结果为 0;两运算位相异,则结果为 1。
假设 A=60,B=13,它们的二进制形式(这里以 8 位二进制数为例)分别为:
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 34
A = 00111100,B = 00001101
则有:
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001 ~A=11000010
2. 位运算符及其功能
下表列出了 C++支持的位运算符(假设变量 A 的值为 60,变量 B 的值为 13,它们的
二进制形式分别为:00111100,00001101)
运算符 描述 实例
& 如果两操作数对应位都是 1,则结果相
应位为 1,否则结果相应位为 0。
(A&B)值为 12(二进制形式
为 00001100)
| 如果两操作数对应位都是 0,则结果相
应位为 0,否则结果相应位为 1。
(A|B)值 61(二进制形式为
00111101)
^ 如果两操作数对应位相同,则结果相应
位为 0,否则结果相应位为 1。。
(A^B)值 49(二进制形式为
00110001)
~ 单目运算符,对运算数的各位取反(0
变成 1,1 变成 0)。
(~A)值为-61(二进制形式
为 11000011
<<
二进制左移位运算符。左操作数的值向
左移动右操作数指定的位数。
A<<2 值为 240(二进制形
式为 11110000
>>
二进制右移位运算符。左操作数的值向
右移动右操作数指定的位数。
A>>2 将得到 15(二进制形
式为 00001111
注:
1)左移一位,高位自然丢失,个位补零;右移一位,个位自然丢失,若是无符号数,
高位补零,若是有符号数,补原高位(即原高位为 0 则补 0,原高位为 1 则补 1)。
2)对无符号数而言,左移就是将第一个操作数扩大 2 倍(前提是:没有超过对应类型
数据表示范围);右移一位就是将第一个操作数缩小 2 倍。
位运算比较复杂些,结果与运算数是有符号数还是无符号数及运算数的位数有关,实
际使用时要加以留意。
3. 示例
请看下面的例子:
#include <iostream>
using namespace std;
int main(){//这里以 32 位有符号整数为例
int a = 60; // 60 = (0000 0000 0011 1100)2
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 35
int b = 13; // 13 = (0000 0000 0000 1101)2
int c = 0;
c = a & b; // 12 = (0000 0000 0000 1100)2
cout << "a&b = " << c << endl ;
c = a | b; // 61 = (0000 0000 0011 1101)2
cout << "a|b = " << c << endl ;
c = a ^ b; // 49 = (0000 0000 0011 0001)2
cout << "a^b = " << c << endl ;
c = ~a; // -61 = (1111 1111 1100 0011)2
cout << "~a = " << c << endl ;
c = a << 2; // 240 = (0000 0000 1111 0000)2
cout << "a<<2 = " << c << endl ;
c = a >> 2; // 15 = (0000 0000 0000 1111)2
cout << "a>>2 = " << c << endl ;
return 0;
}
编译执行上面的程序,显示以下结果:
a&b = 12
a|b = 61
a^b = 49 ~a = -61
a<<2 = 240
a>>2 = 15
4. 位运算符之间的优先级与结合性
1) 优先级
从高到低依次为 位非~ -> 位与& -> 位异或^ -> 位或|
2) 结合性
位非运算“自右而左”,其它位运算为“从左而右”。
五、赋值运算符
我们在前面已讲过变量的赋值。实际上,C++中赋值也是一种运算,在赋值表达式后
加上分号就是一个赋值语句。如:
a=5*3
就是一个赋值表达式,该式的值就是赋值号左边变量 a 所赋得的值 15。
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 36
既然 a=5*3 是一个表达式,那么我们就可以将它的值再赋给另一个变量,所以下式是
正确的表达式:
c=b=a=5*3
结果变量 a,b,c 都被赋值 15。
1. C++的赋值运算符一览
以整型变量的赋值为例,设整型变量 a,b 的初值分别为 3 和 5:
运算符 描述 实例
= 普通赋值运算符,把右边操作数的值赋
给左边变量
c=a+b,c 赋得 8(也是该赋值
表达式的值)
+= 累加赋值运算符,把右边操作数加上左
边操作数的结果赋值给左边变量。
a+=b,a 赋得 8(该赋值表达式
值也为 8)
-= 扣减赋值运算符,把左边操作数减去右
边操作数的结果赋值给左边变量
a-=b,a 赋得-2(该赋值表达式
值也为-2)
*= 累乘赋值运算符,把右边操作数乘以左
边操作数的结果赋值给左边变量。
a*=b-1,a 赋得 12(该赋值表达
式值也为 12)
/= 除且赋值运算符,把左边操作数除以右
边操作数的结果赋值给左边变量。
a/=b-1,a 赋得 0(该赋值表达
式值也为 0)
%= 求模赋值运算符,把左边操作数除以右
边操作数的余数赋值给左边变量。
a%=b-3,a 赋得 1(该赋值表达
式值也为 1)
<<= 左移赋值运算符,将左边操作数左移右
操作数位,并把结果赋值给左边变量。
a<<2,a 赋得 12(该赋值表达
式值也为 12)。
>>= 右移赋值运算符,将左边操作数右移右
操作数位,并把结果赋值给左边变量。
a>>2,a 赋得 0(该赋值表达式
值也为 0)
&= 位与且赋值运算符,将左边操作数与右
边操作数位与,结果赋值给左边变量。
a&=4,a 赋得 0(该赋值表达式
值也为 0)
|= 位或且赋值运算符,将左操作数与右边
操作数位或,结果赋值给左边变量
a|=b,a 赋得 7(该赋值表达式
值也为 7)
^= 位异或且赋值运算符,将左操作数与右
边操作数位异或,结果赋值给左边变量
a^=1,a 赋得 2(该赋值表达式
值也为 2)
注:除普通赋值运算外,其它赋值运算称为复合赋值运算。
2. 示例
请看下面的实例:
#include <iostream>
using namespace std;
int main(){
int a,b,c,d;
a=3;
b=5;
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 37
c=10;
d=1;
c*=a+b;
d+=a+=100;
b<<=a/50;
cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
return 0;
}
程序运行结果::
103 20 80 104
3. 赋值运算符之间的优先级与结合性
1) 优先级
普通赋值运算符和各复合赋值运算符运算优先级相同。
2) 结合性
均自右而左。
六、*其它 C++运算符
1. C++其它运算符功能列表
下表列出了 C++支持的其它重要运算符。
运算符 功能描述
sizeof()
sizeof 运算符返回变量/数据占用空间的大小。例如,
sizeof(123456) 将返回 4。
条件? X : Y 条件运算符。如果“条件”为真,则值为 X,否则值为 Y。
, 逗号运算符会顺序执行一系列运算。整个逗号表达式的值
是逗号表达式列表中的最后一个表达式的值。
.(点)和 ->(箭头) 成员运算符用于引用类、结构和共用体的成员。
cast
(类型强制转换)
强制转换运算符把一种数据类型转换为另一种数据类型。
例如,int(2.2000)将返回 2。
& 取地址运算符。&a 将返回变量 a 的地址。
* 指针运算符。*p 为指针变量 p 所指向的变量。
2. 示例
#include <iostream>
using namespace std;
int main(){
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 38
int a,b;
char c;
double x;
float y;
a=1; b=123456789;
cout<<sizeof(a)<<" "<<sizeof(b)<<" "<<sizeof(568)<<endl;
cout<<sizeof(c)<<" "<<sizeof(x)<<" "<<sizeof(y)<<endl;
int d;
d=a>b?a:a+1;
y=65.2;
c=char(y+5.8);
cout<<c<<" "<<d<<endl;
return 0;
}
程序运行结果:
4 4 4
1 8 4
F 2
七、C++中运算符优先级与结合性
1. 运算符优先级与结合性一览表
下表按运算符优先级从高到低列出各运算符(具有较高优先级的运算符出现在表格的
上面,在表达式中,较高优先级的运算符会优先被计算)。
类别 运算符 优先级 结合性
后缀 () [] -> . 最高 从左到右
一元 + - ! ~ ++ -- (type) * & sizeof 自











从右到左
乘除 * / % 从左到右
加减 + - 从左到右
移位 << >> 从左到右
关系 < <= > >= 从左到右
相等 == != 从左到右
位与 & 从左到右
位异或 ^ 从左到右
位或 | 从左到右
逻辑与 && 从左到右
逻辑或 || 从左到右
条件 ?: 从右到左
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 39
赋值 = += -= *= /= %= >>= <<= &= ^= |= 从右到左
逗号 , 最低 从左到右
2. 示例
下面列举了一些简单问题和相应的运算表达式。给出的表达式中使用的括号都是必须
的,各运算符之间的运算顺序按默认优先级进行。
1、判断年份 year 是否闰年:
year%400==0||year%4==0&&year%100!=0
这里涉及%、==、!=、&&、||等 5 种运算符. 2、为字符型变量 a、b、c、d 统一赋值字符’#’的值:
a=b=c=d=’#’ 赋值运算适用自右而左结合。
注意,如果在写表达式时把握不了运算符之间的优先关系,可以通过适当加括号达到
目的。如上面的判断闰年表达式,若确定不了==、!=与&&、||之间以及&&和||之间的优先
关系,表达式可以写成下式:
(year%400==0)||((year%4==0)&&(year%100!=0))
这样逻辑关系就清晰多了。
八、例题
【例题 1】求任意给定的三位自然数各数字之和。
输入样例
398
输出样例
20
解:如何从一个自然数中把各位数字分解出来?我们可以利用整数的整除运算(/)和求
模运算(%)。任何自然数除以 10 的余数就是该数的个位数字。知道这一点,不难写出程
序:
#include<iostream>
using namespace std;
int main(){
int n,a,b,c;
cin>>n;
a=n%10;//n 的个位数字;
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 40
b=n/10%10 //n 的十位数字
c=n/100%10 //n 的百位数字,因为是三位自然数,所以这里的%10 不是必要的。
cout<<a+b+c;
return 0;
}
【例题 2】求给定的两个实数相除的整数商和余数。
如输入
12.8 9.1
输出
1 3.7
解:求实数 x 除以实数 y 的商为 x/y,整数商目前我们可以用向下取整函数 floor()实现,
也可以用类型强制转换或自动类型转换实现。参考程序如下:
#include <iostream>
#include<cmath>
using namespace std;
int main(){
float x,y,z;
int n;
cin>>x>>y;
n=floor(x/y); //可以用强制类型转换 n=(int) (x/y);或自动类型转换 n=x/y;
z=x-y*n;
cout<<n<<" "<<z;
return 0;
}
习题四
1、计算下列表达式的值,并上机验证。
1)78%10*10+78/10
2)3.14159-(int)3.14159
3)2019%400==0 || 2019%4==0 && 2019%100!=0
4)1.0*200/15
8)200/15*1.0
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 41
2、编程解题
1)浮点数向零舍入输出
描述
输入一个单精度浮点数,将其向零舍入到整数。
说明:向零舍入的含义是,正数向下舍入,负数向上舍入。
提示:可以使用强制类型转换或自动类型转换来实现。
输入
一个单精度浮点数。
输出
一个整数,即向零舍入到整数的结果。
样例输入
2.3
样例输出
2
2)打印 ASCII 码
描述
输入一个除空格以外的可见字符(保证在函数 scanf 中可使用格式说明符%c 读入),
输出其 ASCII 码。
输入
一个除空格以外的可见字符。
输出
一个十进制整数,即该字符的 ASCII 码。
样例输入
A
样例输出
65
3)打印 ASCII 字符
描述
输入一个 ASCII 码,输出对应的字符。
输入
青少年信息学奥林匹克竞赛
©程老师信息学奥赛课堂 4

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值