【问题标题】:How to pass the result of a function that calculates the transpose of a matrix to another function that prints the matrix?如何将计算矩阵转置的函数的结果传递给另一个打印矩阵的函数?
【发布时间】:2019-09-17 02:01:02
【问题描述】:

我创建了两个函数,一个找到函数的转置,另一个打印它。我知道 printMatrix 函数工作正常。 但是我不知道如何使用函数转置矩阵,然后打印它。

int main()
{
  //Constants
  int givenMatrix[3][3];

  //Takes in the given values of the matrix
  cout << "Please input matrix values in the order described " <<endl;
  for (int i=0; i < 3; ++i){
    cout << "Eneter Three Elements for Row: " << i + 1 << endl;
    for (int j=0; j < 3; ++j){
      cin >> givenMatrix[i][j];
    }
  }

printMatrix(givenMatrix);
int p = indexTranspose(givenMatrix);
printMatrix(p);
//pointerTranspose(givenMatrix);

return 0;
}

这是我找到矩阵转置的函数

//Function to find the transpose using indices     
void indexTranspose(int givenMatrix[3][3]){
  int transpose[3][3];

  //Find the transpose of the matrix
  for (int i=0; i < 3; i++){
    for (int j=0; j < 3; j++){
    transpose[i][j] = givenMatrix[j][i];
    }
  }
}

我也尝试通过指针找到矩阵的转置但失败了,如果可能的话,有人可以帮助我理解我做错了什么吗?

//Function to find the transpose using indices
void pointerTranspose(int givenMatrix[3][3])
{

    //Find the transpose of the matrix
    for (int i=0; i < 3; i++){
      for (int j=0; j < 3; j++){
      *(*transpose[j][i]) = *(*givenMatrix[i][j]);
      }
    }
}

【问题讨论】:

  • 如果这是针对家庭作业的问题,我建议您向老师寻求帮助,因为您的问题中有几个部分表明您对某些主题有误解。在不知道你来自哪里的情况下,我很难很好地纠正这些误解。
  • 感谢您的帮助,确实是功课。可悲的是,我不能安排他的办公时间。教授要求创建一个 3x3 矩阵,通过 main 中的键盘读取。然后创建一个 void printMatrix() 函数,该函数将在调用时打印任何矩阵,以及一个 void transposeMatrix() 函数。我们还必须使用 printMatrix() 函数来输出新的转置矩阵。

标签: c++ pointers matrix parameter-passing transpose


【解决方案1】:

但是我不知道如何使用 printMatrix 函数。

该语句包含一些内容,但您似乎在问“我如何将 transpose 函数作为参数传递给 printMatrix 函数,以便 printMatrix 函数打印矩阵(或将根据我传递的函数打印矩阵的任何其他变体)。

本质上,如果这是您所追求的,您只是想传递一个函数,该函数将以某种方式操作您的矩阵作为参数,然后让打印函数应用该函数,然后打印结果。本质上,它与创建转置矩阵然后将转置矩阵作为单个参数传递给printMatrix 相同,但是通过包含另一个对矩阵执行某些操作的参数来改变printMatrix 的行为打印出来有优点。

无论您是先创建转置并传递它,还是传递原始矩阵和转置函数,您都需要第二个矩阵来保存原始的转置,以便可以打印其值。关键区别在于转置矩阵需要在什么范围内可见。从您的indexTranspose 函数来看,这并不重要。您有两个选择(1)您保留返回类型 void 并传入第二个矩阵以填充原始的转置,或者(2)您更改 indexTranspose 函数的返回类型并动态分配矩阵来保存转置并返回一个指向它的指针。

(注意: 作为两者的扩展,您可以传递对现有矩阵的引用,或声明并返回 STL 容器,但是当您使用二维数组时,这些将留到另一天基本类型int)

最简单的方法是传入另一个 3x3 2D 数组来保存转置值。您可以简单地向您的 indexTranspose 函数添加另一个参数来完成此操作,例如

 /* Function to find the transpose using indices */     
void indexTranspose (int (*transpose)[3], int (*givenMatrix)[3])
{
    //Find the transpose of the matrix
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            transpose[i][j] = givenMatrix[j][i];
        }
    }
}

(注意:无论您传递int transpose[][3] 还是int (*transpose)[3],它们都是等价的。当您将数组作为参数传递给函数时,第一级间接转换为指向第一个元素——在这种情况下指向int[3]数组的指针。上面的第二种形式显示了转换的显式结果)

如果您想将indexTranspose 作为参数传递给printMatrix,您必须了解函数指针的类型。 indexTranspose 的完整形式是:

void (*f)(int (*)[3], int (*)[3]);

(一个函数指针f,返回类型为void,它接受两个指向int数组的指针[3],例如两个3x3 2D数组,作为其参数)

因此,将函数指针作为参数添加到 printMatrix 函数可能是:

void printMatrix (int (*m)[3], void (*f)(int (*)[3], int (*)[3]))
{
    int altered[3][3] = {{0}};

    f (altered, m);  /* apply function to original m, with results in altered */

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++)
            std::cout << " " << std::setw(3) << altered[i][j];
        std::cout.put ('\n');
    }
}

注意:这里是第二个矩阵的范围来保存将函数应用于第一个矩阵的结果变得很重要。由于您只使用结果进行打印,因此可以将第二个矩阵(上面称为altered)声明为printMatrix 函数的本地以进行打印。在上面,您的printMatrix 函数现在采用原始矩阵m 和一个指向返回void 并接受两个3x3 2D 整数矩阵作为其参数的函数的指针,它使用以下值更新第一个3x3 2D 数组的值转置操作的结果(或函数将执行的任何操作)

然后在您的调用函数中(此处为main()),将原始矩阵连同指向indexTranspose 的指针一起传递给indexTranspose 并在printMatrix 中发生转置,然后输出,您只需要做的是调用:

    printMatrix (givenMatrix, indexTranspose);

实际上,您只需将更改后的矩阵作为矩阵参数传递给printMatrix,因为您可能会将该矩阵用于打印以外的用途,但学习如何传递函数以提供操作也是如此(因为您将来可能会将该函数传递给打印函数以外的其他东西)

把它们放在一起,你可以做类似的事情:

#include <iostream>
#include <iomanip>

/* Function to find the transpose using indices */     
void indexTranspose (int (*transpose)[3], int (*givenMatrix)[3])
{
    //Find the transpose of the matrix
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            transpose[i][j] = givenMatrix[j][i];
        }
    }
}

void printMatrix (int (*m)[3], void (*f)(int (*)[3], int (*)[3]))
{
    int altered[3][3] = {{0}};

    f (altered, m);

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++)
            std::cout << " " << std::setw(3) << altered[i][j];
        std::cout.put ('\n');
    }
}

int main (void) {

    int givenMatrix[3][3];

    std::cout << "Please input matrix values in the order described " << '\n';
    for (int i = 0; i < 3; i++) {
        std::cout << "Eneter Three Elements for Row: " << i + 1 << '\n';
        for (int j=0; j < 3; ++j){
            if (!(std::cin >> givenMatrix[i][j])) {  /* always VALIDATE input */
                std::cerr << "error: invalid integer input.\n";
                return 1;
            }
        }
    }
    /* pass given & pointer to function */
    printMatrix (givenMatrix, indexTranspose); 
}

使用/输出示例

$ ./bin/prn_mtrx_by_fn
Please input matrix values in the order described
Eneter Three Elements for Row: 1
1 2 3
Eneter Three Elements for Row: 2
4 5 6
Eneter Three Elements for Row: 3
7 8 9
   1   4   7
   2   5   8
   3   6   9

如果您对将函数指针作为参数传递有任何其他问题,或者如果我误解了您的问题,请告诉我,我很乐意为您提供进一步的帮助。

【讨论】:

    【解决方案2】:

    首先,我将解释为什么您的原始功能不起作用。您在 indexTranspose 中创建的数组是一个局部变量,这意味着它不存在于函数之外。所以,当indexTranspose 结束,你的程序返回到main 时,转置就消失了。

    您在尝试使用指针时走在正确的道路上,但没有完全正确。

    您需要让 pointerTranspose 接受指向 3x3 矩阵的指针。看起来您在创建 givenMatrix 后试图将其设为指针,但您不能这样做。这是一个有效的 pointerTranspose 示例:

    //Function to find the transpose using indices
    void pointerTranspose(int (*givenMatrix)[3][3])
    {
        int transpose[3][3];
        //Find the transpose of the matrix
        for (int i=0; i < 3; i++){
            for (int j=0; j < 3; j++){
                transpose[i][j] = (*givenMatrix)[j][i];
            }
        }
    
        //Set the values in the original matrix
        for (int i=0; i < 3; i++){
            for (int j=0; j < 3; j++){
                (*givenMatrix)[i][j] = transpose[i][j];
            }
        }
    }
    

    那么你可以这样称呼它:pointerTranspose(&amp;givenMatrix);

    您也可以通过将(*givenMatrix)[j][i] 直接分配给(*givenMatrix)[i][j] 来在pointerTranspose 中创建临时transpose 变量而不创建临时变量(*givenMatrix)[i][j],但我将把它留给您作为练习。 (提示:小心不要两次交换东西!)

    【讨论】:

    • 非常感谢!!我会试试你的练习,但是你能解释一下为什么我需要 //Set the Values in the original matrix 部分吗?
    • 出于同样的原因,您原来的 indexTranspose 函数不起作用。 transpose[i][j] = (*givenMatrix)[j][i]; 行正在从 givenMatrix 读取,并写入转置。在“查找矩阵的转置”部分之后,transpose 变量保存了转置,但givenMatrix 保持不变。由于transpose 是一个局部变量,它在函数结束时被销毁,而你失去了所有的工作。
    猜你喜欢
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 2012-10-23
    相关资源
    最近更新 更多