C++ 运算符

运算符(operator)是程序里"做计算"的符号——加号、等号、比较大小等等。C++ 提供了丰富的运算符,大部分你数学课就学过,少数是编程特有的(位运算、三元)。这一章我们一一过一遍。

一、算术运算符

最基础的加减乘除:

#include <iostream>
using namespace std;

int main() {
    int a = 17, b = 5;

    cout << a + b << endl;   // 22 加法
    cout << a - b << endl;   // 12 减法
    cout << a * b << endl;   // 85 乘法
    cout << a / b << endl;   // 3  除法(整数除整数,直接舍去小数)
    cout << a % b << endl;   // 2  取余(只对整数)

    // 整数除法的坑
    cout << 7 / 2 << endl;     // 3
    cout << 7.0 / 2 << endl;   // 3.5(只要有一个是浮点,就按浮点除)

    // 自增自减
    int i = 5;
    cout << i++ << endl;  // 5(先用再加)
    cout << i << endl;    // 6
    cout << ++i << endl;  // 7(先加再用)
    return 0;
}

注意几个坑:

二、关系运算符

用于比较两个值,返回 bool:

#include <iostream>
using namespace std;

int main() {
    int a = 10, b = 20;

    cout << (a == b) << endl;   // 0 (相等)
    cout << (a != b) << endl;   // 1 (不等)
    cout << (a < b) << endl;    // 1 (小于)
    cout << (a > b) << endl;    // 0 (大于)
    cout << (a <= b) << endl;   // 1 (小于等于)
    cout << (a >= b) << endl;   // 0 (大于等于)

    // 关系运算返回 bool,在 C++ 里 cout 默认显示为 0/1
    // 用 boolalpha 可以让它显示 true/false
    cout << boolalpha << (a < b) << endl;   // true

    // ⚠️ 别把 == 写成 = !(赋值 vs 比较)
    // if (a = 5)  // 这是把 5 赋给 a,然后判断 a(非零即真),bug!
    return 0;
}

新手最大的坑:把 ==(相等比较)写成 =(赋值)。编译器会警告,但代码仍能编译,bug 很难找。建议开 -Wall 让警告变明显。

三、逻辑运算符

用于组合多个条件:

#include <iostream>
using namespace std;

int main() {
    bool a = true, b = false;

    cout << (a && b) << endl;   // 0  逻辑与(两边都真才真)
    cout << (a || b) << endl;   // 1  逻辑或(一边真即真)
    cout << (!b) << endl;       // 1  逻辑非(取反)

    // 短路求值:&& 第一个为假就不再算第二个;|| 第一个为真就不再算第二个
    int x = 0;
    if (x != 0 && 10/x > 1) {
        // x == 0 时 && 直接短路,不会执行 10/x,避免除零崩溃
        cout << "won't print" << endl;
    }

    // 常见用法:判断范围
    int age = 25;
    if (age >= 18 && age <= 60) {
        cout << "劳动年龄" << endl;
    }
    return 0;
}

四、位运算符

位运算直接操作二进制位,底层编程、性能优化、加密、图形都缺不了:

#include <iostream>
using namespace std;

int main() {
    unsigned char a = 0b1100;   // 12(二进制 1100)
    unsigned char b = 0b1010;   // 10(二进制 1010)

    cout << (int)(a & b) << endl;   // 8  位与 1000
    cout << (int)(a | b) << endl;   // 14 位或 1110
    cout << (int)(a ^ b) << endl;   // 6  位异或 0110(不同为 1)
    cout << (int)(~a) << endl;      // 243 位取反(8 位下)
    cout << (int)(a << 2) << endl;  // 48 位左移 2 位(乘 4)
    cout << (int)(a >> 2) << endl;  // 3  位右移 2 位(除 4)

    // 经典用法:权限标志位(位掩码)
    const int READ = 1;     // 0001
    const int WRITE = 2;    // 0010
    const int EXEC = 4;     // 0100

    int perm = READ | WRITE;          // 0011(可读可写)
    cout << (perm & READ) << endl;    // 1(有读权限)
    cout << (perm & EXEC) << endl;    // 0(无执行权限)
    return 0;
}

位运算的常见用途:

五、赋值运算符

赋值运算符除了基本的 =,还有一系列复合赋值:

#include <iostream>
using namespace std;

int main() {
    int x = 10;
    x += 5;   // 等同 x = x + 5;  现在 x = 15
    x -= 3;   // 等同 x = x - 3;  现在 x = 12
    x *= 2;   // 等同 x = x * 2;  现在 x = 24
    x /= 4;   // 等同 x = x / 4;  现在 x = 6
    x %= 4;   // 等同 x = x % 4;  现在 x = 2

    // 位运算复合赋值
    x <<= 3;  // 等同 x = x << 3; 现在 x = 16
    x &= 0xF; // 等同 x = x & 15;现在 x = 16
    x |= 1;   // 等同 x = x | 1; 现在 x = 17

    cout << x << endl;   // 17

    // 逗号运算符:从左到右计算,结果取最右
    int y = (1, 2, 3);
    cout << y << endl;   // 3
    return 0;
}

复合赋值(+=-=*=...)更简洁,推荐用。

六、三元运算符

三元运算符 ?: 是"短小的 if/else",一行就能搞定简单的二选一:

#include <iostream>
using namespace std;

int main() {
    int a = 10, b = 20;

    // 三元运算符:条件 ? 真值 : 假值
    int max = (a > b) ? a : b;
    cout << max << endl;    // 20

    // 等价于:
    int m;
    if (a > b) {
        m = a;
    } else {
        m = b;
    }

    // 三元可以嵌套,但别太花哨(可读性差)
    int score = 85;
    string grade = (score >= 90) ? "A" :
                   (score >= 80) ? "B" :
                   (score >= 60) ? "C" : "D";
    cout << grade << endl;  // B
    return 0;
}

使用建议:简单二选一用三元,复杂逻辑用 if/else。不要嵌套太深,可读性会断崖式下降。

七、其他常用运算符

#include <iostream>
using namespace std;

int main() {
    // sizeof:返回类型/变量占的字节数
    cout << sizeof(int) << endl;    // 4
    cout << sizeof(double) << endl; // 8

    // 三元 + 条件运算符
    int x = 10;
    cout << (x > 0 ? "positive" : "non-positive") << endl;

    // 逗号运算符
    int a = (1, 2, 3);
    cout << a << endl;   // 3

    // 作用域解析 ::
    int y = 5;
    {
        int y = 10;
        cout << y << endl;       // 10(局部)
        cout << ::y << endl;     // 5(外层)
    }

    // 成员访问:.(对象) ->(指针)
    // 下标:[](数组/容器)
    // 函数调用:() 等
    return 0;
}

八、运算符优先级

C++ 有几十个运算符,优先级不必全背,但要记住几个易错的:

// 优先级从高到低(常用部分):
// 1. ()  []  ->  .  ::              (作用域/成员)
// 2. !  ~  ++  --  + -(正负) * &(解引用/取址) sizeof
// 3. *  /  %                       (算术)
// 4. +  -                          (算术)
// 5. <<  >>                        (移位)
// 6. <  <=  >  >=                  (关系)
// 7. ==  !=                        (关系)
// 8. &  ^  |                       (位运算)
// 9. &&                            (逻辑与)
// 10. ||                           (逻辑或)
// 11. ?:                           (三元)
// 12. =  +=  -=  *=  /= ...        (赋值)
// 13. ,                            (逗号)

// 实战建议:不确定优先级时,直接用括号!可读性最重要。
// a + b * c    => 隐式是 a + (b*c)
// (a + b) * c  => 必须显式加括号

// 经典坑:位运算优先级低于关系运算
// flags & MASK == 0  实际是 flags & (MASK == 0),错误!
// 应写成:(flags & MASK) == 0

实用建议:写代码时,只要不是 100% 确定,就加括号。括号不会让代码变慢,但能让代码意图明确、避免 bug

九、运算符重载(预告)

C++ 独有的强大特性:可以给自定义类型重新定义运算符的含义。比如你定义一个 Vector3(三维向量)类,可以重载 +v1 + v2 做向量加法。这在 C/Java/Python 里都做不到。我们会在类与对象那章详细讲。

小结

这一章你认识了 C++ 的所有常用运算符:算术、关系、逻辑、位、赋值、三元、sizeof 等。记住了几个坑:整数除法、== vs =、位运算优先级低于关系运算。下一篇我们看控制流——怎么让程序"做判断、重复干活"。

← 上一篇 C++ 数据类型

下一篇 C++ 控制流

✈️💬