继续我们在 cmets 中的讨论,您在读取和存储 A 和 B 时面临的最大问题是混乱的混合或用户界面和代码实现。 (接口是您与用户交互的方式,实现是程序的其余部分)您希望将接口和实现分开。
无论您是在用户输入选项的终端中显示文本菜单,还是在选择旁边带有复选框的窗口中显示您的程序选择,您的界面只会将选择返回给您程序来处理。将switch() 实现与Menu() 显示分开将使您不必将数组传递给Menu() 或在菜单显示函数中声明变量。相反,将函数类型更改为int Menu() 并返回菜单选择的值,以便在switch() 中处理main()。
这允许您在main() 中声明您的数组并将它们提供给任何需要它们的功能,而无需将所有逻辑硬塞到您的菜单显示功能中。
当我们使用您的Menu() 函数时,您必须通过检查流状态来验证每个用户输入。否则你无法知道你是否有有效的输入,或者用户是否滑动并按下'r'而不是'4'。您必须处理不可恢复的错误 (badbit)、匹配失败 ('r' 而不是设置 failbit 的 '4') 或用户通过按 Ctrl + d (Ctrl + z在窗户上)。
总而言之,您的Menu() 函数可以写成:
int Menu (void)
{
int mode = 0; /* (initialize all others is good practice) */
std::cout << "\nChoose the operation:\n"
<< " 1- Function to read the matrix A\n"
<< " 2- Function to read the matrix B\n"
<< " 3- Function to display content of a matrix A\n"
<< " 4- Function to display content of a matrix B\n"
<< " 5- Function to find the sum of A & B\n"
<< " 6- Function to find the product of A & B\n"
<< " 7- Function to find & display sum of rows & sum of cols. of a A\n"
<< " 8- Function to find & display sum of rows & sum of cols. of a B\n"
<< " 9- Function to find sum of diagonal elements A\n"
<< " 10- Function to find sum of diagonal elements B\n"
<< " 11- Function to find out transpose of A\n"
<< " 12- Function to find out transpose of B\n"
<< " 13- Exit \n\n"
<< "mode: ";
while (!(std::cin >> mode)) { /* require valid input, exit on badbit or eofbit */
if (std::cin.bad()) { /* handle unrecoverable error */
std::cerr << "unrecoverable stream error.\n";
return -1;
}
else if (std::cin.eof()) { /* handle manual EOF */
std::cout << "(user canceled input)\n";
return -1;
}
/* handle .fail() matching failure */
std::cerr << "error: invalid integer input.\n";
std::cin.clear(); /* clear error */
/* empty stdin */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
}
return mode;
}
(注意: 不可恢复的错误和EOF 将-1 返回给调用者,还要注意使用std::basic_istream::ignore 来清空stdin 中的所有字符以防匹配失败)
您还会注意到using namespace std; 已被删除,请参阅Why is “using namespace std;” considered bad practice?。
在代码顶部定义了一些有用的常量:
static const int ROWS = 10,
COLS = ROWS,
EXIT = 13;
您在main() 中处理用户选择的实现可能是:
do { /* loop continually until error or exit */
switch ((mode = Menu()))
{
case 1: validA = read (A, na, ma); break;
case 2: validB = read (B, nb, mb); break;
case 3: if (validA) printArr (A, na, ma); break;
case 4: if (validB) printArr (B, nb, mb); break;
case 5: if (validA && validB) S = sum (A, B, na, ma); break;
case 6:
case 7: /* case fall-through intentional until filled */
case 8:
case 9:
case 10:
case 11:
case 12: std::cout << mode << " not implemented\n"; break;
case 13: break;
default: std::cerr << "error: invalid menu selection.\n";
break;
}
} while (mode > 0 && mode != EXIT);
对代码的其余更改仅涉及对各个部分进行改组(重构),以便每个部分都获取所需的参数。由于您在不同时间输出每个矩阵,因此编写 void printArr() 函数可以防止代码重复,也可以方便地进入菜单。一个简单的打印数组函数可以是:
void printArr (const int (*A)[COLS], const int N, const int M)
{
std::cout << "\nMatrix\n";
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++) {
std::cout << std::setw(4) << A[i][j];
}
std::cout << '\n';
}
}
(注意:std::setw()用于设置每个元素输出的宽度,需要调整一个)
你最大的问题是你的sum() 函数。正如 cmets 中所讨论的,这是由于矩阵 A 或 B 都没有存储在您的程序中,然后用户必须为每个菜单选择重新输入值(不好)。在 main() 中,A 和 B 将被声明为 10 x 10 Plain-Old-Arrays,由于您的限制(通常使用 std::vector 或 std::array),在 cmets 中也进行了讨论。
但是,对于sum(),参数列表会有点忙于传递A、B、S 和维度,因此,我们只需在sum() 中为S 分配存储空间并返回一个指向新分配的存储的指针,这样您就可以在main() 中获得S 的值(您也可以对product()、transpose() 或diagonals() 函数执行相同的操作。您可以写sum()如下:
// sum part is no longer broken
int (*sum (int (*A)[COLS], int (*B)[COLS], int N, int M))[COLS]
{
int (*S)[COLS] = new int [ROWS][COLS]; /* allocaee storagre for ROWS x COLS */
for (int i = 0; i < ROWS; i++) /* zero elements in S */
std::fill_n (S[i], COLS, 0);
for (int i = 0; i < N; i++) /* sum values in A & B, result in S */
for (int j = 0; j < M; j++)
S[i][j] = A[i][j] + B[i][j];
printArr (S, N, M); /* output result */
return S; /* return pointer to S */
}
(注意:int 的二维数组的类型为 int (*)[10],这就是为什么您会看到 S 的指针以这种方式声明的原因,以及您看到函数 sum() 的原因也这样声明。你返回一个 pointer-to-array-of int[10])
还要注意 #include <algorithm> 的 std::fill_n 用于将新分配的内存归零。
如果您可以简单地以正确的顺序对函数进行排序以满足它们的依赖关系,则不需要在源文件的开头列出函数原型。在您的代码中,这基本上意味着交换 Read() 和 read()。将整个程序放在一起,您可以这样做:
#include <iostream>
#include <iomanip>
#include <limits>
#include <algorithm>
/* To avoid the use of global variables, you must pass the array
* and dimensions to every function that needs A, N, M. Array
* bound are fine as #define or static const int.
*/
static const int ROWS = 10,
COLS = ROWS,
EXIT = 13;
int Menu (void)
{
int mode = 0; /* (initialize all others is good practice) */
std::cout << "\nChoose the operation:\n"
<< " 1- Function to read the matrix A\n"
<< " 2- Function to read the matrix B\n"
<< " 3- Function to display content of a matrix A\n"
<< " 4- Function to display content of a matrix B\n"
<< " 5- Function to find the sum of A & B\n"
<< " 6- Function to find the product of A & B\n"
<< " 7- Function to find & display sum of rows & sum of cols. of a A\n"
<< " 8- Function to find & display sum of rows & sum of cols. of a B\n"
<< " 9- Function to find sum of diagonal elements A\n"
<< " 10- Function to find sum of diagonal elements B\n"
<< " 11- Function to find out transpose of A\n"
<< " 12- Function to find out transpose of B\n"
<< " 13- Exit \n\n"
<< "mode: ";
while (!(std::cin >> mode)) { /* require valid input, exit on badbit or eofbit */
if (std::cin.bad()) { /* handle unrecoverable error */
std::cerr << "unrecoverable stream error.\n";
return -1;
}
else if (std::cin.eof()) { /* handle manual EOF */
std::cout << "(user canceled input)\n";
return -1;
}
/* handle .fail() matching failure */
std::cerr << "error: invalid integer input.\n";
std::cin.clear(); /* clear error */
/* empty stdin */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
}
return mode;
}
void printArr (const int (*A)[COLS], const int N, const int M)
{
std::cout << "\nMatrix\n";
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++) {
std::cout << std::setw(4) << A[i][j];
}
std::cout << '\n';
}
}
bool Read (int (*A)[COLS], const int& N, const int& M)
{
for (int R = 0; R < N; R++)
for (int C = 0; C < M; C++)
{
std::cout << "Element ["<<R<<"]["<<C<<"] = ";
if (!(std::cin >> A[R][C])) {
std::cerr << "error: invalid Element ["<<R<<"]["<<C<<"]";
return false;
}
}
return true;
}
bool read (int (*A)[COLS], int& N, int& M)
{
std::cout << "\nEnter the value of n and m: ";
if (!(std::cin >> N >> M)) { /* validate EVERY input */
std::cerr << "error: invalid integer value for N or M, A not filled.\n";
return false;
}
return Read (A, N, M);
}
// sum part is no longer broken
int (*sum (int (*A)[COLS], int (*B)[COLS], int N, int M))[COLS]
{
int (*S)[COLS] = new int [ROWS][COLS]; /* allocaee storagre for ROWS x COLS */
for (int i = 0; i < ROWS; i++) /* zero elements in S */
std::fill_n (S[i], COLS, 0);
for (int i = 0; i < N; i++) /* sum values in A & B, result in S */
for (int j = 0; j < M; j++)
S[i][j] = A[i][j] + B[i][j];
printArr (S, N, M); /* output result */
return S; /* return pointer to S */
}
int main()
{
int A[ROWS][COLS] = {{0}}, /* initialize all plain-old-arrays */
B[ROWS][COLS] = {{0}},
na = 0, nb = 0, ma = 0, mb = 0, /* (and all variable ig good practice */
(*S)[COLS] = nullptr, /* pointer to allocated sum array */
mode = 0;
bool validA = false, /* flag - A/B filled w/o error */
validB = false;
do { /* loop continually until error or exit */
switch ((mode = Menu()))
{
case 1: validA = read (A, na, ma); break;
case 2: validB = read (B, nb, mb); break;
case 3: if (validA) printArr (A, na, ma); break;
case 4: if (validB) printArr (B, nb, mb); break;
case 5: if (validA && validB) S = sum (A, B, na, ma); break;
case 6:
case 7: /* case fall-through intentional until filled */
case 8:
case 9:
case 10:
case 11:
case 12: std::cout << mode << " not implemented\n"; break;
case 13: break;
default: std::cerr << "error: invalid menu selection.\n";
break;
}
} while (mode > 0 && mode != EXIT);
delete[] S; /* free storage allocated for S */
}
使用/输出示例
$ ./bin/matrix_poa
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 1
Enter the value of n and m: 3 3
Element [0][0] = 1
Element [0][1] = 2
Element [0][2] = 3
Element [1][0] = 4
Element [1][1] = 5
Element [1][2] = 6
Element [2][0] = 7
Element [2][1] = 8
Element [2][2] = 9
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 3
Matrix
1 2 3
4 5 6
7 8 9
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 2
Enter the value of n and m: 3 3
Element [0][0] = 9
Element [0][1] = 8
Element [0][2] = 7
Element [1][0] = 6
Element [1][1] = 5
Element [1][2] = 4
Element [2][0] = 3
Element [2][1] = 2
Element [2][2] = 1
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 4
Matrix
9 8 7
6 5 4
3 2 1
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 5
10 10 10
10 10 10
10 10 10
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 13
这至少应该可以帮助您入门,并向您展示如何将 A 和 B 存储为具有自动存储持续时间的普通旧数组,同时也向您展示如何在需要时分配额外的 2D 数组。如果您有任何问题,请仔细查看并告诉我。