Одномерный статический (с заранее известным размером)массив (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;
Преимущества — сохраняется семантика работы с двумерным массивом
Недостатки — невозможно проверять корректность второгл индекса.
Здравствуйте, potap, Вы писали:
P>Не чувствую, что в этом более здорового .
P>Требовалось: P>1. иметь некоторую переменную p- начальный адрес ЕДИНОГО куска памяти с данными. P>2. обращаться к элементам массива — p[i][j]. P>3. на этапе компиляции неизвестны пределы, в которых будут меняться i и j.
ну может тогда так:
class xxx
{
char data;
public:
char& operator [](int i) {return data;}
};
//...
xxx * p = new xxx [M * N];
p[i][j] = 0;
//...
И все-таки почитай топик, ссылку на который я дал ниже.
Любите книгу — источник знаний (с) М.Горький
Re[6]: двумерный динамический массив
От:
Аноним
Дата:
28.11.02 09:49
Оценка:
Он (потап) говорит о представлении массива в памяти. Если есть int a[5][5];
Можно написать int * pD1 = *a; и далее писать p[i_num*5+j_num] = 10; или a[i_num][j_num] = 10;
Здравствуйте, potap, Вы писали:
P>Люди, просветите плиз.
P>Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)).
P>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
P>Спасибо за возможные ответы.
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, potap, Вы писали:
P>>Не чувствую, что в этом более здорового :???: .
P>>Требовалось: P>>1. иметь некоторую переменную p- начальный адрес ЕДИНОГО куска памяти с данными. P>>2. обращаться к элементам массива — p[i][j]. P>>3. на этапе компиляции неизвестны пределы, в которых будут меняться i и j.
B>
Здравствуйте, potap, Вы писали:
P>Люди, просветите плиз.
P>Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)).
P>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
Нет, с точки зрения машинного представления, разницы между 1-мерным и n-мерным массивом (если не рассматривать масивы а-ля Java). Это в том и в другом случае некоторая область памяти. Есть разница, с точки зрения компилятора и программера в способе адресации этой памяти. Так для получения элемента одномерного массива TYPE A[n], мы пишем A[i], что буквально означает
*((char*)A + (char)sizeof(TYPE)*i)). Для двумерного массива TYPE A[m][n], выражение A[i][j], будет означать
*((char*)A + (char)sizeof(TYPE)*i) + (char)sizeof(TYPE)*j) и т.д.
Т.е. можно прописать некий класс с соответствующими конструкторами и набором операторов ( типа (int i, int j) ), в котором сам массив
будет представлен в виде непрерывной области памяти, а задача распределения и адресации этой памяти реализуется при помощи функций-членов.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Здравствуйте, potap, Вы писали:
P>Люди, просветите плиз.
P>Одномерный статический (с заранее известным размером)массив (char a[5]) легко переводится в одномерный динамический (с заранее НЕизвестным размером) массив (char* a=malloc(n)).
P>А как быть с двумерным (и более) массивом. Как перевести char a[5][7] в nxm динамический массив.
P>Спасибо за возможные ответы.
Привет, вот небольшой пример создания двумерного массива:
#include <stdio.h>
#include <stdlib.h>
typedef int T;
T **Allocate(size_t m, size_t n)
{
int **a;
int *p;
size_t Row;
a = malloc(m * n * sizeof **a + m * sizeof *a);
if(a != NULL)
{
for(Row = 0, p = (T *)a + m; Row < m; Row++, p += n)
{
a[Row] = p;
}
}
return a;
}
вместо T можешь подставить любой другой тип.
Пока.
Трудно ничего не делать, но мы не боимся трудностей.