Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/26: Рейтинг темы: голосов - 26, средняя оценка - 4.92
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 53

Многомерные массивы

11.11.2012, 20:31. Показов 5128. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
Есть необходимость использования как одномерных так и многомерных массивов. В связи с этим возникло 2 вопроса:
1. При объявлении одномерного массива
C++
1
int mas[5];
проблем никаких нету, но вот если использовать
C++
1
2
int NamberOfWells = StrToInt(Edit_NamberOfWell->Text);
int mas[NamberOfWells];
то выдается ошибка: "[BCC32 Error] Unit3.cpp(60): E2313 Constant expression required"
Возможно ли реализовать подобным образом одномерный массив или же другого выхода нет как использовать:
C++
1
2
int NamberOfWells = StrToInt(Edit_NamberOfWell->Text);
int *DepthOfWell = new int[NamberOfWells];
2. Многомерные массивы
А вот случай с многомерными массивами обстоит немного сложнее, есть потребность использовать 3-5 мерные массивы. Если использовать код
C++
1
int mas[5][5][5][5];
то все отлично, но вот проблема в том что там должны быть переменные, соответственно как и в случае с одномерным массивом если использовать
C++
1
2
3
4
5
int a=5;
int b=5;
int c=5;
int d=5;
int mas[a][b][c][d];
то выдается ошибка.
Соответственно и вопрос, возможно ли (если да, то как) сделать одномерный/многомерный массив по типу:
C++
1
2
3
4
5
int a=5;
int b=5;
int c=5;
int d=5;
int mas[a][b][c][d];
Заранее благодарю!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.11.2012, 20:31
Ответы с готовыми решениями:

Многомерные массивы, как перебирать внутренние массивы
Здравствуйте. Такой учебный код и плохо понимаю как перебираются внутренние массивы, может кто пояснит подоходчивее. Именно внутренний...

Многомерные массивы: перевернуть массив как "кубик-рубик" и группировка в массивы порядка выше
Здравствуйте, 1) Мне дан 3-мерный массив, куб данных, который я пробую перевернуть. Т.е массив размерности (A x B x C)...

Многомерные массивы
Вычислить сумму и число положительных элементов матрицы A находящихся над главной диагональю.

19
 Аватар для Gremlin
519 / 307 / 58
Регистрация: 30.07.2008
Сообщений: 607
11.11.2012, 20:51
это называется Динамический массив

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    //Одномерный динамический массив
    int a = 5;
    int *r = new int[a];
    for(int i = 0; i < a; i++)
    {
        r[i] = GetTickCount();
        Memo1->Lines->Add(r[i]);
    }
    delete r;
 
    //Двумерный динамический массив
    int len1 = 8;
    int len2 = 9;
    int **Arr = new int*[len1];
    for(int i = 0; i < len1; i++)
    {
        Arr[i] = new int[len2];
    }
    Arr[1][1] = 4444;
 
    //Трехмерный динамический массив
    int l1 = 8;
    int l2 = 9;
    int l3 = 10;
    int ***Arra = new int**[l1];
    for(int i = 0; i < l1; i++)
    {
        Arra[i] = new int*[l2];
        for(int u = 0; u < l2; u++)
        {
            Arra[i][u] = new int[l3];
        }
    }
    Arra[1][1][1] = 9;
    // дальше потихоньку мозги плавится начинают ...
0
95 / 64 / 5
Регистрация: 03.07.2011
Сообщений: 148
11.11.2012, 21:27
Почитай про шаблоны классов DynamicArray и vector - они позволяют создавать многомерные динамические массивы.
0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 53
11.11.2012, 23:48  [ТС]
Цитата Сообщение от Gremlin Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Трехмерный динамический массив
    //Трехмерный динамический массив
    int l1 = 8;
    int l2 = 9;
    int l3 = 10;
    int ***Arra = new int**[l1];
    for(int i = 0; i < l1; i++)
    {
        Arra[i] = new int*[l2];
        for(int u = 0; u < l2; u++)
        {
            Arra[i][u] = new int[l3];
        }
    }
    Arra[1][1][1] = 9;
    // дальше потихоньку мозги плавится начинают ...
Вот в том то и проблема, а у меня предполагается работа с многими 3-5 мерными масивами. По этому и искал вариант упрощения данной операции.
0
872 / 448 / 35
Регистрация: 25.10.2011
Сообщений: 910
12.11.2012, 10:47
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Gremlin Посмотреть сообщение
C++
1
2
3
4
5
6
7
int *r = new int[a];
for(int i = 0; i < a; i++)
{
  r[i] = GetTickCount();
  Memo1->Lines->Add(r[i]);
}
delete r;
delete[]
Цитата Сообщение от maxkod Посмотреть сообщение
Вот в том то и проблема, а у меня предполагается работа с многими 3-5 мерными масивами. По этому и искал вариант упрощения данной операции.
Самый оптимальный вариант - обернуть все Ваши действия в отработанный класс, ориентированный под Вашу задачу, иначе мозги закипят после 3-4го выделения памяти под 3-5мерный массив. Хотя могу сказать, что на практике, даже 2мерного массива бывает достаточно для большинства случаев. Но если поток данных нужно обрабатывать именно в таком ключе, то внимательно ознакомьтесь с теорией по выделению и освобождению памяти и учтите, что если речь пойдет об абстрактных данных, то данные процессы будут касаться каждого элемента массива.

Как уже было сказано выше - уделите время векторам. Они "проще" в использовании, но если не знать основы можно забить память по самые гланды и не заметить.

Для реального упрощения работы с массивами (как себе, так и ЦП) - рекомендую обратить внимание на методы: ZeroMemory, memset, memcpy и т.п.

И самый лучший друг при работе с динамикой это NULL, а если говорить точнее: освободили память, присвоили указателю 0. Во-первых, если будет происходить обращение по невалидному адресу об этом сразу будет получено сообщение во всех красках. Во-вторых, Вы всегда будет знать, была ли очищена память элементарной проверкой и неперепишите нужный указатель за зря. И в-третьих, это остановит "повторное освобождение памяти". На самом деле, контрольное освобождение в голову - могут получить совсем не те данные, которые находились по старому адресу.
4
12.11.2012, 10:59

Не по теме:

Цитата Сообщение от DefineTrueFalse Посмотреть сообщение
контрольное освобождение в голову
:rofl:

0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 53
12.11.2012, 23:53  [ТС]
а как более правельно удалять многомерный массив?
C++
1
2
3
4
// удаляем
for(size_t i = 0; i < 2; ++i)
    delete[] Points[i];
delete[] Points;
или достаточно
C++
1
2
// удаляем
delete[] Points;
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
13.11.2012, 00:03
А это как правило правой руки на дороге, так же просто - на каждый new должен быть свой delete, то бишь как выделял, так и освобождай.
0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 53
13.11.2012, 16:07  [ТС]
Мне не совсем понятно удаление массива. Когда я создаю массив, а затем сразу его удаляю и запрашиваю значения, то они не удаляются.
C++
1
2
3
4
5
6
7
int *DepthOfWell = new int[NamberOfWells];
for (i = 1; i < 120; i++) {
    DepthOfWell[i]=i;
}
ShowMessage(DepthOfWell[100]);
delete[] DepthOfWell;
ShowMessage(DepthOfWell[100]);
И первый ShowMessage и второй выдает значение 100, хотя первый должен был выдать 100, а второй показать что ячейка пуста. Или я не прав?
0
return (true);
 Аватар для mimicria
1977 / 1112 / 221
Регистрация: 19.04.2011
Сообщений: 2,346
13.11.2012, 16:17
После delete не всегда из памяти выгружаются подключенные страницы, особенно если они в середине кучи. Просто они помечаются как свободные и при повторном запросе на выделение памяти могут быть использованы, если хватает объема. Это ускоряет процесс динамического выделения памяти, которые является довольно ресурсоемким.
0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 53
13.11.2012, 23:01  [ТС]
И еще я столкнулся с одной проблемой. Для упрощения кода я хочу использовать процедуры и в коде просто ссылаться на них, для этого мне необходимо чтобы мой массив был доступен во всех процедурах. Когда вставляю int *DepthOfWell = new int[NamberOfWells]; над процедурами, то программы выполняется, но при закрытии окна программы выдается ошибка Project Project2.exe raised exception class EInvalidPointer with message "Invalid pointer operation".
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <vcl.h>
#pragma hdrstop
#include <ComObj.hpp>
#include <OleServer.hpp>
#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainFormPHG *MainFormPHG;
 
Variant mExcel, WorkBook, Worksheet, cell;
AnsiString LocationOfModel;
int i, NamberOfWells;
//создание матрици начало
int *DepthOfWell = new int[NamberOfWells];
//создание матрици конец
//---------------------------------------------------------------------------
__fastcall TMainFormPHG::TMainFormPHG(TComponent* Owner)
    : TForm(Owner)
{
 
}
//---------------------------------------------------------------------------
void __fastcall TMainFormPHG::Button_TESTClick(TObject *Sender)
{
NamberOfWells = StrToInt(Edit_NamberOfWell->Text);
for ( i = 1; i < 120; i++) {
    DepthOfWell[i]=i;
}
ShowMessage(DepthOfWell[100]);
delete[] DepthOfWell;
}
А если int *DepthOfWell = new int[NamberOfWells]; перемещу в процедуру,
C++
1
2
3
4
5
6
7
8
9
10
void __fastcall TMainFormPHG::Button_TESTClick(TObject *Sender)
{
NamberOfWells = StrToInt(Edit_NamberOfWell->Text);
int *DepthOfWell = new int[NamberOfWells];
for ( i = 1; i < 120; i++) {
    DepthOfWell[i]=i;
}
ShowMessage(DepthOfWell[100]);
delete[] DepthOfWell;
}
то никаких ошибок при закрытии программы не возникает. С чем может быть связанна данная проблема?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
13.11.2012, 23:48
Зачем тыкать пальцем в небо? Почему не почитать про классы, данные и методы? ... но это лишь риторика...
Объявляй указатель DepthOfWell в классе формы, выделяй память под массив в конструкторе формы, освобождай в деструкторе. Все элементарно.
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
14.11.2012, 00:00
вне ф-ций можно только объявлять переменные, но нельзя писать код программы.
0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 53
14.11.2012, 00:41  [ТС]
Цитата Сообщение от BRcr Посмотреть сообщение
Зачем тыкать пальцем в небо? Почему не почитать про классы, данные и методы? ... но это лишь риторика...
Объявляй указатель DepthOfWell в классе формы, выделяй память под массив в конструкторе формы, освобождай в деструкторе. Все элементарно.
Просто дело в том что я не программист, builder изучаю в свободное время, не могли бы Вы подробнее описать что мне необходимо сделать?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
14.11.2012, 11:04
Выложи код Unit3.h и Unit3.cpp - я поправлю, как описывал.
0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 53
14.11.2012, 13:42  [ТС]
Unit3.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <ComObj.hpp>
#include <OleServer.hpp>
#include<math.h>
#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainFormPHG *MainFormPHG;
int i, NamberOfWells;
int *DepthOfWell;
//---------------------------------------------------------------------------
__fastcall TMainFormPHG::TMainFormPHG(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainFormPHG::Button_TESTClick(TObject *Sender)
{
NamberOfWells = StrToInt(Edit_NamberOfWell->Text);
DepthOfWell = new int[NamberOfWells];
for (i = 1; i < 11; i++)
    {
    DepthOfWell[i] = i;
    }
    delete [] DepthOfWell;
    DepthOfWell = NULL;
}
Unit3.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//---------------------------------------------------------------------------
#ifndef Unit3H
#define Unit3H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TMainFormPHG : public TForm
{
__published:    // IDE-managed Components
    TPanel *Panel1;
    TButton *Button_Start;
    TLabel *Label_NamberOfWell;
    TEdit *Edit_NamberOfWell;
    TButton *Button_TEST;
    TLabel *Label_LocationOfModel;
    TEdit *Edit_LocationOfModel;
    void __fastcall Button_TESTClick(TObject *Sender);
private:    // User declarations
public:     // User declarations
    __fastcall TMainFormPHG(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TMainFormPHG *MainFormPHG;
//---------------------------------------------------------------------------
#endif
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
14.11.2012, 15:43
Примерно вот так.
Выделение памяти по необходимости:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//---------------------------------------------------------------------------
// .hpp ---------------------------------------------------------------------
//---------------------------------------------------------------------------
class TMainFormPHG 
        : public TForm {
__published:    // IDE-managed Components
    TPanel *Panel1;
    TButton *Button_Start;
    TLabel *Label_NamberOfWell;
    TEdit *Edit_NamberOfWell;
    TButton *Button_TEST;
    TLabel *Label_LocationOfModel;
    TEdit *Edit_LocationOfModel;
    void __fastcall Button_TESTClick( TObject *Sender );
private:    // User declarations
public:     // User declarations
    int *DepthOfWell, NumberOfWells;
    __fastcall TMainFormPHG( TComponent* Owner );
    __fastcall ~TMainFormPHG( ){ if ( DepthOfWell ) delete [] DepthOfWell; }
};
//---------------------------------------------------------------------------
// .cpp ---------------------------------------------------------------------
//---------------------------------------------------------------------------
__fastcall TMainFormPHG::TMainFormPHG(TComponent* Owner)
    : TForm(Owner){
    NumberOfWells = 0;
    DepthOfWell = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TMainFormPHG::Button_TESTClick(TObject *Sender) {
    if ( DepthOfWell ) {
        delete [] DepthOfWell;
        DepthOfWell = NULL;
    }   
    NumberOfWells = StrToInt(Edit_NamberOfWell->Text);
    if ( NumberOfWells <= 0 ) return;
    DepthOfWell = new int[NumberOfWells];
    for ( int i = 0; i < NumberOfWells; ++i ){
        DepthOfWell[i] = i;
    }
}
Выделение на этапе конструирования:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//---------------------------------------------------------------------------
// .hpp ---------------------------------------------------------------------
//---------------------------------------------------------------------------
class TMainFormPHG 
        : public TForm {
__published:    // IDE-managed Components
    TPanel *Panel1;
    TButton *Button_Start;
    TLabel *Label_NamberOfWell;
    TEdit *Edit_NamberOfWell;
    TButton *Button_TEST;
    TLabel *Label_LocationOfModel;
    TEdit *Edit_LocationOfModel;
    void __fastcall Button_TESTClick( TObject *Sender );
private:    // User declarations
public:     // User declarations
    int *DepthOfWell, NumberOfWells;
    __fastcall TMainFormPHG( TComponent* Owner );
    __fastcall ~TMainFormPHG( ){ if ( DepthOfWell ) delete [] DepthOfWell; }
};
//---------------------------------------------------------------------------
// .cpp ---------------------------------------------------------------------
//---------------------------------------------------------------------------
__fastcall TMainFormPHG::TMainFormPHG(TComponent* Owner)
    : TForm(Owner){
    NumberOfWells = 10;
    DepthOfWell = new int[NumberOfWells];
}
//---------------------------------------------------------------------------
void __fastcall TMainFormPHG::Button_TESTClick(TObject *Sender) {
    if ( !DepthOfWell ) return;
    for ( int i = 0; i < NumberOfWells; ++i ){
        DepthOfWell[i] = i;
    }
}
1
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 53
14.11.2012, 23:22  [ТС]
спасибо!

Добавлено через 1 час 50 минут
если я правельно понимаю
C++
1
__fastcall ~TMainFormPHG( ){ if ( DepthOfWell ) delete [] DepthOfWell; }
является деструктором и при добавлении массивов в различных функциях мне необходимо удалять новый массив в данном деструторе вне зависимости в какой функции я его использую?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    __fastcall ~TMainFormPHG( )
    {
        if ( DepthOfWell ) 
        {
        delete [] DepthOfWell;
        DepthOfWell = NULL;
        }
 
        if ( DepthOfNKT ) 
        {
        delete [] DepthOfNKT;
        DepthOfNKT = NULL;
        }
    }
И еще вопрос деструктор запускается автоматически при закрытии программы или же его необходимо дополнительно как то вызывать?
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
15.11.2012, 00:01
Деструктор всегда вызывается автоматически при удалении объекта класса, т.е. в вашем случае при закрытии формы. В ручную его вызывать не надо.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
15.11.2012, 00:45
Цитата Сообщение от maxkod Посмотреть сообщение
при добавлении массивов в различных функциях мне необходимо удалять новый массив в данном деструторе вне зависимости в какой функции я его использую?
Так можно делать и так вполне надежно, но я бы не назвал это необходимым. Главное - корректно освобождать память, путей же к этому достаточно.
Например, самостоятельно определять момент освобождения, когда память уже не нужна и учитывать, порой, множество взаимосвязей, вводить проверки, подстраховки. Новичкам рекомендуется в качестве тренировки.
А можно вообще все свалить на плечи уборщиков - различных классов для хранения указателей, таких, как auto_ptr.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.11.2012, 00:45
Помогаю со студенческими работами здесь

Многомерные массивы
Здравствуйте! Подскажите, как сделать массив, изменяющий количество измерений в зависимости от прочитанных данных?

Многомерные массивы
1)Для матрицы вычислить:максимальный элемент побочной диагонали, n = 7; min = 3; max = 9; 2)Задана матрица размером N×M. Получить...

Многомерные массивы
Помогите решить плз. Заданы матрица порядка n и число k. Разделить элементы k-ой строки на диагональный элемент, расположенный в этой...

Многомерные массивы.
Вот и пришли ещё чудеснее времена.. Только кое-как разобрался с одномерными массивами.. Задали многомерные. вот задачи.. помогите...

Многомерные массивы
В массиве X(n,m) найти среднее арифметическое тех элементов, квадраты которых не превышают заданную величину А.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru