【C++基础与提高】第四章:运算符与表达式——构建程序逻辑的工具
【C++基础与提高】第四章:运算符与表达式——构建程序逻辑的工具
(持续更新中,欢迎关注!)
文章目录
- 【C++基础与提高】第四章:运算符与表达式——构建程序逻辑的工具
- 4.1 运算符概述——程序逻辑的构建块
- 4.2 算术运算符——数学计算的基础
- 4.2.1 基本算术运算符
- 4.2.2 自增自减运算符
- 4.3 关系运算符——比较数据的工具
- 4.4 逻辑运算符——构建复杂条件
- 4.5 位运算符——底层操作的强大工具
- 4.6 赋值运算符——变量值的更新工具
- 4.7 条件运算符——简洁的三元表达式
- 4.8 运算符优先级与结合性——表达式求值规则
- 4.9 sizeof运算符——查询数据大小
- 4.10 表达式类型与类型转换——隐式与显式转换
- 4.11 现代C++运算符特性——新增便利功能
- 4.12 运算符重载简介——扩展运算符功能
- 4.13 常见陷阱与最佳实践
- 4.14 本章小结
4.1 运算符概述——程序逻辑的构建块
运算符是C++中用于执行特定操作的符号,它们就像数学中的加减乘除一样,是构成程序逻辑的基础工具。每个运算符都有特定的操作数(operands)和返回值。
#include <iostream>int main() {// 运算符示例int a = 10; // 赋值运算符 =int b = 5;int sum = a + b; // 算术运算符 +bool result = a > b; // 关系运算符 >std::cout << "a = " << a << std::endl;std::cout << "b = " << b << std::endl;std::cout << "sum = " << sum << std::endl;std::cout << "a > b ? " << std::boolalpha << result << std::endl;return 0;
}
4.2 算术运算符——数学计算的基础
4.2.1 基本算术运算符
#include <iostream>
#include <iomanip>int main() {int x = 20;int y = 6;std::cout << std::fixed << std::setprecision(2);std::cout << "=== 整数运算 ===" << std::endl;std::cout << "x = " << x << ", y = " << y << std::endl;std::cout << "x + y = " << (x + y) << std::endl; // 加法std::cout << "x - y = " << (x - y) << std::endl; // 减法std::cout << "x * y = " << (x * y) << std::endl; // 乘法std::cout << "x / y = " << (x / y) << std::endl; // 除法(整数除法)std::cout << "x % y = " << (x % y) << std::endl; // 取模(求余数)// 浮点数运算double a = 20.0;double b = 6.0;std::cout << "\n=== 浮点数运算 ===" << std::endl;std::cout << "a = " << a << ", b = " << b << std::endl;std::cout << "a + b = " << (a + b) << std::endl;std::cout << "a - b = " << (a - b) << std::endl;std::cout << "a * b = " << (a * b) << std::endl;std::cout << "a / b = " << (a / b) << std::endl;// std::cout << "a % b = " << (a % b) << std::endl; // 错误!浮点数不能取模return 0;
}
4.2.2 自增自减运算符
#include <iostream>int main() {int a = 10;int b = 10;std::cout << "=== 前置自增 ===" << std::endl;std::cout << "a = " << a << std::endl;std::cout << "++a = " << (++a) << std::endl; // 先自增,再使用std::cout << "a = " << a << std::endl;std::cout << "\n=== 后置自增 ===" << std::endl;std::cout << "b = " << b << std::endl;std::cout << "b++ = " << (b++) << std::endl; // 先使用,再自增std::cout << "b = " << b << std::endl;// 自减运算符int c = 10;int d = 10;std::cout << "\n=== 自减运算符 ===" << std::endl;std::cout << "--c = " << (--c) << std::endl; // 前置自减std::cout << "d-- = " << (d--) << std::endl; // 后置自减std::cout << "最终 c = " << c << ", d = " << d << std::endl;// 实际应用场景std::cout << "\n=== 实际应用 ===" << std::endl;int counter = 0;// 在循环中的应用while(counter < 3) {std::cout << "第" << (++counter) << "次循环" << std::endl;}return 0;
}
4.3 关系运算符——比较数据的工具
#include <iostream>int main() {int x = 10;int y = 20;std::cout << std::boolalpha; // 以true/false形式输出布尔值std::cout << "x = " << x << ", y = " << y << std::endl;std::cout << "========================" << std::endl;// 相等性比较std::cout << "x == y : " << (x == y) << std::endl; // 等于std::cout << "x != y : " << (x != y) << std::endl; // 不等于// 大小比较std::cout << "x > y : " << (x > y) << std::endl; // 大于std::cout << "x < y : " << (x < y) << std::endl; // 小于std::cout << "x >= y : " << (x >= y) << std::endl; // 大于等于std::cout << "x <= y : " << (x <= y) << std::endl; // 小于等于// 字符串比较std::string str1 = "apple";std::string str2 = "banana";std::cout << "\n字符串比较:" << std::endl;std::cout << "str1 = \"" << str1 << "\", str2 = \"" << str2 << "\"" << std::endl;std::cout << "str1 == str2 : " << (str1 == str2) << std::endl;std::cout << "str1 < str2 : " << (str1 < str2) << std::endl;std::cout << "str1 > str2 : " << (str1 > str2) << std::endl;return 0;
}
4.4 逻辑运算符——构建复杂条件
#include <iostream>int main() {bool a = true;bool b = false;std::cout << std::boolalpha;std::cout << "a = " << a << ", b = " << b << std::endl;std::cout << "========================" << std::endl;// 基本逻辑运算std::cout << "a && b : " << (a && b) << std::endl; // 逻辑与(AND)std::cout << "a || b : " << (a || b) << std::endl; // 逻辑或(OR)std::cout << "!a : " << (!a) << std::endl; // 逻辑非(NOT)// 短路求值演示std::cout << "\n=== 短路求值演示 ===" << std::endl;int x = 5;int y = 0;// 逻辑与短路:如果第一个条件为false,则不会检查第二个条件if(y != 0 && x/y > 1) {std::cout << "条件成立" << std::endl;} else {std::cout << "由于短路求值,避免了除零错误" << std::endl;}// 逻辑或短路:如果第一个条件为true,则不会检查第二个条件if(x > 0 || ++y > 0) { // ++y不会被执行std::cout << "条件成立,y = " << y << std::endl;}// 实际应用示例std::cout << "\n=== 实际应用示例 ===" << std::endl;int age = 25;bool has_license = true;bool is_drunk = false;// 判断是否可以合法驾驶if(age >= 18 && has_license && !is_drunk) {std::cout << "可以合法驾驶" << std::endl;} else {std::cout << "不可以驾驶" << std::endl;}return 0;
}
4.5 位运算符——底层操作的强大工具
#include <iostream>
#include <bitset> // 用于显示二进制表示int main() {unsigned int a = 12; // 二进制: 1100unsigned int b = 10; // 二进制: 1010std::cout << "a = " << a << " (" << std::bitset<8>(a) << ")" << std::endl;std::cout << "b = " << b << " (" << std::bitset<8>(b) << ")" << std::endl;std::cout << "========================" << std::endl;// 位运算操作std::cout << "a & b : " << (a & b) << " (" << std::bitset<8>(a & b) << ")" << std::endl; // 按位与std::cout << "a | b : " << (a | b) << " (" << std::bitset<8>(a | b) << ")" << std::endl; // 按位或std::cout << "a ^ b : " << (a ^ b) << " (" << std::bitset<8>(a ^ b) << ")" << std::endl; // 按位异或std::cout << "~a : " << (~a) << " (" << std::bitset<8>(~a) << ")" << std::endl; // 按位取反// 位移运算std::cout << "\n=== 位移运算 ===" << std::endl;std::cout << "a << 1 : " << (a << 1) << " (" << std::bitset<8>(a << 1) << ")" << std::endl; // 左移std::cout << "a >> 1 : " << (a >> 1) << " (" << std::bitset<8>(a >> 1) << ")" << std::endl; // 右移// 实际应用:标志位操作std::cout << "\n=== 标志位操作示例 ===" << std::endl;enum Flags {READ = 1, // 0001WRITE = 2, // 0010EXECUTE = 4 // 0100};int permissions = READ | WRITE; // 设置读写权限 0011std::cout << "初始权限: " << std::bitset<4>(permissions) << std::endl;// 添加执行权限permissions |= EXECUTE;std::cout << "添加执行权限后: " << std::bitset<4>(permissions) << std::endl;// 检查是否有写权限if(permissions & WRITE) {std::cout << "具有写权限" << std::endl;}// 移除写权限permissions &= ~WRITE;std::cout << "移除写权限后: " << std::bitset<4>(permissions) << std::endl;return 0;
}
4.6 赋值运算符——变量值的更新工具
#include <iostream>int main() {int a = 10;int b = 5;std::cout << "初始值: a = " << a << ", b = " << b << std::endl;std::cout << "========================" << std::endl;// 基本赋值运算符a = b;std::cout << "a = b 后: a = " << a << std::endl;// 复合赋值运算符a += 10; // 等价于 a = a + 10std::cout << "a += 10后: a = " << a << std::endl;a -= 3; // 等价于 a = a - 3std::cout << "a -= 3 后: a = " << a << std::endl;a *= 2; // 等价于 a = a * 2std::cout << "a *= 2 后: a = " << a << std::endl;a /= 4; // 等价于 a = a / 4std::cout << "a /= 4 后: a = " << a << std::endl;a %= 3; // 等价于 a = a % 3std::cout << "a %= 3 后: a = " << a << std::endl;// 位运算赋值a <<= 1; // 等价于 a = a << 1std::cout << "a <<= 1后: a = " << a << std::endl;a >>= 1; // 等价于 a = a >> 1std::cout << "a >>= 1后: a = " << a << std::endl;a &= 3; // 等价于 a = a & 3std::cout << "a &= 3 后: a = " << a << std::endl;a |= 4; // 等价于 a = a | 4std::cout << "a |= 4 后: a = " << a << std::endl;a ^= 2; // 等价于 a = a ^ 2std::cout << "a ^= 2 后: a = " << a << std::endl;return 0;
}
4.7 条件运算符——简洁的三元表达式
#include <iostream>int main() {int a = 10;int b = 20;// 条件运算符(三元运算符)int max = (a > b) ? a : b;std::cout << "较大值: " << max << std::endl;// 嵌套条件运算符int x = 15;std::string result = (x > 0) ? ((x % 2 == 0) ? "正偶数" : "正奇数") : "非正数";std::cout << x << " 是 " << result << std::endl;// 实际应用示例std::cout << "\n=== 实际应用示例 ===" << std::endl;// 成绩等级判定int score = 85;char grade = (score >= 90) ? 'A' :(score >= 80) ? 'B' :(score >= 70) ? 'C' :(score >= 60) ? 'D' : 'F';std::cout << "分数: " << score << ", 等级: " << grade << std::endl;// 数字绝对值int number = -25;int absolute = (number >= 0) ? number : -number;std::cout << "数字: " << number << ", 绝对值: " << absolute << std::endl;return 0;
}
4.8 运算符优先级与结合性——表达式求值规则
#include <iostream>int main() {// 运算符优先级示例int a = 5, b = 3, c = 2;std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;std::cout << "========================" << std::endl;// 乘法优先级高于加法int result1 = a + b * c; // 5 + 3 * 2 = 5 + 6 = 11int result2 = (a + b) * c; // (5 + 3) * 2 = 8 * 2 = 16std::cout << "a + b * c = " << result1 << std::endl;std::cout << "(a + b) * c = " << result2 << std::endl;// 关系运算符优先级低于算术运算符bool result3 = a + b > c * 2; // 8 > 4 = truebool result4 = a > b && b > c; // (5 > 3) && (3 > 2) = true && true = truestd::cout << "a + b > c * 2 = " << std::boolalpha << result3 << std::endl;std::cout << "a > b && b > c = " << result4 << std::endl;// 赋值运算符优先级最低int x, y, z;x = y = z = 10; // 从右到左结合:x = (y = (z = 10))std::cout << "x = " << x << ", y = " << y << ", z = " << z << std::endl;// 复杂表达式示例int expr_result = a + b * c - (a - b) / 2;// 计算步骤:// 1. b * c = 3 * 2 = 6// 2. (a - b) = (5 - 3) = 2// 3. (a - b) / 2 = 2 / 2 = 1// 4. a + b * c = 5 + 6 = 11// 5. a + b * c - (a - b) / 2 = 11 - 1 = 10std::cout << "a + b * c - (a - b) / 2 = " << expr_result << std::endl;return 0;
}
4.9 sizeof运算符——查询数据大小
#include <iostream>int main() {// sizeof运算符用于查询数据类型或变量占用的字节数std::cout << "=== 基本数据类型大小 ===" << std::endl;std::cout << "char: " << sizeof(char) << " 字节" << std::endl;std::cout << "int: " << sizeof(int) << " 字节" << std::endl;std::cout << "float: " << sizeof(float) << " 字节" << std::endl;std::cout << "double: " << sizeof(double) << " 字节" << std::endl;std::cout << "bool: " << sizeof(bool) << " 字节" << std::endl;std::cout << "\n=== 修饰符类型大小 ===" << std::endl;std::cout << "short int: " << sizeof(short int) << " 字节" << std::endl;std::cout << "long int: " << sizeof(long int) << " 字节" << std::endl;std::cout << "long long int: " << sizeof(long long int) << " 字节" << std::endl;// 对变量使用sizeofint x = 100;double y = 3.14;std::cout << "\n=== 对变量使用sizeof ===" << std::endl;std::cout << "变量x的大小: " << sizeof(x) << " 字节" << std::endl;std::cout << "变量y的大小: " << sizeof(y) << " 字节" << std::endl;// 对数组使用sizeofint arr[10];std::cout << "\n=== 对数组使用sizeof ===" << std::endl;std::cout << "数组arr的总大小: " << sizeof(arr) << " 字节" << std::endl;std::cout << "数组元素个数: " << sizeof(arr)/sizeof(arr[0]) << std::endl;return 0;
}
4.10 表达式类型与类型转换——隐式与显式转换
#include <iostream>int main() {// 整数运算int a = 10;int b = 3;int int_result = a / b; // 整数除法double double_result = static_cast<double>(a) / b; // 强制类型转换std::cout << "整数除法: " << a << " / " << b << " = " << int_result << std::endl;std::cout << "浮点除法: " << a << " / " << b << " = " << double_result << std::endl;// 混合类型运算中的隐式转换int x = 5;double y = 2.5;auto result = x + y; // int自动转换为doublestd::cout << "\n混合类型运算:" << std::endl;std::cout << "x = " << x << " (int)" << std::endl;std::cout << "y = " << y << " (double)" << std::endl;std::cout << "x + y = " << result << " (" << typeid(result).name() << ")" << std::endl;// 布尔类型在算术运算中的转换bool flag1 = true;bool flag2 = false;int bool_sum = flag1 + flag2;std::cout << "\n布尔类型运算:" << std::endl;std::cout << "flag1 = " << flag1 << std::endl;std::cout << "flag2 = " << flag2 << std::endl;std::cout << "flag1 + flag2 = " << bool_sum << std::endl;return 0;
}
4.11 现代C++运算符特性——新增便利功能
#include <iostream>
#include <vector>int main() {// 范围for循环(C++11)std::vector<int> numbers = {1, 2, 3, 4, 5};std::cout << "传统循环: ";for(size_t i = 0; i < numbers.size(); ++i) {std::cout << numbers[i] << " ";}std::cout << std::endl;std::cout << "范围for循环: ";for(const auto& num : numbers) {std::cout << num << " ";}std::cout << std::endl;// nullptr(C++11)int* ptr1 = nullptr; // 推荐使用int* ptr2 = NULL; // 传统方式std::cout << "\n空指针比较:" << std::endl;std::cout << "ptr1 == nullptr: " << (ptr1 == nullptr) << std::endl;// Lambda表达式中的捕获(C++11)int multiplier = 10;auto lambda = [multiplier](int x) { return x * multiplier; };std::cout << "\nLambda表达式:" << std::endl;std::cout << "5 * " << multiplier << " = " << lambda(5) << std::endl;return 0;
}
4.12 运算符重载简介——扩展运算符功能
#include <iostream>class Complex {
private:double real;double imag;public:Complex(double r = 0, double i = 0) : real(r), imag(i) {}// 重载+运算符Complex operator+(const Complex& other) const {return Complex(real + other.real, imag + other.imag);}// 重载<<运算符(友元函数)friend std::ostream& operator<<(std::ostream& os, const Complex& c) {os << c.real << " + " << c.imag << "i";return os;}// 重载==运算符bool operator==(const Complex& other) const {return (real == other.real) && (imag == other.imag);}
};int main() {Complex c1(3, 4);Complex c2(1, 2);Complex c3 = c1 + c2; // 使用重载的+运算符std::cout << "c1 = " << c1 << std::endl;std::cout << "c2 = " << c2 << std::endl;std::cout << "c1 + c2 = " << c3 << std::endl;if(c1 == c2) {std::cout << "c1 和 c2 相等" << std::endl;} else {std::cout << "c1 和 c2 不相等" << std::endl;}return 0;
}
4.13 常见陷阱与最佳实践
#include <iostream>int main() {// 1. 赋值运算符vs相等运算符int a = 5;int b = 10;// 常见错误:使用=而不是==if(a = b) { // 这会将b的值赋给a,然后判断a是否非零std::cout << "警告:这可能是错误的!a现在是" << a << std::endl;}// 正确写法a = 5; // 先恢复a的值if(a == b) {std::cout << "a等于b" << std::endl;} else {std::cout << "a不等于b" << std::endl;}// 2. 浮点数比较double x = 0.1 + 0.2;double y = 0.3;std::cout << "\n浮点数比较:" << std::endl;std::cout << "0.1 + 0.2 = " << x << std::endl;std::cout << "0.3 = " << y << std::endl;// 错误的比较方式if(x == y) {std::cout << "x等于y" << std::endl;} else {std::cout << "x不等于y(由于浮点精度问题)" << std::endl;}// 正确的比较方式const double epsilon = 1e-9;if(std::abs(x - y) < epsilon) {std::cout << "x近似等于y" << std::endl;}// 3. 自增运算符的使用std::cout << "\n自增运算符:" << std::endl;int arr[] = {1, 2, 3, 4, 5};int* ptr = arr;std::cout << "*ptr++ = " << *ptr++ << std::endl; // 先取值,再移动指针std::cout << "*ptr = " << *ptr << std::endl; // 现在指向第二个元素return 0;
}
4.14 本章小结
本章全面介绍了C++中的运算符和表达式:
- 算术运算符:+、-、*、/、% 以及自增自减运算符
- 关系运算符:==、!=、>、<、>=、<=
- 逻辑运算符:&&、||、! 及其短路特性
- 位运算符:&、|、^、~、<<、>> 用于底层操作
- 赋值运算符:= 以及复合赋值运算符
- 条件运算符:? : 提供简洁的条件表达式
- 运算符优先级:决定了表达式的求值顺序
- 现代C++特性:范围for循环、nullptr等新增功能
掌握这些运算符及其使用规则对于编写高效、准确的C++程序至关重要。运算符是构建程序逻辑的基础工具,熟练运用它们能够使代码更加简洁和高效。
专栏预告:第五章将深入探讨程序流程控制,包括条件语句(if/else、switch)和循环语句(for、while、do-while),帮助读者掌握程序执行流程的控制技巧。
