【问题标题】:c++ performing operations on functions and declaring functionsc++ 对函数执行操作并声明函数
【发布时间】:2014-04-23 10:35:21
【问题描述】:

我想为以下代码声明一个函数,该函数是从文本文件中读取的矩阵。代码如下。

if (infile == "A.txt")
    {
        ifstream myfile("A.txt");
    string line;
    int MatA[3][3];
    int i=0;
    while (getline (myfile, line))
    {
        stringstream ss(line);
        for(int j=0; j<3; j++)
            ss >> MatA[i][j]; // load the i-th line in the j-th row of mat
        i++;
    }
    // display the loaded matrix                                    
        for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
            cout<<MatA[i][j]<<" ";
            cout<<endl;
            }

        }

现在我尝试将这个矩阵声明为一个函数,以便稍后在我的代码中执行操作时,我可以只调用该函数,而不必重新编写整个矩阵。但是我很难做到这一点,我尝试将矩阵声明为函数如下所示。

int display (int MatA)
{
     for(int i=0; i<3; i++)
    {
        for(int j=0; j<3; j++)
           cout<<MatA[i][j]<<" ";
       cout<<endl;
    }
}

但是出现了一个错误,说[i]'表达式必须有一个指向对象类型的指针'。

如果有人能帮忙那就太好了!

【问题讨论】:

  • 您传递的是int,而对于二维数组,您应该传递int **

标签: c++ arrays function variables function-declaration


【解决方案1】:

例如函数可以这样定义

const size_t N = 3;

void display( const int ( &MatA )[N][N] )
{
    for ( size_t i = 0; i < N; i++ )
    {
        for ( size_t j = 0; j < N; j++ ) std::cout << MatA[i][j] << " ";
        std::cout << std::endl;
    }
}

另一种方式如下

const size_t N = 3;

void display( const int ( *MatA )[N], size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < N; j++ ) std::cout << MatA[i][j] << " ";
        std::cout << std::endl;
    }
}

函数可以调用为

#include <iostream>

const size_t N = 3;

// the function definitions

int main()
{
   int a[N][N] = {};
   // some code to fill the matrix

   display( a );
   display( a, N );
}

最后,您可以使用 cmets 中建议的方法来发布 @boycy 的帖子,但就我而言,我不喜欢这种方法。 例如

#include <iostream>

const size_t N = 3;

void display( const int **MatA, size_t m, size_t n )
{
    for ( size_t i = 0; i < m * n; i++ )
    {
        std::cout << MatA[i] << " ";
        if ( ( i + 1 ) % n == 0 ) std::cout << std::endl;
    }
}

int main()
{
   int a[N][N] = {};
   // some code to fill the matrix

   display( reinterpret_cast<const int **>( a ), N, N );
}

【讨论】:

  • 这两个实现都不像它们可以/应该[可以说]那样通用;第一个强制矩阵为 NxN 方阵,而第二个强制矩阵为 nxN。 @SingerOfTheFall 建议将矩阵作为 int** 传递是最灵活(也是最常用)的方法。因此,函数签名将是 void display( const int** MatA, size_t m, size_t n ),访问 MatA[i][j] 中的 i[0, n) 中的 j 将按需要工作。
  • @boycy 在这种情况下,您可能无法在不更改函数主体的情况下将二维数组传递给该函数。作者没有询问通用函数定义。如果您在使用模板函数或容器时需要通用方法。
  • 抱歉,您当然是对的。直到我忘记了多维数组在 C++ 中是多么令人不快 :-) 值得注意的是,在数组维度上模板化的函数可以正常工作,但是由于模板为每个唯一的 (m,n) 对实例化一次,它可能导致一个臃肿的二进制文件。
  • @boycy:我不得不不同意:在 2014 年传递具有编译时固定边界(如果可能)的引用是惯用的——多层次的指针和显式的大小参数在不久前就像渡渡鸟一样!尽管有膨胀的潜力,我个人还是会使用template &lt;typename T, size_t N, size_t M&gt; void display(const T (&amp;ar)[N][M]);。不过,我必须在这个决定与我实际最终得到的实例数量之间取得平衡,虽然最终可能会得到一个很像你建议的实现,尽管心情很沉重。 :)
  • @VladfromMoscow 我不认为我提倡reinterpret_cast;我忘记了数组类型衰减不是递归的。给定一个固定大小的数组,我通常会选择模板方法。 @LightnessRacesinOrbit 非常正确。一些额外的想法,(因为这毕竟是标记为 C++):std::array 是数组的 C++11 拼写,并且确实支持多维(尽管很奇怪;请参阅here)和std::dynarray(数组Extensions TS) 将提供最小化膨胀的运行时调整。适合各种场合:-)
【解决方案2】:

您将int MatA 传递给显示,但您希望int[][] 作为参数。然而,这不是那样工作的。因此,您要么必须传递 int** 并对其执行指针运算,要么必须为此矩阵创建一些更好的访问器。

我建议查看类似的实现,例如解决您的问题的 OpenCV Mat 类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    相关资源
    最近更新 更多