面试题答案
一键面试1. 矩阵类 Matrix 的运算符重载实现
#include <iostream>
#include <vector>
class Matrix {
private:
std::vector<std::vector<int>> data;
int rows;
int cols;
public:
Matrix(int r, int c) : rows(r), cols(c) {
data.resize(rows, std::vector<int>(cols, 0));
}
// 获取矩阵元素
int get(int i, int j) const {
return data[i][j];
}
// 设置矩阵元素
void set(int i, int j, int value) {
data[i][j] = value;
}
// 矩阵加法运算符重载
Matrix operator+(const Matrix& other) const {
if (rows != other.rows || cols != other.cols) {
throw std::invalid_argument("Matrices must have the same dimensions for addition.");
}
Matrix result(rows, cols);
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
result.set(i, j, data[i][j] + other.data[i][j]);
}
}
return result;
}
// 矩阵乘法运算符重载
Matrix operator*(const Matrix& other) const {
if (cols != other.rows) {
throw std::invalid_argument("Number of columns in the first matrix must be equal to the number of rows in the second matrix for multiplication.");
}
Matrix result(rows, other.cols);
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < other.cols; ++j) {
int sum = 0;
for (int k = 0; k < cols; ++k) {
sum += data[i][k] * other.data[k][j];
}
result.set(i, j, sum);
}
}
return result;
}
// 打印矩阵
void print() const {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << data[i][j] << " ";
}
std::cout << std::endl;
}
}
};
2. 说明运算符重载提升代码可读性
使用运算符重载后,矩阵的加法和乘法操作变得更加直观。例如:
int main() {
Matrix a(2, 2);
a.set(0, 0, 1);
a.set(0, 1, 2);
a.set(1, 0, 3);
a.set(1, 1, 4);
Matrix b(2, 2);
b.set(0, 0, 5);
b.set(0, 1, 6);
b.set(1, 0, 7);
b.set(1, 1, 8);
Matrix sum = a + b;
Matrix product = a * b;
std::cout << "Sum of matrices:" << std::endl;
sum.print();
std::cout << "Product of matrices:" << std::endl;
product.print();
return 0;
}
在上述代码中,a + b
和 a * b
这样的表达式直接明了,就像我们在数学中书写矩阵运算一样,大大提升了代码的可读性。相比不使用运算符重载,使用单独的函数如 addMatrices(a, b)
和 multiplyMatrices(a, b)
,运算符重载的方式更加简洁和直观。
3. 处理运算符优先级和结合性对代码可读性的影响
-
优先级:在 C++ 中,乘法运算符
*
的优先级高于加法运算符+
,这与数学中的运算优先级一致。例如,表达式a * b + c
会先计算a * b
,再将结果与c
相加。这种默认的优先级规则在矩阵运算中同样适用,符合我们对数学运算优先级的理解,因此不需要额外处理就可以保证代码的可读性。 -
结合性:加法和乘法运算符都是左结合性,即
a + b + c
会被解析为(a + b) + c
,a * b * c
会被解析为(a * b) * c
。在矩阵运算中,这种结合性也符合我们对数学运算的习惯,不会对代码可读性造成负面影响。
但是,如果表达式中同时包含多种运算符且优先级和结合性较为复杂时,为了确保代码的可读性和正确性,可以使用括号明确运算顺序。例如,(a + b) * c
这样可以清楚地表明先进行加法运算,再进行乘法运算。这样即使在复杂的表达式中,也能让阅读代码的人清楚了解运算的先后顺序。