Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)).
А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
Здравствуйте, potap, Вы писали:
P>Люди, просветите плиз.
P>Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)).
char * — это указатель на char, а не динамический массив.
P>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
Здравствуйте, potap, Вы писали:
P>Люди, просветите плиз.
P>Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)).
P>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
P>Спасибо за возможные ответы.
Двумерный массив — это одномерный массив указателей на одномерные массивы.
Динамически можно организовать, например так:
const int width=5,height=7;
int **a;
// создание
a=malloc(sizeof(int*)*width);
for(int i=0;i<width;i++)a[i]=malloc(sizeof(int)*height);
a[1][1]=10;
a[4][6]=1;
// удалениеfor(i=0;i<width;i++)free(a[i]);
free(a);
Здравствуйте, potap, Вы писали:
P>Люди, просветите плиз.
P>Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)).
P>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
P>Спасибо за возможные ответы.
char * p = new char [M * N];
p[i][j] -->> p[i*N + j];
Re[2]: Динамическим по одному или обоим измерениям?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, potap, Вы писали:
P>>Люди, просветите плиз.
P>>Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)). А>char * — это указатель на char, а не динамический массив.
P>>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
А>char (*p)[5] = new char[5][7]; А>p[0][0] = 'x';
Ты, наверное, хотел сказать
char (*p)[5] = new char[5][n];//Вместо 7 — n А>p[0][0] = 'x';
Но, насколько я понимаю — 5 в m никак не превратится, а мне заранее не известны оба измерения.
Здравствуйте, potap, Вы писали:
P>Люди, просветите плиз.
P>Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)).
P>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
P>Спасибо за возможные ответы.
Здравствуйте, Volnin L.V., Вы писали:
VLV>Двумерный массив — это одномерный массив указателей на одномерные массивы.
Если говорить про обычный (статический) массив, то это, имхо, неверно. Двумерный статический массив 5x7- это одномерный массив длиной 5x7=35. Данные лежат по строкам. Т.е. это не char** а char*.
VLV>Динамически можно организовать, например так:
VLV>[ccode] VLV>const int width=5,height=7; VLV>int **a; VLV>// создание VLV>a=malloc(sizeof(int*)*width); VLV>for(int i=0;i<width;i++)a[i]=malloc(sizeof(int)*height);
В данной реализации, как я уже говорил, данные будут храниться не компактно, а кусками по height. А это, согласись, совершенно не эквивалентно статическому двумерному массиву. Кроме того, ничто тебе не мешает сделать "неровный", "рваный" массив — с неодинаковыми height, а мне это не нужно. У тебя char**, а мне нужно char*.
Здравствуйте, potap, Вы писали:
P>Люди, просветите плиз.
P>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
я бы сделал так:
class Array
{
int n, m;
char** p;
public:
Array(int nRow, int nCol)
{
n = nRow;
m = nCol;
p = new char* [n];
for(int i = 0; i < n; i++)
p[i] = new char[m];
}
~Array()
{
for(int i = 0; i < n; i++)
{
delete []p[i];
p[i] = NULL;
}
delete []p;
}
char Get(int i, int j)
{return p[i][j];}
char Set(int i, int j, char ch)
{return p[i][j] = ch;}
};
Хотя можно, наверно, как-то хитрее исподвыподвернуться....
Здравствуйте, potap, Вы писали:
P>Здравствуйте, Volnin L.V., Вы писали:
VLV>>Двумерный массив — это одномерный массив указателей на одномерные массивы. P>Если говорить про обычный (статический) массив, то это, имхо, неверно. Двумерный статический массив 5x7- это одномерный массив длиной 5x7=35. Данные лежат по строкам. Т.е. это не char** а char*.
Насколько я понимаю, это единственно реальный способ. В-общем, я обычно так и делаю, для удобства задефайнив последнюю строку
#define P(i,j) p[i*N + j]
kmn>char * p = new char [M * N];
kmn>p[i][j] -->> p[i*N + j];
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, potap, Вы писали:
P>>Здравствуйте, Volnin L.V., Вы писали:
VLV>>>Двумерный массив — это одномерный массив указателей на одномерные массивы. P>>Если говорить про обычный (статический) массив, то это, имхо, неверно. Двумерный статический массив 5x7- это одномерный массив длиной 5x7=35. Данные лежат по строкам. Т.е. это не char** а char*.
B>Неверно.
Требовалось:
1. иметь некоторую переменную p- начальный адрес ЕДИНОГО куска памяти с данными.
2. обращаться к элементам массива — p[i][j].
3. на этапе компиляции неизвестны пределы, в которых будут меняться i и j.
Здравствуйте, wasilij, Вы писали:
W>Здравствуйте, kmn, Вы писали:
kmn>>char * p = new char [M * N];
kmn>>p[i][j] -->> p[i*N + j];
W>Помоему, это то, что и требовалось, если еще добавить:
W>
Здравствуйте, potap, Вы писали:
P>Что именно неверно? Уточни, пожалуйста.
То, что "двумерный статический массив 5x7- это одномерный массив длиной 5x7=35. Данные лежат по строкам."
То, что все элементы двумерного статического массива лежат в одном блоке памяти, вовсе не означает, что это одномерный массив. К одномерному массиву нельзя применить [][], к двумерному — можно.
P>"Т.е. это не char** а char*."
Это ни то, и не другое. Это char[5][7].
Здравствуйте, potap, Вы писали:
P>Не чувствую, что в этом более здорового .
P>Требовалось: P>1. иметь некоторую переменную p- начальный адрес ЕДИНОГО куска памяти с данными. P>2. обращаться к элементам массива — p[i][j]. P>3. на этапе компиляции неизвестны пределы, в которых будут меняться i и j.
template<typename T>
class Arr
{
T* m_pData;
int m_nRows;
...
public:
Arr(int nRows, int nColumns) : m_nRows(nRows) { m_pData = new T[nRows*nColumns]; }
...
T* operator[] (size_t n) { return m_pData + n*m_nRows; }
...
};
использование:
Arr<int> arr(5, 7);
arr[1][2] = 3;
Преимущества — сохраняется семантика работы с двумерным массивом
Недостатки — невозможно проверять корректность второгл индекса.