导言

运算符是编程语言中用于执行特定操作的符号或关键字。在C++中,运算符的使用广泛且多样,掌握运算符的使用对于编写高效、简洁的代码至关重要。本教案旨在全面介绍C++中的各种运算符,帮助学习者深入理解和灵活运用。

运算符概述

运算符(Operator) 是用来对变量进行操作的符号或函数。C++中的运算符可分为多种类型,每种运算符具有特定的功能和使用规则。运算符可以单目(仅操作一个操作数)、双目(操作两个操作数)、甚至三目(操作三个操作数)等。

运算符分类

C++中的运算符可以根据功能和使用方式分为以下几类:

1. 算术运算符

用于执行基本的数学计算。

运算符 描述 示例
+ 加法 a + b
- 减法 a - b
* 乘法 a * b
/ 除法 a / b
% 取模(求余数) a % b
++ 自增(前缀/后缀) ++a, a++
-- 自减(前缀/后缀) --a, a--

示例:

int a = 10, b = 3;
int sum = a + b;    // 13
int diff = a - b;   // 7
int prod = a * b;   // 30
int div = a / b;    // 3
int mod = a % b;    // 1
a++;                // a = 11
--b;                // b = 2

2. 关系运算符

用于比较两个值之间的关系,返回布尔值(truefalse)。

运算符 描述 示例
== 等于 a == b
!= 不等于 a != b
> 大于 a > b
< 小于 a < b
>= 大于或等于 a >= b
<= 小于或等于 a <= b

示例:

int a = 5, b = 10;
bool result1 = (a == b); // false
bool result2 = (a < b);  // true
bool result3 = (a >= b); // false

3. 逻辑运算符

用于组合或反转布尔表达式,返回布尔值。

运算符 描述 示例
&& 逻辑与(AND) a && b
` ` 逻辑或 (OR) `a b`
! 逻辑非(NOT) !a

示例:

bool a = true, b = false;
bool result1 = a && b; // false
bool result2 = a || b; // true
bool result3 = !a;     // false

4. 位运算符

用于按位操作整数类型的二进制位。

运算符 描述 示例
& 按位与 a & b
` ` 按位或 `a b`
^ 按位异或(不等时为1) a ^ b
~ 按位取反 ~a
<< 左移 a << 2
>> 右移 a >> 2

示例:

int a = 5;  // 二进制:0101
int b = 3;  // 二进制:0011
int andResult = a & b; // 1 (0001)
int orResult = a | b;  // 7 (0111)
int xorResult = a ^ b; // 6 (0110)
int notResult = ~a;    // -6 (补码)
int leftShift = a << 1; // 10 (1010)
int rightShift = a >> 1; // 2 (0010)

5. 赋值运算符

用于向变量赋值。

运算符 描述 示例
= 简单赋值 a = b
+= 加后赋值 a += b
-= 减后赋值 a -= b
*= 乘后赋值 a *= b
/= 除后赋值 a /= b
%= 取模后赋值 a %= b
&= 按位与后赋值 a &= b
` =` 按位或后赋值 `a = b`
^= 按位异或后赋值 a ^= b
<<= 左移后赋值 a <<= 2
>>= 右移后赋值 a >>= 2

示例:

int a = 5;
int b = 3;
a += b; // a = 8
a *= 2; // a = 16
a &= b; // a = 16 & 3 = 0

6. 复合赋值运算符

结合赋值与其他运算的运算符(如上表中所示的+=, -=, 等)。

示例:

int a = 10;
a += 5; // 等同于 a = a + 5; 结果 a = 15

7. 条件运算符

用于基于条件选择值。

运算符 描述 示例
?: 条件(三目)运算符 a ? b : c

示例:

int a = 10, b = 20, c;
c = (a > b) ? a : b; // c = 20

8. 递增和递减运算符

用于增加或减少变量的值,前缀和后缀形式。

运算符 描述 示例
++ 自增(前缀/后缀) ++a, a++
-- 自减(前缀/后缀) --a, a--

示例:

int a = 5;
int b = ++a; // a = 6, b = 6
int c = a--; // a = 5, c = 6

9. 指针运算符

用于操作指针。

运算符 描述 示例
* 间接访问(解引用) *ptr
& 取地址 &a
-> 成员访问(指向对象的指针) ptr->member
[] 数组下标访问 arr[2]

示例:

int a = 10;
int *ptr = &a;
int value = *ptr; // value = 10

10. 成员访问运算符

用于访问类或结构体的成员。

运算符 描述 示例
. 直接成员访问 object.member
-> 指向成员的指针访问 ptr->member
::* 指向成员的指针(成员指针操作符) Class::*ptr

示例:

struct Point {
    int x;
    int y;
};

Point p = {10, 20};
Point *ptr = &p;
int a = p.x;      // 使用 . 运算符
int b = ptr->y;  // 使用 -> 运算符

11. 其他运算符

运算符 描述 示例
sizeof 返回变量或类型所占字节数 sizeof(int)
?: 条件(三目)运算符 a ? b : c
, 逗号运算符 a = (b, c)
typeid 运行时类型信息运算符 typeid(a)
new 动态内存分配 int *ptr = new int;
delete 动态内存释放 delete ptr;

示例:

int a = 5;
int size = sizeof(a); // size = 4 (通常)
int b, c;
b = (a++, a + 2); // a = 6, b = 8

运算符优先级与结合性

运算符的优先级决定了在没有括号明确指定的情况下,哪一个运算符先被计算。结合性则决定了运算符在具有相同优先级时的计算顺序(从左到右或从右到左)。

优先级表

以下是C++运算符的优先级从高到低的简要概览:

优先级 运算符类别 运算符 结合性 备注
1 范围解析运算符 :: 左到右 用于访问命名空间或类的成员
2 后缀运算符 (), [], ., ->, ++(后置), --(后置) 左到右 包含函数调用、数组下标、成员访问
3 一元运算符 +, -, !, ~, ++(前置), --(前置), *(解引用), &(取地址), sizeof, typeid 右到左 适用于单个操作数的运算符
4 乘法运算符 *, /, % 左到右 乘法、除法和取模运算
5 加法运算符 +, - 左到右 加法和减法运算
6 移位运算符 <<, >> 左到右 位左移和位右移
7 关系运算符 <, <=, >, >= 左到右 比较运算符
8 相等运算符 ==, != 左到右 判断相等与不相等
9 位与运算符 & 左到右 按位与
10 位异或运算符 ^ 左到右 按位异或
11 位或运算符 ` ` 左到右
12 逻辑与运算符 && 左到右 逻辑与
13 逻辑或运算符 ` `
14 条件运算符 ?: 右到左 条件(三目)运算符
15 赋值运算符 =, +=, -=, *=, /=, %=, &=, ` =,^=,<<=,>>=` 右到左
16 逗号运算符 , 左到右 逗号用于表达式中多个操作

表格说明

  • 优先级:数字越小,优先级越高。即优先级为1的运算符最先被计算。
  • 运算符类别:运算符的功能分类,帮助理解不同类型运算符的用途。
  • 运算符:具体的C++运算符符号。
  • 结合性:当表达式中出现多个相同优先级的运算符时,决定运算顺序的规则。左到右表示从左侧的操作数开始,右到左表示从右侧的操作数开始。
  • 备注:对运算符类别或特定运算符的简要说明。

运算符重载

运算符重载(Operator Overloading) 允许开发者为自定义类型(如类和结构体)定义或改变运算符的行为,使其表现得像内置类型一样。这提高了代码的可读性和可维护性。

运算符重载的规则

  1. 可重载运算符:几乎所有的运算符都可以被重载,但如 ::, ?:, sizeof 等运算符不能被重载。
  2. 至少一个操作数必须是用户定义类型:即至少有一个操作数是类、结构体或联合体类型。
  3. 运算符重载不改变运算符的优先级、结合性和操作数数量

运算符重载的基本语法

运算符可以作为成员函数或友元函数进行重载。

成员函数重载示例:

class Complex {
public:
    double real, imag;

    Complex operator+(const Complex &c) {
        Complex temp;
        temp.real = real + c.real;
        temp.imag = imag + c.imag;
        return temp;
    }
};

友元函数重载示例:

class Complex {
public:
    double real, imag;

    friend Complex operator+(const Complex &c1, const Complex &c2);
};

Complex operator+(const Complex &c1, const Complex &c2) {
    Complex temp;
    temp.real = c1.real + c2.real;
    temp.imag = c1.imag + c2.imag;
    return temp;
}

常见的重载运算符

  • 算术运算符+, -, *, /, %
  • 关系运算符==, !=, <, >, <=, >=
  • 逻辑运算符&&, ||, !
  • 赋值运算符=, +=, -=, *=, /=
  • 输入输出运算符<<, >>
  • 索引运算符[]
  • 函数调用运算符()

示例:

#include <iostream>
using namespace std;

class Complex {
public:
    double real, imag;

    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载 + 运算符
    Complex operator+(const Complex &c) {
        return Complex(real + c.real, imag + c.imag);
    }

    // 重载 << 运算符(作为友元函数)
    friend ostream& operator<<(ostream &out, const Complex &c);
};

ostream& operator<<(ostream &out, const Complex &c) {
    out << c.real << " + " << c.imag << "i";
    return out;
}

int main() {
    Complex c1(1.2, 3.4);
    Complex c2(5.6, 7.8);
    Complex c3 = c1 + c2;
    cout << "c1 + c2 = " << c3 << endl; // 输出: c1 + c2 = 6.8 + 11.2i
    return 0;
}

练习题

1 交换两个数

题目: 使用位运算符,交换两个整数变量的值而不使用第三个变量。

答案:

#include <iostream>
int main() {
    int x = 15;
    int y = 27;

    std::cout << "Before swap: x = " << x << ", y = " << y << std::endl;

    // 交换操作
    x = x ^ y;
    y = x ^ y;
    x = x ^ y;

    std::cout << "After swap: x = " << x << ", y = " << y << std::endl;

    return 0;
}

预期输出:

Before swap: x = 15, y = 27
After swap: x = 27, y = 15

解析: 通过异或运算 ^ 完成变量值的交换,无需使用临时变量。

2 函数修改外部变量

题目: 编写一个函数,接受一个整数指针,使用解引用运算符修改其值为原值的平方。

答案:

#include <iostream>
void square(int* ptr) {
    *ptr = (*ptr) * (*ptr);
}

int main() {
    int num = 5;
    std::cout << "Before: " << num << std::endl;
    square(&num);
    std::cout << "After: " << num << std::endl;
    return 0;
}

预期输出:

Before: 5
After: 25

解析: 通过指针访问并修改原变量的值。

3 计算范围内所有元素的和

题目: 编写一个函数,接受 std::vector<int> 的迭代器范围,计算并返回范围内所有元素的和。

函数示例:

须实现如下函数,返回范围内元素求和的结果

int sumRange(std::vector<int>::iterator start, std::vector<int>::iterator end);

答案:

#include <iostream>
#include <vector>

int sumRange(std::vector<int>::iterator start, std::vector<int>::iterator end) {
    int sum = 0;
    while (start != end) {
        sum += *start;
        ++start;
    }
    return sum;
}

int main() {
    std::vector<int> numbers = {2, 4, 6, 8, 10};
    int total = sumRange(numbers.begin(), numbers.end());
    std::cout << "Sum: " << total << std::endl;
    return 0;
}

预期输出:

Sum: 30

解析: 函数通过迭代器遍历范围,累加元素值。

results matching ""

    No results matching ""