Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как объявить двумерный массив с переменной в размере.

12K
14 сентября 2006 года
andrystepa
24 / / 08.06.2006
Проблема такая: хочу объявить двумерный массив, одна из размерностей которого задается переменной.
С одномерным массивом все получается просто:
int size1;
cin>>size1;
int* p_mas;
p_mas=new int[size1];
Все нормально компилируется и работает (пример проверял в Visual Studio.Net 2005). Теперь слегка видоизменяю программу:
int size1, size2;
cin>>size1>>size2;
int* p_mas;
p_mas=new int[size1][size2];
При компиляции выдается такая ошибка:
Error 1 error C2540: non-constant expression as array bound c:\programming\visual studio 2005 projects\probe\probe\probe.cpp
Error 2 error C2440: '=' : cannot convert from 'int (*)[1]' to 'int *' c:\programming\visual studio 2005 projects\probe\probe\probe.cpp

обе ошибки относятся к строке:
p_mas=new int[size1][size2];

Почему это происходит? В чем отличие этой строки от первоначального варианта с одномерным массивом?
Заранее благодарен за помощь!
14K
14 сентября 2006 года
wrap
35 / / 02.06.2006
Двумерный динамический массив создается так:
 
Код:
int rows, cols;

cin >> rows >> cols;

int **pArray = new int*[rows];

for(int i = 0; i < rows; i++)
  pArray = new int[cols];
12K
15 сентября 2006 года
andrystepa
24 / / 08.06.2006
[QUOTE=wrap]Двумерный динамический массив создается так:
 
Код:
int rows, cols;

cin >> rows >> cols;

int **pArray = new int*[rows];

for(int i = 0; i < rows; i++)
  pArray = new int[cols];
[/QUOTE]
То есть, как я понял, надо создавать одномерный массив одномерных массивов. Видимо и с другими многомерными массивами надо поступать точно так же?
14K
15 сентября 2006 года
wrap
35 / / 02.06.2006
Да. Любой многомерный массив является массивом массивов. В приведенном примере следует обратить внимание на то, что элементы двумерного массива уже не будут располагаться в памяти последовательно по строкам, как это было бы в случае встроенного двумерного массива. Обращение же к элементам массива выглядит так же
 
Код:
pArray[j]
Разница будет заключаться в вычислении адреса элемента массива компилятором.
12K
15 сентября 2006 года
andrystepa
24 / / 08.06.2006
Спасибо, вроде все работает, но как-то странно:
Такая вот тестовая программа
Код:
#include<iostream>
#include<iomanip>
using namespace std;

int main() {
    cout<<"Enter two num >";
    int sizerow, sizecol;
    cin>>sizerow>>sizecol;
    int** p_mas;
    p_mas=new int*[sizecol];
    for(int i=0; i<sizecol; i++) p_mas=new int[sizerow];
    for(int j=0; j<sizecol; j++) {
    for(int i=0; i<sizerow; i++) p_mas[j]=i*j;
        }
    for(int j=0; j<sizecol; j++) {
        for(int i=0; i<sizerow; i++) {
            cout<<setw(8)<<"mas["<<i<<","<<j<<"]= ";
            cout<<setw(5)<<p_mas[j]<<" | "; }
        cout<<endl;
        }
    cout<<" Enter Y >";
    char y;
    cin>>y;
    return 0;
    }

вроде работает, но при вводе некоторых размеров, например 4 10 зависает, выведя только такую строку:

mas[

и все. Виснем напрочь. Но если ввести меньшие значения, например 4 8 (если 9, то уже виснем), то все работает нормально. Более того, под отладчиком программа работает без проблем, нигде не виснет. Если поставить брейкпойнт на эту строчку, то все там как и должно быть при нормальной работе программы. Да и без брейкпойнта, но под отладчиком все ОК. В чем может быть проблема?
350
15 сентября 2006 года
cheburator
589 / / 01.06.2006
[QUOTE=andrystepa]
Код:
#include<iostream>
#include<iomanip>
using namespace std;

int main() {
    cout<<"Enter two num >";
    int sizerow, sizecol;
    cin>>sizerow>>sizecol;
    int** p_mas;
    p_mas=new int*[sizecol];
    for(int i=0; i<sizecol; i++) p_mas=new int[sizerow];
    for(int j=0; j<sizecol; j++) {
    for(int i=0; i<sizerow; i++) p_mas[j]=i*j;
        }
    for(int j=0; j<sizecol; j++) {
        for(int i=0; i<sizerow; i++) {
            cout<<setw(8)<<"mas["<<i<<","<<j<<"]= ";
            cout<<setw(5)<<p_mas[j]<<" | "; }
        cout<<endl;
        }
    cout<<" Enter Y >";
    char y;
    cin>>y;
    return 0;
    }

вроде работает, но при вводе некоторых размеров, например 4 10 зависает...[/QUOTE]
Брат, а ты случаем с измерениями не напутал? Первое измерение меняется от 0 до sizecol, второе - от 0 до sizerow (по крайней мере, так у тебя происходит выделение памяти). А вот в этом блоке:
 
Код:
for(int j=0; j<sizecol; j++) {
    for(int i=0; i<sizerow; i++) p_mas[j]=i*j;
        }

у тебя как-то всё наоборот. Замени на p_mas[j]. И дальше, при выводе на экран, то же самое.
И кстати, почему бы тебе циклы присвоения и вывода на экран не объединить?
3
15 сентября 2006 года
Green
4.8K / / 20.01.2000
Ты задаешь вопрос из академических интересов или тебе действительно необходим многомерный динамически алоцируемый контейнер?

Не проще ли тогда воспользоваться стандартными контейнерами, например, std::vector?
Тогда пример создания двумерного массива будет выглядеть так:
 
Код:
vector< vector<int> > mas( sizecol, vector<int>(sizerow) );
12K
17 сентября 2006 года
andrystepa
24 / / 08.06.2006
[QUOTE=cheburator]Брат, а ты случаем с измерениями не напутал? Первое измерение меняется от 0 до sizecol, второе - от 0 до sizerow (по крайней мере, так у тебя происходит выделение памяти). А вот в этом блоке:
 
Код:
for(int j=0; j<sizecol; j++) {
    for(int i=0; i<sizerow; i++) p_mas[j]=i*j;
        }

у тебя как-то всё наоборот. Замени на p_mas[j]. И дальше, при выводе на экран, то же самое.
И кстати, почему бы тебе циклы присвоения и вывода на экран не объединить?[/QUOTE]

Спасибо! Дело действительно именно в неверном обозначении измерений!
Вот только второй вопрос все-таки висит - почему программа совершенно нормально работала под отладчиком?!! Из-за этого, собственно, я и не смог понять причину ошибки - ведь при отладке никаких ошибок не было!!! Более того, непонятно, почему программа висла, выведя mas[ - переменные i, j да и вообще всю первую строку она должна была выдать на гора - к моменту вывода на экран как минимум элемент массива mas[j] был полностью определен!
12K
17 сентября 2006 года
andrystepa
24 / / 08.06.2006
[QUOTE=Green]Ты задаешь вопрос из академических интересов или тебе действительно необходим многомерный динамически алоцируемый контейнер?

Не проще ли тогда воспользоваться стандартными контейнерами, например, std::vector?
Тогда пример создания двумерного массива будет выглядеть так:
 
Код:
vector< vector<int> > mas( sizecol, vector<int>(sizerow) );
[/QUOTE]

Вопрос действительно скорее академический - это тестовая программка для функции к заданию из учебника. Хотя, меня еще и другая сторона вопроса интересует - какой код будет меньше и быстрее работать - с определенным вручную динамическим массивом, или с массивом определенным посредством вектора?
5.4K
17 сентября 2006 года
Svyatozar
221 / / 11.09.2006
Быстрее будет объявить одномерный массив размером rows * cols.
double *myarray;
myarray = new double[rows * cols];
И считать его массивом m строк по n колонок (как матрица).
Чтобы адресовать элемент (9, 6), к примеру (9 строка 6 колонка):
*(myarray + 8 * cols + 5) = 14.32;
Чтобы определить адрес элемента i:
int col = i % cols;
int row = i / cols;
Так как в Си отсчет начинается с нуля, а в математике матрицы принято индексировать с единицы, то при выводе на печать следует прибавлять 1:
printf("row %d, column %d", i / cols + 1, i % cols + 1);
3
18 сентября 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=andrystepa]какой код будет меньше и быстрее работать - с определенным вручную динамическим массивом, или с массивом определенным посредством вектора?[/QUOTE]
Работать будет одинаково, а размер кода сравни сам:
 
Код:
int **pArray = new int*[rows];

for(int i = 0; i < rows; i++)
  pArray = new int[cols];

 
Код:
vector< vector<int> > mas( sizecol, vector<int>(sizerow) );
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог