31

这个网站上的第一个计时器,所以这里..

我是 C++ 的新手,我目前正在阅读 DS Malik 的“使用 C++ 2nd ed 的数据结构”一书。

在书中 Malik 提供了两种创建动态二维数组的方法。在第一种方法中,您将变量声明为指针数组,其中每个指针都是整数类型。前任。

int *board[4];

..然后使用 for 循环创建“列”,同时将指针数组用作“行”。

第二种方法,你使用一个指针指向一个指针。

int **board;
board = new int* [10]; 

等等

我的问题是:哪种方法更好?** 方法对我来说更容易可视化,但第一种方法可以以几乎相同的方式使用。这两种方法都可以用来制作动态二维数组。

编辑:上面的帖子不够清楚。这是我尝试过的一些代码:

int row, col;

cout << "Enter row size:";
cin >> row;
cout << "\ncol:";
cin >> col;

int *p_board[row];
for (int i=0; i < row; i++)
    p_board[i] = new int[col];

for (int i=0; i < row; i++)
{
    for (int j=0; j < col; j++)
    {
        p_board[i][j] = j;
        cout << p_board[i][j] << " ";
    }
    cout << endl;
}
cout << endl << endl;

int **p_p_board;
p_p_board = new int* [row];
for (int i=0; i < row; i++)
    p_p_board[i] = new int[col];

for (int i=0; i < row; i++)
{
    for (int j=0; j < col; j++)
    {
        p_p_board[i][j] = j;
        cout << p_p_board[i][j] << " ";
    }
    cout << endl;
}
4

5 回答 5

55

第一种方法不能用于创建动态二维数组,因为这样做:

int *board[4];

您实际上分配了一个由 4 个指针组成的数组int on stack。因此,如果您现在用动态数组填充这 4 个指针中的每一个:

for (int i = 0; i < 4; ++i) {
  board[i] = new int[10];
}

你最终得到的是一个具有静态行数(在本例中为 4)和动态列数(在本例中为 10)的二维数组。所以它不是完全动态的,因为当您在堆栈上分配一个数组时,您应该指定一个常量大小,即在编译时已知。动态数组之所以称为动态数组,是因为它的大小不必在编译时知道,而是可以在运行时由某个变量确定。

再一次,当你这样做时:

int *board[4];

或者:

const int x = 4; // <--- `const` qualifier is absolutely needed in this case!
int *board[x];

您提供一个在编译时已知的常量(在本例中为 4 或x),以便编译器现在可以为您的数组预分配此内存,并且当您的程序加载到内存中时,它已经拥有该board数组的内存量,这就是为什么它被称为static,即因为大小是硬编码的并且不能动态更改(在运行时)。

另一方面,当你这样做时:

int **board;
board = new int*[10];

或者:

int x = 10; // <--- Notice that it does not have to be `const` anymore!
int **board;
board = new int*[x];

编译器不知道需要多少内存board数组,因此它不会预先分配任何东西。但是当您启动程序时,数组的大小将由x变量的值(在运行时)决定,并且数组的相应空间board将分配在所谓的堆上- 计算机上运行的所有程序都可以的内存区域预先(在编译时)分配未知数量的内存供个人使用。

因此,要真正创建动态二维数组,您必须使用第二种方法:

int **board;
board = new int*[10]; // dynamic array (size 10) of pointers to int

for (int i = 0; i < 10; ++i) {
  board[i] = new int[10];
  // each i-th pointer is now pointing to dynamic array (size 10) of actual int values
}

我们刚刚创建了一个 10 x 10 维度的方形二维数组。要遍历它并用实际值填充它,例如 1,我们可以使用嵌套循环:

for (int i = 0; i < 10; ++i) {   // for each row
  for (int j = 0; j < 10; ++j) { // for each column
    board[i][j] = 1;
  }
}
于 2013-04-14T17:17:22.687 回答
11

您对第二种方法的描述仅给您一个一维数组:

int *board = new int[10];

这只是分配一个包含 10 个元素的数组。也许你的意思是这样的:

int **board = new int*[4];
for (int i = 0; i < 4; i++) {
  board[i] = new int[10];
}

在这种情况下,我们分配 4 个int*s,然后将它们中的每一个指向一个动态分配的 10 个数组int

所以现在我们将其与int* board[4];. 主要区别在于,当您使用这样的数组时,“行”的数量必须在编译时知道。这是因为数组必须具有编译时固定大小。如果您想返回这个int*s 数组,您也可能会遇到问题,因为该数组将在其作用域结束时被销毁。

动态分配行和列的方法确实需要更复杂的措施来避免内存泄漏。您必须像这样释放内存:

for (int i = 0; i < 4; i++) {
  delete[] board[i];
}
delete[] board;

我必须推荐使用标准容器。您可能喜欢使用 astd::array<int, std::array<int, 10> 4>或 a std::vector<std::vector<int>>,您将其初始化为适当的大小。

于 2013-04-14T17:16:39.280 回答
1

在这两种情况下,您的内部维度都可以动态指定(即取自变量),但区别在于外部维度。

这个问题基本上等同于以下问题:

int* x = new int[4];比“更好”吗int x[4]

答案是:“,除非您需要动态选择该数组维度。”

于 2013-04-14T17:49:29.223 回答
0

这可以通过这种方式完成

  1. 我使用过运算符重载
  2. 重载分配
  3. 重载的复制构造函数

    /*
     * Soumil Nitin SHah
     * Github: https://github.com/soumilshah1995
     */
    
    #include <iostream>
    using namespace std;
            class Matrix{
    
    public:
        /*
         * Declare the Row and Column
         *
         */
        int r_size;
        int c_size;
        int **arr;
    
    public:
        /*
         * Constructor and Destructor
         */
    
        Matrix(int r_size, int c_size):r_size{r_size},c_size{c_size}
        {
            arr = new int*[r_size];
            // This Creates a 2-D Pointers
            for (int i=0 ;i < r_size; i++)
            {
                arr[i] = new int[c_size];
            }
    
            // Initialize all the Vector to 0 initially
            for (int row=0; row<r_size; row ++)
            {
                for (int column=0; column < c_size; column ++)
                {
                    arr[row][column] = 0;
                }
            }
            std::cout << "Constructor -- creating Array Size ::" << r_size << " " << c_size << endl;
        }
    
        ~Matrix()
        {
            std::cout << "Destructpr  -- Deleting  Array Size ::" << r_size <<" " << c_size << endl;
    
        }
    
        Matrix(const Matrix &source):Matrix(source.r_size, source.c_size)
    
        {
            for (int row=0; row<source.r_size; row ++)
            {
                for (int column=0; column < source.c_size; column ++)
                {
                    arr[row][column] = source.arr[row][column];
                }
            }
    
            cout << "Copy Constructor " << endl;
        }
    
    
    public:
        /*
         * Operator Overloading
         */
    
        friend std::ostream &operator<<(std::ostream &os, Matrix & rhs)
        {
            int rowCounter = 0;
            int columnCOUNTER = 0;
            int globalCounter = 0;
    
            for (int row =0; row < rhs.r_size; row ++)
            {
                for (int column=0; column < rhs.c_size ; column++)
                {
                    globalCounter = globalCounter + 1;
                }
                rowCounter = rowCounter + 1;
            }
    
    
            os << "Total There are " << globalCounter << " Elements" << endl;
            os << "Array Elements are as follow -------" << endl;
            os << "\n";
    
            for (int row =0; row < rhs.r_size; row ++)
            {
                for (int column=0; column < rhs.c_size ; column++)
                {
                    os << rhs.arr[row][column] << " ";
                }
            os <<"\n";
            }
            return os;
        }
    
        void operator()(int row, int column , int Data)
        {
            arr[row][column] = Data;
        }
    
        int &operator()(int row, int column)
        {
            return arr[row][column];
        }
    
        Matrix &operator=(Matrix &rhs)
                {
                    cout << "Assingment Operator called " << endl;cout <<"\n";
                    if(this == &rhs)
                    {
                        return *this;
                    } else
                        {
                        delete [] arr;
    
                            arr = new int*[r_size];
                            // This Creates a 2-D Pointers
                            for (int i=0 ;i < r_size; i++)
                            {
                                arr[i] = new int[c_size];
                            }
    
                            // Initialize all the Vector to 0 initially
                            for (int row=0; row<r_size; row ++)
                            {
                                for (int column=0; column < c_size; column ++)
                                {
                                    arr[row][column] = rhs.arr[row][column];
                                }
                            }
    
                            return *this;
                        }
    
                }
    
    };
    
                int main()
    {
    
        Matrix m1(3,3);         // Initialize Matrix 3x3
    
        cout << m1;cout << "\n";
    
        m1(0,0,1);
        m1(0,1,2);
        m1(0,2,3);
    
        m1(1,0,4);
        m1(1,1,5);
        m1(1,2,6);
    
        m1(2,0,7);
        m1(2,1,8);
        m1(2,2,9);
    
        cout << m1;cout <<"\n";             // print Matrix
        cout << "Element at Position (1,2) : " << m1(1,2) << endl;
    
        Matrix m2(3,3);
        m2 = m1;
        cout << m2;cout <<"\n";
    
        print(m2);
    
        return 0;
    }
    
于 2019-09-21T15:32:17.847 回答
0

此代码在对外部库的要求很少的情况下运行良好,并展示了int **array.

这个答案表明每个数组都是动态大小的,以及如何将动态大小的叶子数组分配到动态大小的分支数组中。

该程序采用以下格式从 STDIN 获取参数:

2 2   
3 1 5 4
5 1 2 8 9 3
0 1
1 3

下面的程序代码...

#include <iostream>

int main()
{
    int **array_of_arrays;

    int num_arrays, num_queries;
    num_arrays = num_queries = 0;
    std::cin >> num_arrays >> num_queries;
    //std::cout << num_arrays << " " << num_queries;

    //Process the Arrays
    array_of_arrays = new int*[num_arrays];
    int size_current_array = 0;

    for (int i = 0; i < num_arrays; i++)
    {
        std::cin >> size_current_array;
        int *tmp_array = new int[size_current_array];
        for (int j = 0; j < size_current_array; j++)
        {
            int tmp = 0;
            std::cin >> tmp;
            tmp_array[j] = tmp;
        }
        array_of_arrays[i] = tmp_array;
    }


    //Process the Queries
    int x, y;
    x = y = 0;
    for (int q = 0; q < num_queries; q++)
    {
        std::cin >> x >> y;
        //std::cout << "Current x & y: " << x << ", " << y << "\n";
        std::cout << array_of_arrays[x][y] << "\n";
    }

    return 0;
}

这是一个非常简单的实现,int main仅依赖于std::cinand std::cout。准系统,但足以展示如何使用简单的多维数组。

于 2016-11-30T22:37:13.593 回答