【问题标题】:manipulating multidimensional arrays with functions in C++使用 C++ 中的函数操作多维数组
【发布时间】:2012-03-12 18:30:57
【问题描述】:

我正在尝试使用函数在 C++ 中修改二维数组的内容。我无法找到有关如何通过引用将二维数组传递给函数然后操作单个单元格的信息。

我要解决的问题具有以下格式。为了简洁,我做了一个简单的程序。

#include<cstdlib>
#include<iostream>
using namespace std;

void func(int& mat) {
    int k,l;
    for(k=0;k<=2;k++) {
    for(l=0;l<=2;l++) {
    mat[k][l]=1;  //This is incorrect because mat is just a reference, but
                  // this is the kind of operation I want. 
    }
}

return; 
}

int main() {
int A[3][3];
int i, j;
char jnk;

for(i=0;i<=2;i++) {
    for(j=0;j<=2;j++) {
        A[i][j]=0;
    }
}

    func(A);

cout << A[0][0];
    return 0;
}

所以 A[0][0] 的值应该从 0 变为 1。这样做的正确方法是什么?非常感谢提前...

【问题讨论】:

    标签: c++ multidimensional-array matrix pass-by-reference linear-algebra


    【解决方案1】:

    数组不是按值传递的,所以你可以简单地使用

    void func(int mat[][3])
    

    而且,如果您在func 中修改mat 的值,您实际上是在main 中修改它。

    如果您事先知道矩阵的大小,则可以使用该方法,否则请考虑使用指针:

    #include <iostream>
    
    void f(int **m, int r, int c) {
        m[0][0]=1;
    }
    
    int main () {
    
        int **m;
        int r=10,c=10;
        int i;
    
        m = (int**)malloc(r*sizeof(int*));
    
        for (i=0; i<r;i++)
            m[i] = (int*)malloc(c*sizeof(int));
    
        f(m,r,c);
    
        printf("%d\n",m[0][0]);
    
        for(i=0;i<r;i++)
            free(m[i]);
    
        free(m);
    
        return 0;
    
    }
    

    【讨论】:

    • @FredOverflow 好吧,实际上你是对的,我选择的词不是最好的。我编辑了我的答案
    • 并非如此,因为二维数组实际上是线性的,并且“数组规则”[ x[i] = *(x+i),然后 x[i][k] = *(*( x + i) + k) ] 不正确。这就是为什么你不能只声明 mat[3][3] 然后期望一个 int ** 函数正确地写入它。
    【解决方案2】:

    C++ 允许您将这样的代码结构封装到一个对象中,例如一个数组具有std::vector 和std::array 对象。

    我亲自推出了自己的矩阵容器。这样您就不必担心它们如何传递的细节。

    矩阵实现的基本示例可能是:

    template<typename T>
    class matrix
    {
    public:                     //TYPEDEFS
        typedef                         T                                                       value_type;
    private:
        typedef                 std::vector<value_type>         vect_type;
    public:
        typedef typename        vect_type::iterator             iterator;
        typedef typename        vect_type::const_iterator       const_iterator;
    
    private:            //DATAMEMBERS
        vect_type values;
        size_t x_sz, y_sz;/not const for assingment reasons
    
    public:                     //MEMBER FUNCTIONS
        matrix(const matrix&)           =default;
        matrix(matrix&&)                =default;
        matrix& operator=(const matrix&)=default;
        matrix& operator=(matrix&&)     =default;
    
        matrix(size_t x_sz_=0u, size_t y_sz_=0u, value_type t=value_type())
        : values(x_sz_*y_sz_, t)
        , x_sz(x_sz_)
        , y_sz(y_sz_)
        { }
    
        //return        symbol          const   body
        size_t          x_size()        const   { return x_sz; }
        size_t          y_size()        const   { return y_sz; }
    
        iterator        begin()                 { return values.begin();        }
        iterator        end()                   { return values.end();          }
        const_iterator  begin()         const   { return values.cbegin();       }
        const_iterator  end()           const   { return values.cend();         }
        const_iterator  cbegin()        const   { return values.cbegin();       }
        const_iterator  cend()          const   { return values.cend();         }
    
        value_type& at(size_t x, size_t y)
        {
                return values.at(y*x_sz+x);
        }
    
        const value_type& at(size_t x, size_t y) const
        {
                return values.at(y*x_sz+x);
        }
    };  //class matrix
    

    然后您只需执行以下操作:

     void func(const mat& m)....
     :::
    
     matrix<int> mat(3,3);
    
     //this isn't necessary as the ctor take a default value,
     // however it show you how you might iterate through the values.
     for(size_t y=0; y!=mat.y_size(); ++y)
        for(size_t x=0; x!=mat.x_size(); ++x)
            mat.at(x, y)=0; 
    
    func(mat); //as param
    

    【讨论】:

      【解决方案3】:

      你能检查一下吗:

      #include <cstdio>
      #include <cstdlib>
      
      void printArrays(int* array[], int len1, int len2) {
        for (int i=0; i<len1; i++) {
          for (int j=0; j<len2; j++) {
            printf("%d ", array[i][j]);
          }
          printf("\n");
        }
      }
      
      void modify(int* array[], int len1, int len2) {
        for (int i=0; i<len1; i++) {
          for (int j=0; j<len2; j++) {
            array[i][j]*=(i+j);
          }
        }
      }
      
      int main() {
        int arr1[3] = {4, 5, 5};
        int arr2[3] = {6, 1, 5};
        int arr3[3] = {7, 5, 1};
        int *array[3] = {arr1, arr2, arr3};
        printArrays(array, 3, 3);
        printf("After modify:\n");
        modify(array, 3, 3);
        printArrays(array, 3, 3);
        return 0;
      }
      

      【讨论】:

        【解决方案4】:

        这是传统的方式。您可以使用任一版本的函数“f”:

        #include <cstdlib>
        
        const size_t cols = 10; // You can hardcode this below if you want
        
        // Can only be called if you know "cols" at compile-time
        void f(int pArray[][cols], size_t rows)
        {
            for(size_t i = 0; i < rows; ++i)
            {
                for(size_t j = 0; j < cols; ++j)
                {
                    pArray[i][j] = 1;
                }
            }
        }
        
        // Use this if you don't know "cols" at compile-time (good for any arbitrary 2D array)
        void f(int *pArray, size_t rows, size_t cols)
        {
            for(size_t i = 0; i < rows; ++i)
            {
                const size_t RowOffset = (i * cols);
                for(size_t j = 0; j < cols; ++j)
                {
                    pArray[RowOffset + j] = 1;
                }
            }
        }
        
        int main()
        {
            int array[][cols]= {{   5,  10,  15,  20,  25,  30,  35,  40,  45,  50 },
                                {  55,  60,  65,  70,  75,  80,  85,  90,  95, 100 },
                                { 105, 110, 115, 120, 125, 130, 135, 140, 145, 150 },
                                { 155, 160, 165, 170, 175, 180, 185, 190, 195, 200 },
                                { 205, 210, 220, 225, 230, 235, 240, 245, 250, 255}};
        
            const size_t rows = sizeof(array) / sizeof(array[0]); // 5 in this example but you can hardcode it if you want
            f(array, rows);
            f(array[0], rows, cols);
        
            return 0;
        }
        

        【讨论】:

          猜你喜欢
          • 2013-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-02
          • 2011-08-29
          • 2020-01-26
          相关资源
          最近更新 更多