C++赋值运算符 #

一、基本赋值运算符 #

1.1 基本用法 #

cpp
// 基本赋值
int x = 10;
double d = 3.14;
char c = 'A';

1.2 赋值表达式 #

赋值运算符返回左值的引用。

cpp
int x;
int y = (x = 10);  // x = 10, y = 10

// 链式赋值
int a, b, c;
a = b = c = 0;  // 从右向左赋值

1.3 赋值与初始化 #

cpp
// 初始化
int x = 10;  // 调用拷贝构造函数

// 赋值
int y;
y = 10;  // 调用赋值运算符

二、复合赋值运算符 #

2.1 运算符列表 #

运算符 等价形式 示例
+= a = a + b x += 5
-= a = a - b x -= 5
*= a = a * b x *= 5
/= a = a / b x /= 5
%= a = a % b x %= 5
&= a = a & b x &= 5
|= a = a | b x |= 5
^= a = a ^ b x ^= 5
<<= a = a << b x <<= 2
>>= a = a >> b x >>= 2

2.2 基本使用 #

cpp
int x = 10;

x += 5;   // x = 15
x -= 3;   // x = 12
x *= 2;   // x = 24
x /= 4;   // x = 6
x %= 4;   // x = 2

2.3 位运算复合赋值 #

cpp
int flags = 0b1010;

flags |= 0b0101;  // flags = 0b1111 (15)
flags &= 0b1100;  // flags = 0b1100 (12)
flags ^= 0b1000;  // flags = 0b0100 (4)
flags <<= 2;      // flags = 0b10000 (16)
flags >>= 1;      // flags = 0b01000 (8)

三、复合赋值 vs 普通赋值 #

3.1 效率差异 #

cpp
// 复合赋值:更高效
array[index] += value;  // 只计算一次array[index]

// 普通赋值:可能计算两次
array[index] = array[index] + value;  // array[index]计算两次

3.2 复杂表达式 #

cpp
// 复合赋值更清晰
getValue().data[index] += 1;

// 普通赋值冗长
getValue().data[index] = getValue().data[index] + 1;

四、自增自减与赋值 #

4.1 与复合赋值的区别 #

cpp
int x = 5;

// 自增:只能加1
x++;  // x = 6

// 复合赋值:可以加任意值
x += 5;  // x = 11

4.2 使用场景 #

cpp
// 自增:循环计数
for (int i = 0; i < 10; i++) {
    // ...
}

// 复合赋值:累加
int sum = 0;
for (int i = 1; i <= 10; i++) {
    sum += i;  // 累加
}

五、赋值运算符优先级 #

5.1 优先级很低 #

cpp
// 赋值运算符优先级很低,几乎最后执行
int x = 5 + 3 * 2;  // x = 11

// 赋值在条件表达式中
int y;
if ((y = getValue()) > 0) {  // 先赋值,再比较
    // ...
}

5.2 结合性 #

cpp
// 赋值运算符从右向左结合
int a, b, c;
a = b = c = 10;  // c = 10, b = c, a = b

5.3 注意事项 #

cpp
// 危险:赋值在条件中
int x;
if (x = 5) {  // x被赋值为5,条件为true
    // ...
}

// 正确:使用比较
if (x == 5) {
    // ...
}

// 或者使用括号强调
if ((x = getValue()) != 0) {
    // ...
}

六、赋值与类型转换 #

6.1 隐式类型转换 #

cpp
double d = 3.14;
int i = d;  // 隐式转换,i = 3

// 复合赋值也会转换
int x = 10;
x += 3.5;  // x = 13(3.5被截断为3)

6.2 窄化转换警告 #

cpp
double d = 3.14;

// 可能警告
int i = d;

// 显式转换消除警告
int i = static_cast<int>(d);

七、自定义赋值运算符 #

7.1 拷贝赋值运算符 #

cpp
class String {
private:
    char* data;
    size_t length;
    
public:
    // 拷贝赋值运算符
    String& operator=(const String& other) {
        if (this != &other) {  // 自赋值检查
            delete[] data;
            length = other.length;
            data = new char[length + 1];
            strcpy(data, other.data);
        }
        return *this;
    }
};

7.2 移动赋值运算符(C++11) #

cpp
class String {
public:
    // 移动赋值运算符
    String& operator=(String&& other) noexcept {
        if (this != &other) {
            delete[] data;
            data = other.data;
            length = other.length;
            other.data = nullptr;
            other.length = 0;
        }
        return *this;
    }
};

7.3 复合赋值运算符 #

cpp
class Complex {
public:
    double real, imag;
    
    Complex& operator+=(const Complex& other) {
        real += other.real;
        imag += other.imag;
        return *this;
    }
    
    Complex& operator-=(const Complex& other) {
        real -= other.real;
        imag -= other.imag;
        return *this;
    }
};

八、实际应用 #

8.1 累加器 #

cpp
int sum = 0;
int product = 1;

for (int i = 1; i <= 10; i++) {
    sum += i;       // 累加
    product *= i;   // 累乘
}

8.2 标志操作 #

cpp
int flags = 0;

// 设置标志
flags |= FLAG_A;
flags |= FLAG_B;

// 清除标志
flags &= ~FLAG_A;

// 切换标志
flags ^= FLAG_C;

8.3 字符串拼接 #

cpp
#include <string>

std::string result = "Hello";
result += ", ";
result += "World";
result += "!";  // "Hello, World!"

8.4 容器操作 #

cpp
#include <vector>

std::vector<int> vec;
vec = {1, 2, 3};  // 赋值

std::vector<int> vec2;
vec2 = std::move(vec);  // 移动赋值

九、最佳实践 #

9.1 优先使用复合赋值 #

cpp
// 推荐
x += 1;
arr[i] *= 2;

// 不推荐
x = x + 1;
arr[i] = arr[i] * 2;

9.2 注意赋值与比较的区别 #

cpp
// 错误
if (x = 5) { }

// 正确
if (x == 5) { }

// 如果确实需要赋值后判断
if ((x = getValue()) > 0) { }

9.3 避免自赋值 #

cpp
class MyClass {
public:
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {  // 检查自赋值
            // 执行赋值操作
        }
        return *this;
    }
};

9.4 使用移动语义 #

cpp
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2;

// 移动赋值,避免拷贝
vec2 = std::move(vec1);

十、总结 #

赋值运算符一览 #

运算符 说明 示例
= 赋值 x = 10
+= 加赋值 x += 5
-= 减赋值 x -= 5
*= 乘赋值 x *= 5
/= 除赋值 x /= 5
%= 取余赋值 x %= 5
&= 位与赋值 x &= 5
|= 位或赋值 x |= 5
^= 异或赋值 x ^= 5
<<= 左移赋值 x <<= 2
>>= 右移赋值 x >>= 2

注意事项 #

  1. 区分 ===
  2. 优先使用复合赋值
  3. 注意自赋值问题
  4. 理解赋值表达式的返回值
  5. 注意类型转换

下一步,让我们学习运算符优先级!

最后更新:2026-03-26