Форум программистов, компьютерный форум, киберфорум
Turbo Pascal
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
5 / 5 / 0
Регистрация: 02.01.2013
Сообщений: 438
1

Хранения матриц в динамически распределяемой области памяти

22.02.2018, 23:38. Показов 2015. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Скажите пожалуйста или приведите пример хранения матриц в динамически распределяемой области памяти, для трёх случаев:
а) число строк - константа, а число столбцов - исходное данное;
б) число строк - исходное данное, число столбцов - константа;
в) число строк и число столбцов - исходные данные.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.02.2018, 23:38
Ответы с готовыми решениями:

Реализовать мониторинг использования динамически распределяемой памяти.
Здравствуйте, мне в лабораторке нужно реализовать мониторинг динамически распределяемой памяти....

Двумерные массивы. Использование динамически распределяемой памяти
Уважаемые форумчане, опять нужны ваши подсказки Условие: Создать квадратную матрицу целых чисел и...

Нужно ли удалять указатель на символьный массив созданный в куче(динамически распределяемой памяти)
Подскажите, программа состоит из 2 функций (main и fun), программа меняет значение указателя на...

Разработать способ экономного хранения в памяти разреженных матриц
Помогите плз зделать Задание 1 Разработать способ экономного хранения в памяти разреженных матриц...

12
3406 / 1825 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
23.02.2018, 01:00 2
Лучший ответ Сообщение было отмечено ZX Spectrum-128 как решение

Решение

alex-rudenkiy, думаю код Вам все покамжет.
Pascal
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const
  n=4;
type
  t=array[1..n,1..n]of integer;
var
  a:^t;
  b:pointer;
  c:integer;
  d:array[1..n,1..n]of integer;
procedure CreateArray(a:pointer;b,c:integer);
  var
    i,j:integer;
    d:^integer;
  begin
    d:=a;
    for i:=1 to b do
      for j:=1 to c do
        begin
          d^:=random(100);
          inc(d);
        end;
  end;
procedure WriteArray(a:pointer;b,c:integer);
  var
    i,j:integer;
    d:^integer;
  begin
    d:=a;
    for i:=1 to b do
      begin
        for j:=1 to c do
          begin
            write(d^:3);
            inc(d);
          end;
        writeln
      end;
  end;
begin
  new(a);
  CreateArray(a,n,n);
  WriteArray(a,n,n);
  dispose(a);
  writeln;
  CreateArray(@d,n,n);
  WriteArray(@d,n,n);
  writeln;
  repeat
    write('Enter m:');
    readln(c);
  until c in [n..9];
  GetMem(b,c*sizeof(integer)*n);
  CreateArray(b,n,c);
  writeArray(b,n,c);
  writeln;
  writeArray(b,c,n);
  freeMem(b,c*sizeof(integer)*n);
end.
1
5 / 5 / 0
Регистрация: 02.01.2013
Сообщений: 438
23.02.2018, 12:20  [ТС] 3
Constantin Cat, это я как понял для второго случая когда n-константа, а вот как получится когда число строк и число столбцов - исходные данные? И ещё, как в открытом массиве обращаться к элементу с индексом x,y.
0
3406 / 1825 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
23.02.2018, 13:08 4
Цитата Сообщение от alex-rudenkiy Посмотреть сообщение
это я как понял для второго случая когда n-константа, а вот как получится когда число строк и число столбцов - исходные данные?
Какай разница одна константа или там всё исходные данные(константа, это такое же число, как и введенное пользователем, только после компиляции оно не меняется), память выделяется в процессе работы. Выделите Вы столько, сколько Вам нужно. Посчитали размер и получили нужную память.

Цитата Сообщение от alex-rudenkiy Посмотреть сообщение
И ещё, как в открытом массиве обращаться к элементу с индексом x,y.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure WriteArray(a:pointer;b,c:integer);
  var
    i,j:integer;
    d:^integer;
  begin
    d:=a;
    for i:=1 to b do
      begin
        for j:=1 to c do
          begin
            write(d^:3);
            inc(d);
          end;
        writeln
      end;
    i:=3;
    j:=4;
    d:=a;
    inc(d,(i-1)*c+j-1);
    writeln('a[',i,',',j,']:=',d^);
  end;
По другому компилятор не пропустит.
Если массив определен в типе:
Pascal
1
2
3
4
5
6
7
8
9
10
11
const
  n=10;
type
  tArray=array[1..n]of integer;
var
  a:^tArray;
  b,c,d,m:integer;
begin
  new(a);
. . .
      a^[b]:=random(100);
То тогда можно и так, но там две константы.
0
5 / 5 / 0
Регистрация: 02.01.2013
Сообщений: 438
23.02.2018, 16:46  [ТС] 5
Хорошо, тогда ещё вопрос, вот вы выводите массив, тут цикл, что-то инкрементируется, а вот как вывести именно 1 произвольный элемент?

И ещё вопрос, что делает эта строчка inc(d,(i-1)*c+j-1);?
0
3406 / 1825 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
23.02.2018, 17:50 6
Массив хранится в памяти последовательно.
первая строка : первый, второй, . . ., последний элемент; вторая строка :первый, второй, . . ., последний элемент; . . .; последняя строка : первый, второй, . . ., последний элемент;

Передавая в П/программу указатель на массив - передается адрес первого элемента первой строки, его смещение относительно указателя будет [0,0](как в С/С++), поэтому в строке inc(d,(i-1)*c+j-1) все переменные уменьшаются на 1.
Inc (процедура) Увеличивает значение переменной.
Объявление: Procedure Inc(Var X [ ; N : Longint ] );
Режим: Windows, Real, Protected
Замечания:
Параметр X - переменная перечислимого типа или переменная типа PChar, если допускается расширенный синтаксис, а N - выражение целочисленного типа. Значение X увеличивается на 1, если параметр N не определен, или на N, если праметр N определен, то есть Inc(X) соответствует X:=X+1, а Inc(X, N) соответствует X:=X+N.
Переменная типа PChar, это переменная указательного типа, при работе с ними Inc автоматически умножает N на sizeof(integer) и добавляет к указателю, тем самым перемещая его к нужному элементу.
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
7769 / 4598 / 2823
Регистрация: 22.11.2013
Сообщений: 13,077
Записей в блоге: 1
24.02.2018, 17:38 7
Ну и еще момент для размышления.
Матрицы ТП хранит построчно, но никто не запретит интерпретировать хранение поколоночно Это к вопросу о том, какую часть вычисления адреса можно переложить на собственно компилятор.

Добавлено через 4 минуты
Ах да, другие диалекты Паскаля могут позволять естественную арифметику с указателями, и тогда
Inc(p,n) и Dec(p,n) будут менять указатель на n*SizeOf(p^) байт (то есть, не потребуется домножение на размер элемента).
К сожалению, в ТП это поведение не реализовано.
В ТП 7 указатели масштабируются:
Pascal
1
2
3
4
var p, q: ^Integer;
begin
  Inc(q); WriteLn(PChar(q)-PChar(p));
end.
Прогон:
Код
2
Это значит, что Inc(q) увеличил q не на 1, а на SizeOf(q^).
0
5 / 5 / 0
Регистрация: 02.01.2013
Сообщений: 438
25.02.2018, 12:35  [ТС] 8
Constantin Cat, а как бы это выглядело через absolute ?
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
7769 / 4598 / 2823
Регистрация: 22.11.2013
Сообщений: 13,077
Записей в блоге: 1
25.02.2018, 13:58 9
Когда число столбцов константа, часть адресной арифметики можно легко переложить на компилятор:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const n=5;
type
  TRow: array [0..n-1] of Integer;
  TMatrix: array [0..$FFFE div SizeOf(TRow)-1] of TRow;
 
procedure arElSet(var a; i, j, e: Integer);
var m: TMatrix absolute a;
begin
  m[i,j]:=e;
end;
 
function arElGet(var a; i, j: Integer): Integer;
var m: TMatrix absolute a;
begin
  arElGet:=m[i,j];
end;
Добавлено через 2 минуты
Некоторые компиляторы Pascal (но не ТП) позволяют делать так:
Pascal
1
2
type
  TMatrix: array [0..0] of TRow;
Добавлено через 1 минуту
ТП не даст с этим работать даже при {$R-}, будет давать ошибку выхода за диапазон еще при компиляции (формально он тут прав, но это очень неудобно).

Добавлено через 6 минут
Если вместо номеров от 1 использовать смещения от 0, то "(i-1)*c+j-1" превращается в элегантное "i*c+j".

Добавлено через 5 минут
Когда количество столбцов переменно, удобно использовать такой трюк:
Pascal
1
2
3
4
5
6
7
8
9
10
11
type
  PInteger = ^Integer;
 
function At(a: Pointer; n, i, j: Integer): PInteger;
begin
  At:=PInteger(PChar(a)+(n*i+j)*SizeOf(Integer));
end;
 
...
  At(a,n, 0,0)^ := 0;
  WriteLn('a[0,0] = ',At(a,n, 0,0)^);
или
Pascal
1
2
3
4
function At(a: Pointer; n, i, j: Integer): PInteger;
begin
  Inc(PInteger(a),n*i+j); At:=a;
end;
Добавлено через 3 минуты
Если матрицу можно хранить не единым куском памяти, можно делать массив указателей на строки (или колонки).
1
5 / 5 / 0
Регистрация: 02.01.2013
Сообщений: 438
25.02.2018, 14:41  [ТС] 10
bormant, Кстати очень хочу спросить что означает TMatrix absolute a ?

Добавлено через 6 минут
И как "оформить" например 2 матрицы через absolute?
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
7769 / 4598 / 2823
Регистрация: 22.11.2013
Сообщений: 13,077
Записей в блоге: 1
25.02.2018, 14:44 11
Pascal
1
var m: TMatrix absolute a;
Переменная m типа TMatrix, начало которой расположено по тому же адресу памяти, что и фактически переданный в процедуру параметр a.

Добавлено через 2 минуты
Pascal
1
2
3
4
procedure DoSomething(var a; var b; { остальные параметры });
var
  aa: TMatrix absolute a;
  bb: TMatrix absolute b;
Это если я правильно понял вопрос про "оформить".
0
5 / 5 / 0
Регистрация: 02.01.2013
Сообщений: 438
25.02.2018, 14:53  [ТС] 12
Хорошо а как уместить в одном TMatrix две матрицы например?

Добавлено через 15 секунд
ой, уже увидел

Добавлено через 2 минуты
А как определяется значение(начало расположения матрицы) указателей a и b?

Добавлено через 1 минуту
а, понял a := a +n*i+j;

Добавлено через 4 минуты
только вот теперь не понятно а как для b потом сделать, чтобы a и b не пересекались не дай бог
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
7769 / 4598 / 2823
Регистрация: 22.11.2013
Сообщений: 13,077
Записей в блоге: 1
25.02.2018, 19:21 13
Pascal
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
type
  TElement = Integer;
  PElement = ^TElement;
 
function At(var a; n, i, j: Integer): PElement;
var b: array [0..$FFFE div SizeOf(TElement)-1] of TElement absolute a;
begin
  At:=@(b[i*n+j]);
end;
 
var
  m, n, i, j: Integer;
  a, b: Pointer;
begin
  Write('m n: '); ReadLn(m,n);
  GetMem(a,m*n*SizeOf(TElement));
  GetMem(b,m*n*SizeOf(TElement));
 
  for i:=0 to m-1 do
    for j:=0 to n-1 do begin
      At(a^,n, i,j)^:=i*n+j;
      At(b^,n, i,j)^:=m*n-i*n-j;
    end;
  WriteLn('A =');
  for i:=0 to m-1 do begin for j:=0 to n-1 do Write(At(a^,n, i,j)^:4); WriteLn; end;
  WriteLn('B =');
  for i:=0 to m-1 do begin for j:=0 to n-1 do Write(At(b^,n, i,j)^:4); WriteLn; end;
 
  FreeMem(b,m*n*SizeOf(TElement));
  FreeMem(a,m*n*SizeOf(TElement));
end.
Добавлено через 13 минут
Цитата Сообщение от alex-rudenkiy Посмотреть сообщение
только вот теперь не понятно а как для b потом сделать, чтобы a и b не пересекались не дай бог
Достаточно не менять их руками.

Добавлено через 3 часа 49 минут
Не ваша задачка:
Дана вещественная матрица. Упорядочить ее строки по неубыванию их наибольших элементов

Там пример с кусочной матрицей из строк, адресная арифметика на компиляторе.
0
25.02.2018, 19:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.02.2018, 19:21
Помогаю со студенческими работами здесь

Разработать способ экономического хранения в памяти разреженных матриц
задание Разработать способ экономического хранения в памяти разреженных матриц. Разработать...

Пересылка двух слов из области памяти M1 в область памяти М2
Нужно выполнить пересылку двух слов из области памяти M1 в область памяти М2. Описание области M1:...

Хранения Графа в памяти
Вечер добрый. Есть графы.В них: Точки, рёбра, длины рёбер, координаты точек, точки не имеющие...

Пример использования для хранения описаний объектов предметной области списков
Будьте так любезны, покажите пример использования для хранения описаний объектов предметной области...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru