вопрос по массивам в с ++ - PullRequest
0 голосов
/ 18 июня 2010

int java-объявление массива, подобное этому int a[][]=new int[3][3] работает, но в c ++ не почему?Пожалуйста, помогите мне, я не использовал C ++ долгое время, поэтому, пожалуйста, помогите мне

Ответы [ 7 ]

8 голосов
/ 18 июня 2010

В C ++ вы бы просто сказали int a[3][3];. C ++ не требует, чтобы все массивы и объекты объявлялись с новым.

EDIT: Для динамического размера n нельзя использовать массивы на основе стека.

Наверное, лучший способ - вектор векторов:

std::vector<std::vector<int> > a;
a.resize(n);
for(int i = 0; i < n; ++i)
{
    a[i].resize(n);
}
5 голосов
/ 18 июня 2010

Как правило, говоря, вам вообще следует избегать использования массивов в C ++.В то время как есть особые случаи, когда они (почти) единственный выбор, ваш первый выбор должен обычно использовать вместо std::vector.В этом случае то, что вы хотите, становится довольно простым:

// vector of 3 ints, each initialized to 0
std::vector<int> init(3, 0);   

// vector of three vectors of int, each initialized to the value of 'init':
std::vector<std::vector<int> > a(3, init);
2 голосов
/ 18 июня 2010

В C ++ вы можете размещать массивы в стеке или в куче.Выделение в стеке возможно только для массивов фиксированного размера (т. Е. Размеры известны во время компиляции):

int a[3][3];

Приведенное выше распределение массива 3x3 в стеке.Если вы хотите динамически распределять массивы (то есть размер не известен во время компиляции), это должно быть сделано в куче.Однако, насколько мне известно, C ++ не поддерживает напрямую многомерные массивы.Поэтому вам, возможно, придется сделать что-то вроде

int * a = new int[n*n];

, а затем получить доступ к элементу в (i, j) как [i + j * n].

В качестве альтернативы вы также можете сделать что-то вроде

int **a = new *int[n];
for(int i = 0; i < n; ++i {
  a[i] = new int[n];
}

Попытка выделить динамический массив в стеке, такой как

int a[n][n];

Приведет к ошибке компилятора.

0 голосов
/ 18 июня 2010

Однажды у меня возникла такая же проблема, и в итоге я создал для нее класс.По сути, он хранится как указатель на одномерный массив, а указателями немного манипулируют, так что он действует как двумерный массив (матрица).Вот код, который я использовал:

#include <utility>
#include <memory.h>

template <typename T>
class Matrix
{
protected:
    T** m;
    int x,y;

    __forceinline void setMatrix()
    {
        assert(x > 0);
        assert(y > 0);
        m = new T*[y];
        m[0] = new T[x*y];
        for (int i = 1; i < y; ++i)
        {
            m[i] = m[i-1] + x;
        }
    }
public:
    Matrix():m(0),x(0),y(0){}
    Matrix(int rows, int cols):x(cols),y(rows),m(0)
    {
        setMatrix();
    }

    Matrix(const Matrix<T>& mat):m(0),x(mat.x),y(mat.y)
    {
        setMatrix();
        memcpy_s(m[0], x*y, mat.m[0], x*y);
    }

    ~Matrix()
    {
        if (m)
        {
            delete[] m[0];
            delete[] m;
        }
    }

    void fill(const T& val)
    {
        if (m)
        {
            for (int j = 0; j < y; ++j)
                for (int i = 0; i < x; ++i)
                    m[j][i] = val;
        }
    }

    T& at(int row, int col)
    {
        assert(row >= 0 && row < y);
        assert(col >= 0 && col < x);
        return m[row][col];
    }

    const T& at(int row, int col) const
    {
        assert(row >= 0 && row < y);
        assert(col >= 0 && col < x);
        return m[row][col];
    }

    T* operator[](int row)
    {
        assert(row >= 0 && row < y);
        return m[row];
    }

    const T* operator[](int row) const
    {
        assert(row >= 0 && row < y);
        m[row];
    }

    T& operator ()(int row, int col)
    {
        assert(row >= 0 && row < y);
        assert(col >= 0 && col < x);
        return m[row][col];
    }

    const T& operator ()(int row, int col) const
    {
        assert(row >= 0 && row < y);
        assert(col >= 0 && col < x);
        return m[row][col];
    }

    void swap(Matrix<T>& mat)
    {
        std::swap(m, mat.m);
        std::swap(x, mat.x);
        std::swap(y, mat.y);
    }

    const Matrix& operator = (const Matrix<T>& rhs)
    {
        Matrix temp(rhs);
        swap(temp);
        return *this;
    }

    //

    int getRows() const
    {
        return y;
    }

    int getColumns() const
    {
        return x;
    }
};

Использование будет выглядеть следующим образом:

typedef Matrix<int> IntMatrix;
IntMatrix mat(2,3); // Creates a 2x3 matrix to store integers.
mat.fill(0); // Fill it with zeroes.
int val02 = mat[0][2]; // Unsafe way to retrieve values
int val12 = mat(1,2); // Safe way to retrieve values;
mat(0,1) = 10; // Assign values directly to the matrix.

Вы также можете расширить этот класс, чтобы он имел другую функцию, связанную с матрицей.

0 голосов
/ 18 июня 2010

Самое близкое совпадение:

int a[][] = { 
    new int[3],
    new int[3],
    new int[3]
};

, а управление памятью - ваша ответственность в C ++ (если вы не используете нестандартный пользовательский new[]) - это означает, что вам придется звонитьdelete[] для каждого из элементов a.

Лучше всего объявить это следующим образом:

int a[3][3];

Это создаст автоматический 3x3 двумерный массив.В отличие от первого примера, его память будет выделена в стеке и, таким образом, будет автоматически удалена.Нет необходимости звонить delete на этот.

0 голосов
/ 18 июня 2010

В этом разделе рассматриваются два важных аспекта C ++: явные указатели и динамическая память.Краткий ответ заключается в том, что в C ++ все, что нужно для инициализации массива, это объявить его следующим образом:

int a [5][5];

Если вы хотите использовать переменную для размера массива, это должно бытьconst int:

const int n = 5;
int b [n];

Имейте в виду, однако, что большая часть функциональности массивов в Java не существует в C ++.Например, не существует простого атрибута «length».

Длинный ответ: найдите две темы, упомянутые выше, в частности, с точки зрения массивов и ключевого слова «new», а также «const»."ключевое слово.Понимание этих идей жизненно важно для использования C ++;

0 голосов
/ 18 июня 2010

В C ++ вы можете объявить двумерный int-массив заранее определенного размера, используя int a[30][10];.

Вы можете выделить новые массивы с помощью new в Java, потому что массивы являются объектами и, следовательно, их необходимо создавать с использованием new в Java. Но C ++ не заставляет вас создавать все, используя new.

Конечно, было бы без проблем ввести этот новый синтаксис для объявления массивов также в C ++, но зачем вводить новый синтаксис, если «каждый» используется для существующего?

Обратите внимание, что вы не можете объявить 2-мерный массив с размерами, определенными во время выполнения с использованием int arr[n][m]. Вы должны создать массив массивов, представляющих 2-мерный массив, используя int **arr = new int[n][m], то есть в C ++ массив указателей, указывающих на каждый подмассив. Аналогично для многомерных массивов.

Еще один способ для многомерных массивов - объявить только одномерный массив и соответствующим образом вычислить индексы. Однако это предполагает некоторые мысли о том, как организовать данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...