梦想不会自己发光,真正闪耀的是那个为梦狂奔的你。献给知行的孩子们!(Eric.He著)
本教程将从 C++ 运算符和表达式的核心概念出发,全面拆解算术、关系、逻辑、位操作、赋值等各类运算符的语法、用法和优先级,帮助你掌握这一C++编程的基础核心技能。
表达式(Expression)是由运算符、操作数(常量、变量、函数调用等)和括号组成的、符合C++语法规则的式子,表达式执行后会产生一个确定的值。
示例:
// 简单表达式
3 + 5; // 算术表达式,值为8
a > b; // 关系表达式,值为true/false
x = 10; // 赋值表达式,值为10
// 复合表达式
(a + b) * c - 5; // 混合算术表达式
!(x > 0) && y == 5; // 混合逻辑表达式
运算符(Operator)是 C++ 中用于执行特定操作的符号,它能够对一个或多个操作数(变量、常量、表达式)进行运算并返回结果。
C++ 运算符按功能可分为以下大类:
按操作数个数可分为:
当一个表达式包含多个运算符时,优先级决定运算的先后顺序(如先乘除后加减);当多个运算符优先级相同时,结合性决定运算方向(从左到右/从右到左)。
// 优先级示例
int a = 3 + 5 * 2; // 先算5*2=10,再算3+10=13,a=13
int b = (3 + 5) * 2; // 括号优先,先算3+5=8,再算8*2=16,b=16
// 结合性示例
int c = 10 - 5 - 2; // 从左到右:(10-5)-2=3
int d = 10 = 5; // 错误!赋值运算符从右到左,但10是常量不能被赋值
int e = f = 0; // 从右到左:先f=0,再e=f,e=0
算术运算符用于执行基本的数学运算,包括加、减、乘、除、取模、自增、自减,除自增/自减为单目,其它均为双目运算符。
| 运算符 | 名称 | 语法 | 说明 | 示例 |
|---|---|---|---|---|
| + | 加法 | a + b | 求a与b的和 | 5 + 3 → 8 |
| - | 减法 | a - b | 求a与b的差 | 5 - 3 → 2 |
| * | 乘法 | a * b | 求a与b的积 | 5 * 3 → 15 |
| / | 除法 | a / b | 求a除以b的商(整数除法取整,浮点数保留小数) | 5 / 2 → 2;5.0 / 2 → 2.5 |
| % | 取模(取余) | a % b | 求a除以b的余数(仅适用于整数) | 5 % 2 → 1;7 % 3 → 1 |
| ++ | 自增 | ++a / a++ | 前置自增:先加1后使用;后置自增:先使用后加1 | int a=3, b=0; b=++a; //a为4, b为4 |
| -- | 自减 | --a / a-- | 前置自减:先减1后使用;后置自减:先使用后减1 | int a=3, b=0; b=--a; //a为2, b为2 |
#include <iostream>
using namespace std;
int main() {
int a = 10, b = 3;
// 基本算术运算
cout << "a + b = " << a + b << endl; // 13
cout << "a - b = " << a - b << endl; // 7
cout << "a * b = " << a * b << endl; // 30
cout << "a / b = " << a / b << endl; // 3(整数除法)
cout << "a % b = " << a % b << endl; // 1(取余)
// 自增/自减运算
int c = 5;
cout << "前置自增:" << ++c << endl; // 6(c先加1,再输出)
cout << "c的值:" << c << endl; // 6
int d = 5;
cout << "后置自增:" << d++ << endl; // 5(先输出,d再加1)
cout << "d的值:" << d << endl; // 6
// 浮点数除法
double e = 10.0, f = 3.0;
cout << "e / f = " << e / f << endl; // 3.33333
return 0;
}
关系运算符用于比较两个操作数的大小或相等关系,返回值为bool布尔类型(真 true / 假 false,对应C++中的1/0),均为双目运算符。
| 运算符 | 名称 | 语法 | 说明 | 示例(a=5, b=3) |
|---|---|---|---|---|
| > | 大于 | a > b | a大于b时为true,否则为false | 5>3 → true |
| < | 小于 | a < b | a小于b时为true,否则为false | 5<3 → false |
| >= | 大于等于 | a >= b | a大于或等于b时为true | 5>=3 → true;3>=3 → true |
| <= | 小于等于 | a <= b | a小于或等于b时为true | 5<=3 → false;3<=3 → true |
| == | 等于 | a == b | a与b相等时为true | 5==3 → false;3==3 → true |
| != | 不等于 | a != b | a与b不相等时为true | 5!=3 → true;3!=3 → false |
#include <iostream>
using namespace std;
int main() {
int x = 10, y = 20;
cout << "x > y: " << (x > y) << endl; // 0(false)
cout << "x < y: " << (x < y) << endl; // 1(true)
cout << "x >= 10: " << (x >= 10) << endl;// 1(true)
cout << "y <= 15: " << (y <= 15) << endl;// 0(false)
cout << "x == 10: " << (x == 10) << endl;// 1(true)
cout << "y != 20: " << (y != 20) << endl;// 0(false)
// 关系表达式常用于条件判断
if (x < y) {
cout << "x小于y" << endl;
}
return 0;
}
逻辑运算符用于对布尔值进行逻辑运算(与、或、非),返回值为布尔类型,其中&&和||为双目运算符,!为单目运算符。
| 运算符 | 名称 | 语法 | 说明 | 示例(a=true, b=false) |
|---|---|---|---|---|
| && | 逻辑与 | a && b | 两边都为true时才为true;左为false时,右不执行(短路求值) | true&&false → false |
| || | 逻辑或 | a || b | 至少一边为true时为true;左为true时,右不执行(短路求值) | true||false → true |
| ! | 逻辑非 | !a | 取反:true→false,false→true | !true → false;!false → true |
#include <iostream>
using namespace std;
int main() {
int m = 5, n = 0;
// 逻辑与(短路求值:n==0为true,才执行m>0)
if (n == 0 && m > 0) {
cout << "n为0且m大于0" << endl;
}
// 逻辑或(短路求值:m>0为true,n>0无需执行)
if (m > 0 || n > 0) {
cout << "m大于0或n大于0" << endl;
}
// 逻辑非
if (!(m == n)) {
cout << "m不等于n" << endl;
}
// 短路求值演示
int a = 1, b = 1;
// a>2为false,逻辑与短路,b++不会执行
if (a > 2 && b++) {
cout << "执行了b++" << endl;
}
cout << "b的值:" << b << endl; // 1(b++未执行)
return 0;
}
位操作运算符用于对整数的二进制位进行操作,直接操作内存中的二进制位,效率极高,均为双目运算符(除~为单目)。
参考教程:1.6 进制转换、1.9 原码补码反码
| 运算符 | 名称 | 语法 | 说明 | 示例(a=6(0110), b=3(0011)) |
|---|---|---|---|---|
| & | 按位与 | a & b | 对应位都为1时,结果位为1,否则为0 | 6&3 → 2(0010) |
| | | 按位或 | a | b | 对应位至少一个为1时,结果位为1 | 6|3 → 7(0111) |
| ^ | 按位异或 | a ^ b | 对应位不同时为1,相同时为0 | 6^3 → 5(0101) |
| ~ | 按位取反 | ~a | 所有位取反(1→0,0→1) | ~6 → -7(补码表示) |
| << | 左移 | a << n | 将a的二进制位左移n位,右侧补0(等价于乘2ⁿ) | 6<<1 → 12(1100) |
| >> | 右移 | a >> n | 将a的二进制位右移n位,左侧补符号位(等价于除2ⁿ取整) | 6>>1 → 3(0011) |
#include <iostream>
using namespace std;
int main() {
int a = 6; // 二进制:0000 0110
int b = 3; // 二进制:0000 0011
cout << "a & b = " << (a & b) << endl; // 2(0000 0010)
cout << "a | b = " << (a | b) << endl; // 7(0000 0111)
cout << "a ^ b = " << (a ^ b) << endl; // 5(0000 0101)
cout << "~a = " << (~a) << endl; // -7(补码:1111 1001)
cout << "a << 1 = " << (a << 1) << endl;// 12(0000 1100)
cout << "a >> 1 = " << (a >> 1) << endl;// 3(0000 0011)
// 位操作经典应用:交换两个数(无需临时变量)
int x = 10, y = 20;
cout << "交换前:x=" << x << ", y=" << y << endl;
x = x ^ y;
y = x ^ y;
x = x ^ y;
cout << "交换后:x=" << x << ", y=" << y << endl;
return 0;
}
简单赋值运算符(=)用于将右侧表达式的值赋给左侧变量,是双目运算符,结合性为“从右到左”。
语法:变量 = 表达式;
int main() {
int num1 = 10; // 直接赋值
int num2 = num1 + 5; // 表达式结果赋值
int a, b, c;
a = b = c = 0; // 连续赋值(从右到左:c=0 → b=c → a=b)
// 注意:赋值运算符左侧必须是可修改的左值(变量),不能是常量/表达式
// 5 = 10; // 错误:5是常量
// (a + b) = 20; // 错误:a+b是表达式,不是左值
return 0;
}
复合算术赋值运算符是赋值运算符与算术运算符的结合,用于简化“运算+赋值”操作,均为双目运算符。
| 运算符 | 语法 | 等价于 | 示例(a=10) |
|---|---|---|---|
| += | a += b | a = a + b | a += 5 → a=15 |
| -= | a -= b | a = a - b | a -= 3 → a=7 |
| *= | a *= b | a = a * b | a *= 2 → a=20 |
| /= | a /= b | a = a / b | a /= 4 → a=2 |
| %= | a %= b | a = a % b | a %= 3 → a=1 |
#include <iostream>
using namespace std;
int main() {
int x = 20;
x += 5; // x = x + 5 → 25
cout << "x += 5: " << x << endl;
x -= 8; // x = x - 8 → 17
cout << "x -= 8: " << x << endl;
x *= 2; // x = x * 2 → 34
cout << "x *= 2: " << x << endl;
x /= 3; // x = x / 3 → 11
cout << "x /= 3: " << x << endl;
x %= 4; // x = x % 4 → 3
cout << "x %= 4: " << x << endl;
return 0;
}
条件运算符(?:)是C++中唯一的三目运算符,用于简化简单的if-else判断,语法简洁、执行高效。
语法:条件表达式 ? 表达式1 : 表达式2;
规则:
#include <iostream>
using namespace std;
int main() {
// 示例1:求两个数的最大值
int num1 = 15, num2 = 25;
int maxNum = (num1 > num2) ? num1 : num2;
cout << "最大值:" << maxNum << endl; // 25
// 示例2:判断奇偶性
int n = 7;
string res = (n % 2 == 0) ? "偶数" : "奇数";
cout << n << "是" << res << endl; // 7是奇数
// 示例3:等价于if-else
int score = 85;
// 条件运算符版
string level = (score >= 90) ? "优秀" : (score >= 80) ? "良好" : "及格";
cout << "成绩等级:" << level << endl; // 良好
// 等价的if-else版
if (score >= 90) {
level = "优秀";
} else if (score >= 80) {
level = "良好";
} else {
level = "及格";
}
return 0;
}
逗号运算符(,)用于将多个表达式连接成一个表达式,按从左到右顺序执行所有表达式,最终返回最后一个表达式的值。
语法:表达式1, 表达式2, 表达式3, ..., 表达式n;
#include <iostream>
using namespace std;
int main() {
// 示例1:基本用法
int a, b;
// 执行顺序:a=1 → b=2 → a+b=3,最终返回3
int c = (a=1, b=2, a+b);
cout << "c = " << c << endl; // 3
cout << "a = " << a << endl; // 1
cout << "b = " << b << endl; // 2
// 示例2:循环中使用(初始化/更新多个变量)
int i, j;
for (i=0, j=10; i<5; i++, j--) {
cout << "i=" << i << ", j=" << j << endl;
}
// 示例3:注意优先级(逗号运算符优先级最低)
int d = 5 + 3, 10; // 错误!等价于(d=5+3), 10
int e = (5 + 3, 10); // 正确:先算5+3,再返回10,e=10
return 0;
}
取内容运算符(解引用运算符)是单目运算符,用于访问指针变量指向的内存地址中的值。
语法:*指针变量;
取地址运算符是单目运算符,用于获取变量的内存地址(返回值为指针类型)。
语法:&变量名;
#include <iostream>
using namespace std;
int main() {
// 取地址运算符&:获取变量地址
int num = 100;
int* p = &num ; // p存储num的内存地址
cout << "num的值:" << num << endl; // 100
cout << "num的地址:" << &num << endl; // 如0x7ffeefbff5ac
cout << "指针p的值:" << p << endl; // 与&num相同
// 取内容运算符*:访问指针指向的值
cout << "p指向的值:" << *p << endl; // 100
// 修改指针指向的值
*p = 200;
cout << "修改后num的值:" << num << endl; // 200
// 注意:指针运算符的优先级
int a = 5, b = 10;
int* q = &a;
*q += b; // 等价于(*q) += b,a=15(*优先级高于+=)
cout << "a的值:" << a << endl; // 15
return 0;
}
sizeof运算符是单目运算符,用于计算数据类型或变量在内存中占用的字节数,编译期计算(无运行时开销)。
语法:
sizeof(数据类型);:计算指定类型的字节数;sizeof(变量名);:计算变量的字节数(可省略括号);sizeof 表达式;:计算表达式结果类型的字节数(表达式不执行)。
#include <iostream>
using namespace std;
int main() {
// 基本数据类型的字节数
cout << "char: " << sizeof(char) << "字节" << endl; // 1
cout << "int: " << sizeof(int) << "字节" << endl; // 4(32/64位系统)
cout << "float: " << sizeof(float) << "字节" << endl; // 4
cout << "double: " << sizeof(double) << "字节" << endl; // 8
cout << "long long: " << sizeof(long long) << "字节" << endl; // 8
// 变量的字节数
int num = 10;
cout << "num的字节数:" << sizeof num << endl; // 4(省略括号)
// 数组的字节数(总字节数)
int arr[5] = {1,2,3,4,5};
cout << "数组arr总字节数:" << sizeof(arr) << endl; // 20(5*4)
cout << "数组元素个数:" << sizeof(arr)/sizeof(arr[0]) << endl; // 5
// 表达式的字节数(表达式不执行)
int a = 1, b = 2;
cout << "sizeof(a+b): " << sizeof(a+b) << endl; // 4(int类型)
cout << "a的值:" << a << endl; // 1(a+b未执行)
// 结构体的字节数(考虑内存对齐)
struct Student {
char name[20];
int age;
float score;
};
cout << "Student结构体字节数:" << sizeof(Student) << endl; // 28(20+4+4,内存对齐)
return 0;
}
括号运算符有两大核心作用:
// 作用1:改变优先级
int res1 = 3 + 5 * 2; // 13(先乘后加)
int res2 = (3 + 5) * 2; // 16(先加后乘)
// 作用2:函数调用
int add(int a, int b) {
return a + b;
}
int main() {
int sum = add(3,5); // ()用于函数调用,传递参数
return 0;
}
下标运算符用于访问数组/容器的元素,是双目运算符(左侧为数组/容器,右侧为索引)。
语法:数组名[索引] / 容器名[索引]
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 数组下标访问
int arr[5] = {10,20,30,40,50};
cout << arr[2] << endl; // 30(访问第3个元素,索引从0开始)
arr[3] = 45; // 修改第4个元素
// 容器下标访问
vector vec = {1,2,3,4,5};
cout << vec[1] << endl; // 2
// 注意:下标越界不会编译报错,但运行时会崩溃
// cout << arr[10] << endl; // 未定义行为
return 0;
}
成员访问运算符用于访问结构体/类的成员变量或成员函数:
.(点运算符):用于普通对象/引用对象访问成员;->(箭头运算符):用于指针对象访问成员。
#include <iostream>
#include <cstring>
using namespace std;
struct Student {
char name[20];
int age;
void printInfo() {
cout << "姓名:" << name << ",年龄:" << age << endl;
}
};
int main() {
// 普通对象:. 访问成员
Student stu;
strcpy(stu.name, "张三");
stu.age = 18;
stu.printInfo();
// 指针对象:-> 访问成员
Student* pStu = &stu;
pStu->age = 19;
pStu->printInfo();
// 引用对象:. 访问成员
Student& refStu = stu;
refStu.age = 20;
refStu.printInfo();
return 0;
}
本教程从运算符和表达式的核心概念出发,全面拆解了各类运算符的语法、用法和注意事项。掌握运算符的灵活运用,是学习C++编程的必经之路,也是后续学习流程控制、函数、类和对象的重要基础。