写在前面:
如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持!
【C++语言基础学习】系列文章
第一章 《项目与程序结构》
第二章 《数据类型》
第三章 《运算符》
第四章 《流程控制》
第五章 《Vector向量》
第六章 《String字符串》
第七章 《Array数组》
第八章 《函数》
第九章 《指针》
第十章 《结构体》
文章目录
一、运算符分类
(一)算术运算符
算术运算符(Arithmetic Operator),即为C++语言中用于执行各种数学运算的运算符。
符号 | 名称 | 作用 |
---|---|---|
+ | 加法运算符 | 用于执行两个操作数的相加运算 |
~ | 减法运算符 | 用于执行两个操作数的相减运算 |
* | 乘法运算符 | 用于执行两个操作数的相乘运算 |
/ | 除法运算符 | 用于执行两个操作数的相除运算 |
% | 取模运算符 | 用于获取两个操作数相除后的余数 |
++ | 自增运算符 | 用于将操作数的值增加1 |
-- | 自减运算符 | 用于将操作数的值减少1 |
使用test.cpp的下列代码实验。
#include "test.h"
#include <iostream>
using namespace std;
void test::Test()
{
int a = 10;
int b = 3;
cout << "a + b:" << a + b << endl;
cout << "a - b:" << a - b << endl;
cout << "a * b:" << a * b << endl;
cout << "a / b:" << a / b << endl;
cout << "a % b:" << a % b << endl;
cout << "++a:" << ++a << endl;
cout << "--b:" << --b << endl;
}
返回结果如下。
a + b:13
a - b:7
a * b:30
a / b:3
a % b:1
++a:11
–b:2
(二)关系运算符
关系运算符(Relational Operator)用于比较两个值之间的关系,并返回一个布尔值(true 或 false),如果条件满足,则返回真(true),否则返回假(false)。
符号 | 名称 | 作用 |
---|---|---|
== | 相等比较 | 用于检查两个值是否相等 |
!= | 不相等比较 | 用于检查两个值是否不相等 |
> | 大于比较 | 用于检查第一个值是否大于第二个值 |
< | 小于比较 | 用于检查第一个值是否小于第二个值 |
>= | 大于等于比较 | 用于检查第一个值是否大于等于第二个值 |
<= | 小于等于比较 | 用于检查第一个值是否小于等于第二个值 |
使用test.cpp的下面代码实验。
#include "test.h"
#include <iostream>
using namespace std;
void test::Test()
{
int a = 100;
int b = 500;
if (a == b)
{
cout << "a与b相等" << endl;
}
else if (a != b)
{
cout << "a与b不等" << endl;
}
if (a > b)
{
cout << "a大于b" << endl;
}
else if (a < b)
{
cout << "a小于b" << endl;
}
}
返回结果如下。
a与b不等
a小于b
这里使用了两个if语句来判定关系运算符的判定结果,首先判定a与b是否相等,完成后再次判定a与b的大小关系。其中if语句的括号内的判定条件只有结果为真才会执行大括号内的代码逻辑(本系列以后部分会具体解释if语句的使用)。
(三)逻辑运算符
逻辑运算符(Logical Operator)用于对布尔类型的值进行逻辑操作,它们返回的结果也是布尔值(true 或 false)。
符号 | 逻辑 | 作用 |
---|---|---|
&& | 与 | 用于检查两个条件是否都成立 |
|| | 或 | 用于检查两个条件是否至少一个成立 |
! | 非 | 用于取反一个条件的结果 |
使用test.cpp的下面代码实验。
#include "test.h"
#include <iostream>
using namespace std;
void test::Test()
{
int baseScore = 60;
int myScore1 = 80;
int myScore2 = 58;
if (myScore1 > baseScore && myScore2 > baseScore)
{
cout << "我的两门成绩都及格了!" << endl;
}
else if (myScore1 > baseScore || myScore2 > baseScore)
{
cout << "我只有一门成绩及格了!" << endl;
}
else if (!(myScore1 > baseScore && myScore2 > baseScore))
{
cout << "我的两门成绩都不及格!" << endl;
}
}
返回结果如下。
我只有一门成绩及格了!
从这里的if语句判断条件就可以看到,使用逻辑与运算符令我的两门成绩都必须及格才能返回“我的两门成绩都及格了!”的提示;使用逻辑或运算符令我的两门成绩中有一门合格就返回“我只有一门成绩合格了!”的提示;使用逻辑非运算符取反第一个判定条件(即我的两门成绩都必须不合格)才会返回“我的两门成绩都不及格!”的提示。由于设定的第一门成绩为80分,第二门成绩为58分,故返回“我只有一门成绩及格了!”。
(四)位运算符
位运算符(Bitwise Operator)用于对二进制数据的位进行操作。它们对操作数的每个位执行逻辑运算,并返回一个结果。
符号 | 名称 | 运算规则 |
---|---|---|
& | 按位与 | 0 & 0 = 0;0 & 1 = 0;1 & 0 = 0;1 & 1 = 1 |
| | 按位或 | 0 | 0 = 0;0 | 1 = 1;1 | 0 = 1;1 | 1 = 1 |
^ | 按位异或 | 0 ^ 0 = 0;0 ^ 1 = 0;1 ^ 0 = 0;1 ^ 1 = 1 |
~ | 按位取反 | ~ 1 = -2;~ 0 = -1 |
<< | 左移 | 将操作数的每个位向左移动指定的位数 |
>> | 右移 | 将操作数的每个位向右移动指定的位数 |
使用test.cpp的下面代码实验。
#include "test.h"
#include <iostream>
using namespace std;
void test::Test()
{
int a = 1;// 二进制为0b01
int b = 3;// 二进制为0b11
cout << "a&b:" << (a & b) << endl;
cout << "a|b:" << (a | b) << endl;
cout << "a^b:" << (a ^ b) << endl;
cout << "~a:" << (~a) << endl;
cout << "a<<2:" << (a << 2) << endl;
cout << "a>>2:" << (a >> 2) << endl;
}
返回结果如下。
a&b:1
a|b:3
a^b:2
~a:-2
a<<2:4
a>>2:0
代码设定a为1,二进制则为1;b为3,二进制则为11。当a和b进行与运算时即01 & 11 = 01,返回十进制数字1;当a和b进行或运算时即01 | 11 = 11,返回十进制数字3;当a和b进行异或运算时即01 ^ 11 = 10,返回十进制数字2;当取反a时即~1 =-2;当a左移两位时即从1变成了100,返回十进制数字4;当a右移两位时由于总共只有1一位,左移两位归零,返回十进制数字0。
(五)赋值运算符
赋值运算符(Assignment Operator)用于将一个值赋给变量。它将右边的操作数的值赋给左边的操作数(通常是一个变量),并返回一个值。
符号 | 名称 | 运算法则 |
---|---|---|
= | 简单赋值运算符 | 把右边操作数的值赋给左边操作数 |
+= | 加法赋值运算符 | x = x + y |
-= | 减法赋值运算符 | x = x - y |
*= | 乘法赋值运算符 | x = x * y |
/= | 除法赋值运算符 | x = x / y |
%= | 取模赋值运算符 | x = x % y |
<<= | 左移赋值运算符 | x = x << y |
>>= | 右移赋值运算符 | x = x >> y |
&= | 按位与赋值运算符 | x = x & y |
|= | 按位或赋值运算符 | x = x | y |
^= | 按位异或赋值运算符 | x = x ^ y |
使用test.cpp的下面代码实验。
#include "test.h"
#include <iostream>
using namespace std;
void test::Test()
{
int a = 2;
int b = 3;
cout << "a+=b:" << (a += b) << endl;
cout << "a-=b:" << (a -= b) << endl;
cout << "a*=b:" << (a *= b) << endl;
cout << "a/=b:" << (a /= b) << endl;
cout << "a%=b:" << (a %= b) << endl;
cout << "a<<=b:" << (a <<= b) << endl;
cout << "a>>=b:" << (a >>= b) << endl;
cout << "a&=b:" << (a &= b) << endl;
cout << "a|=b:" << (a |= b) << endl;
cout << "a^=b:" << (a ^= b) << endl;
}
返回结果如下。
a+=b:5
a-=b:2
a*=b:6
a/=b:2
a%=b:2
a<<=b:16
a>>=b:2
a&=b:2
a|=b:3
a^=b:0
(六)其他运算符
除了以上运算符外,C++语言中还有一些其他的运算符。
符号 | 名称 | 描述 | 实例 |
---|---|---|---|
sizeof | sizeof运算符 | 返回变量所占用的字节数 | 当a为整型变量,sizeof(a) 则返回4 |
?: | 条件运算符 | 根据条件的真假选择执行两个不同的表达式 | int max = (x > y) ? x : y 表示若x大于y则max值为x,否则为y |
, | 逗号运算符 | 顺序执行一系列运算 | int x = 1, y = 2, z = 3 建立x,y,z三个整型变量 |
. 和-> | 成员运算符 | 访问类和结构体中的成员变量和成员函数 | testObject.testStorage() 就是调用testObject对象的testStorage函数 |
Cast | 强制转换运算符 | 把一种数据类型转换为另一种数据类型 | int(2.22) 将返回2 |
& | 取址运算符 | 返回变量的地址 | &a 将给出变量a的实际地址 |
* | 解引用运算符 | 访问指针指向的内存位置的值 | *var 将指向变量var |
二、运算符优先级
C++中的运算符按照优先级从高到低的顺序执行。
优先级 | 操作符 | 描述 | 实例 | 结合性 |
---|---|---|---|---|
1 | () [] -> . :: ++ -- | 调节优先级的括号操作符 数组下标访问操作符 通过指向对象的指针访问成员的操作符 通过对象本身访问成员的操作符 作用域操作符 后置自增操作符 后置自减操作符 | (a + b) / 4; array[4] = 2; ptr->age = 34; obj.age = 34; Class::age = 2; for (i = 0; i < 10; i++)... for (i = 10; i > 0; i--)... | 从左到右 |
2 | ! ~ ++ -- - + * & (type) sizeof | 逻辑取反操作符 按位取反(按位取补) 前置自增操作符 前置自减操作符 一元取负操作符 一元取正操作符 解引用操作符 取值操作符 类型转换操作符 返回对象占用的字节数操作符 | if (!done)... flags = ~flags; for (i = 0; i < 10; ++i)... for (i = 10; i > 0; --i)... int i = -1; int i = +1; data = *ptr; address = &obj; int i = (int)floatNum int size = sizeof(floatNum) | 从右到左 |
3 | -> . | 在指针上通过指向成员指针访问成员的操作符 在对象上通过指向成员指针访问成员的操作符 | ptr->var = 24; obj.var = 24; | 从左到右 |
4 | * / % | 乘法操作符 除法操作符 取余数操作符 | int i = 2 * 4; float f = 10 / 3; int rem = 4 % 3; | 从左到右 |
5 | + - | 加法操作符 减法操作符 | int i = 2 + 3; int i = 5 - 1; | 从左到右 |
6 | << >> | 按位左移操作符 按位右移操作符 | int flags = 33 << 1; int flags = 33 >> 1; | 从左到右 |
7 | < <= > >= | 小于比较操作符 小于等于比较操作符 大于比较操作符 大于等于比较操作符 | if (i < 42)... if (i <= 42)... if (i > 42)... if (i >= 42)... | 从左到右 |
8 | == != | 等于比较操作符 不等于比较操作符 | if (i == 42)... if (i != 42)... | 从左到右 |
9 | & | 按位与操作符 | flags = flags & 42; | 从左到右 |
10 | ^ | 按位异或操作符 | flags = flags ^ 42; | 从左到右 |
11 | | | 按位或操作符 | flags = flags | 42; | 从左到右 |
12 | && | 逻辑与操作符 | if (i > 1 && j < 2)... | 从左到右 |
13 | || | 逻辑或操作符 | if (i > 1 || j < 2)... | 从左到右 |
14 | ? : | 三元条件操作符 | int i = (a > b) ? a : b; | 从右到左 |
15 | = += -= *= /= %= &= ^= |= <<= >>= | 赋值操作符 复合赋值操作符(加法) 复合赋值操作符(减法) 复合赋值操作符(乘法) 复合赋值操作符(除法) 复合赋值操作符(取余) 复合赋值操作符(按位与) 复合赋值操作符(按位异或) 复合赋值操作符(按位或) 复合赋值操作符(按位左移) 复合赋值操作符(按位右移) | int a = b; a += 3; b -= 4; a *= 5; a /= 2; a %= 3; flags &= new_flags; flags ^= new_flags; flags |= new_flags; flags <<= 2; flags >>= 3; | 从左到右 |
16 | , | 逗号操作符 | int a = 1, b = 2, c = 3; | 从左到右 |
其中,运算符结合性指的是当同一优先级的运算符连续出现时,它们的计算顺序是从左到右还是从右到左。
使用test.cpp的下面代码实验。
#include "test.h"
#include <iostream>
using namespace std;
void test::Test()
{
int a = 3;
int b = 2;
if (a > b && a + b < a + (a - b) * 2)
{
cout << "条件成立" << endl;
}
else
{
cout << "条件不成立" << endl;
}
}
这里if语句的判定条件中,首先运行的顺序由最高优先级的()
括号运算符开始,计算得a-b=1;然后再运算优先级次一级的*
乘法运算符,计算得1*2=2;下一级运算+
和-
的加减法运算符,计算得a+b=5和a+2=4;再下一级运算>
和<
的大于小于比较运算符,计算得a>b成立和5<4不成立;最终运算&&
逻辑与运算符,由于两个条件只有一个满足,所以判断条件会返回false。
返回结果如下。
条件不成立
三、类型转换
类型转换(Type Conversion)是将一个数据类型的值转换为另一个数据类型的过程。在编程中,经常需要进行类型转换以适应不同的操作或满足特定的需求。
类型转换可以分为显式转换和隐式转换两种方式。
(一)隐式转换
隐式转换(Implicit Conversion):也称为自动转换,由编译器在表达式中自动进行的类型转换,无需显式指定。隐式转换通常发生在不同数据类型之间,例如将整数转换为浮点数、将较小的整数类型转换为较大的整数类型等,通常是从存储空间占用小的类型转换到存储空间占用大的类型,从精度小的类型转换到精度大的类型。有些情况下,编译器还会将字面量转换为合适的数据类型。
使用test.cpp的下面代码实验。
#include "test.h"
#include <iostream>
using namespace std;
void test::Test()
{
float a = 1.25f;
short int b = 3000;
char c = 65;
cout << "浮点型a占用字节为" << sizeof(a) << endl;
cout << "短整型b占用字节为" << sizeof(b) << endl;
cout << "字符型c占用字节为" << sizeof(c) << endl;
cout << "浮点数与整数相加" << a + b << "占用字节为" << sizeof(a + b) << endl;
cout << "字节与整数相加" << b + c << "占用字节为" << sizeof(b + c) << endl;
}
返回结果如下。
浮点型a占用字节为4
短整型b占用字节为2
字符型c占用字节为1
浮点数与整数相加3001.25占用字节为4
字节与整数相加3065占用字节为4
从返回结果可以看到,在加法运算完成后,其结果均自动变换了数据存储形式,导致储存空间在运算后纷纷发生了变化。
(二)显式转换
显式转换(Explicit Conversion):也称为强制类型转换,需要通过显式指定转换的方式将一个数据类型的值转换为另一个数据类型。在C++中,可以使用特定的类型转换运算符来实现显式转换。常见的显式转换操作符包括 static_cast
、const_cast
、reinterpret_cast
和dynamic_cast
。
使用test.cpp的下面代码实验。
#include "test.h"
#include <iostream>
using namespace std;
void test::Test()
{
float a = 1.25f;
short int b = 3000;
char c = 65;
// C风格转换
cout << "浮点数与整数相加" << (int)a + b << "占用字节为" << sizeof((int)a + b) << endl;
cout << "字节与整数相加" << (char)b + c << "占用字节为" << sizeof((char)b + c) << endl;
// C++风格转换
int intnum = static_cast<int>(a);
cout << "浮点转换" << intnum << endl;
}
返回结果如下。
浮点数与整数相加3001占用字节为4
字节与整数相加-7占用字节为4
浮点转换1
可以看到,显式转换也分为C语言风格,即直接使用类型转换操作符(type)
转换数据类型;而C++语言风格则是使用类似static_cast
的关键字进行类型转换。
但需要注意的是,当进行例如从整型转换到字符型的转换时,有可能会发生返回值为“-7”的溢出现象,所以使用类型转换时应当尽量避免大类型向小类型转换。
我是EC,一个永远在学习中的探索者,关注我,让我们一起进步!