Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.04.2009, 20:07   #1
world12_tk
Форумчанин
 
Регистрация: 24.02.2009
Сообщений: 269
По умолчанию pascal динамический массив

Добрый вечер... Мне нужно было написать программу, которая вычисляет средне арифметического значения отрицательных элементов квадратной матрицы A(K,K) расположенных под главной диагональю с ипсользованием динамического массива. Саму матрицу считывают из фала и записывают в файл. Размерность динамического массива задается не пользователем, а при помощи определения размера файла. Вот исходный код:
Код:
Код:
program matrix_avg(input, output);
{$R-}
{$N+}
uses CRT;
const
     MAX_DIM = 50;

type
     Matrix = array [1..1, 1..1] of integer;
     Matrix_din=^Matrix;
procedure Send;
begin
    CLRSCR;
    writeln ('Программа для вычисления средне арифметического значения отрицательных элементов квадратной матрицы A(K,K)');
    writeln ('расположенных под главной диагональю');
    writeln ('для продолжении работы нажмите клавишу  Enter');
    readln;
end;

procedure InputFile(var input_name:string;var fin:text);
begin
  writeln('введите имя файла');
  readln(input_name);
  ass8ign(fin,input_name);
  {+$I}
    reset(fin);
  {-$I}

end;
procedure Dinamycs(input_name:string;var matr:matrix_din;var size:longint);
var
    fin_temp:File of char;

begin
    assign(fin_temp,input_name);
    reset(fin_temp);
    size:=FileSize(fin_temp);
    Getmem(matr,size);
    close(fin_temp);

end;

procedure InputMatrix (var fin:text; var dim:integer; var matr:matrix_din);
var
i,j:integer;
begin
    readln(fin,dim);
    for i:=1 to dim do
        for j:=1 to dim do
        begin
            read (fin,matr^[i,j]);
        end;
    close(fin);
end;
procedure OutputMatrix(dim:integer; var matr:matrix_din);
var
i,j:integer;
begin
    writeln('Матрица прочитана успешно');
    for i := 1 to dim do
    begin
        for j := 1 to dim do
              write(matr^[i, j]  , ' ');
              writeln;
     end;
end;

 procedure AverageArithmeticsValueOfMatrix (size:longint;dim:integer; var matr:matrix_din;
           var num_neg: integer;var  sum_neg: double);
 var
    i, j: integer;

 begin
    sum_neg := 0;
    num_neg := 0;
    for i := 2 to dim do
         for j := 1 to i-1 do
              if matr^[i, j] < 0 then
              begin
                   num_neg := num_neg + 1;
                   sum_neg := sum_neg + matr^[i, j];
             end;
   FreeMem(matr,size);
 end;
procedure OutputInFileAverageArithmeticsValueOfMatrix (num_neg:integer; sum_neg:double);
var
sum:double;
    fout:text;
begin
    assign(fout,'output.txt');
    rewrite(fout);
    if num_neg > 0 then
    begin
         sum:= -1*sum_neg/num_neg;
         write(fout,'среднее арифметическое значение под главной диагональю = ',sum:4:3);
    end
    else
         write(fout,'отрицательных элементов под  главной диагональю нет');
    close(fout);
    writeln('результаты программы сохранены в файле OUTPUT.TXT');
    writeln ('для завершении работы нажмите клавишу Enter');
    readln;
end;
var
    matr:Matrix_din;
    dim: integer;
    sum_neg: double;
    num_neg: integer;
    fin:text;
    input_name:string;
    size:longint;
begin
 Send;
 InputFile(input_name,fin);
 Dinamycs(input_name,matr,size);
 InputMatrix (fin,dim,matr);
 OutputMatrix(dim,matr);
 AverageArithmeticsValueOfMatrix (size,dim,matr,num_neg,sum_neg);
 OutputInFileAverageArithmeticsValueOfMatrix (num_neg,sum_neg);

end.
Программа почему то работает не корректно и ошибку исправить не могу. Скорее всего проблема в считывании матрицы...
Помогите мне исправить задачку...
world12_tk вне форума Ответить с цитированием
Старый 21.04.2009, 00:40   #2
Скандербег
Форумчанин
 
Регистрация: 04.04.2009
Сообщений: 438
По умолчанию

Динамические массивы отсутствуют в TP, поэтому приходится изворачиваться с помощью указателей на блоки памяти. При таком расположении данных в памяти индексация тоже допустима, но ДОЛЖНА НАЧИНАТЬСЯ С 0.
Код:
 вместо:
 for i:=1 to dim do
        for j:=1 to dim do
        begin
            read (fin,matr^[i,j]);
  надо:
 for i:=0 to dim-1 do
        for j:=0 to dim-1 do
        begin
            read (fin,matr^[i,j]);
Так должно быть везде где есть индексация ("i, j").

А это вообще полнейший бред:
Код:
begin
    assign(fin_temp,input_name);
    reset(fin_temp);
    size:=FileSize(fin_temp);
    Getmem(matr,size);
    close(fin_temp);
end;
На примере. В файл запишем только число 12000. Какой размер файла? Правильно, 5 байт, а какой будет размер выделенной под него памяти? Правильно, 4 байта (pascal). Теперь запишем в файл число 1. Какой размер файла? Правильно, 1. А памяти? Все равно, 4. Во как.
Память надо выделять по размерности массива учитывая тип данных, а не по размеру файла:
size:= SizeOf(Integer)*dim*dim; {а это долой FileSize(fin_temp);}

Когда код был избавлен от перечисленных выше ошибок, то все заработало на 5.

Последний раз редактировалось Скандербег; 21.04.2009 в 00:42.
Скандербег вне форума Ответить с цитированием
Старый 21.04.2009, 04:30   #3
world12_tk
Форумчанин
 
Регистрация: 24.02.2009
Сообщений: 269
По умолчанию

Цитата:
Когда код был избавлен от перечисленных выше ошибок, то все заработало на 5.
Уважаемый Скандербег. Может я немного туповат, но она все равно не работает, точнее работает также как и было. Вот мой исправленный исходник:
Код:
program matrix_avg(input, output);
{$N+}
{$R-}
uses CRT;
const
     MAX_DIM = 50;

type
     Matrix = array [1..1, 1..1] of integer;
     Matrix_din=^Matrix;
procedure Send;
begin
    CLRSCR;
    writeln ('Программа для вычисления средне арифметического значения отрицательных элементов квадратной матрицы A(K,K)');
    writeln ('расположенных под главной диагональю');
    writeln ('для продолжении работы нажмите клавишу  Enter');
    readln;
end;

procedure InputFile(var dim:integer;var input_name:string;var fin:text;var matr:matrix_din);
var size:integer;
begin
  writeln('введите имя файла');
  readln(input_name);
  assign(fin,input_name);
  {+$I}
    reset(fin);
  {-$I}
      readln(fin,dim);
     size:=SizeOf(integer)*dim*dim;
    Getmem(matr,size);


end;
procedure InputMatrix (var fin:text; dim:integer; var matr:matrix_din);
var
i,j:integer;
begin
    for i:=0 to dim-1  do
        for j:=0 to dim-1 do
        begin
            read (fin,matr^[i,j]);
        end;

end;
procedure OutputMatrix(dim:integer; var matr:matrix_din);
var
i,j:integer;
begin
    writeln('Матрица прочитана успешно');
    for i := 0 to dim-1 do
    begin
        for j := 0 to dim-1 do
              write(matr^[i, j]  , ' ');
              writeln;
     end;
end;

 procedure AverageArithmeticsValueOfMatrix (size:longint;dim:integer; var matr:matrix_din;
           var num_neg: integer;var  sum_neg: double);
 var
    i, j: integer;

 begin
    sum_neg := 0;
    num_neg := 0;
    for i := 2 to dim-1 do
         for j := 0 to i-1 do
              if matr^[i, j] < 0 then
              begin
                   num_neg := num_neg + 1;
                   sum_neg := sum_neg + matr^[i, j];
             end;
   FreeMem(matr,size);
 end;
procedure OutputInFileAverageArithmeticsValueOfMatrix (num_neg:integer; sum_neg:double);
var
sum:double;
    fout:text;
begin
    assign(fout,'output.txt');
    rewrite(fout);
    if num_neg > 0 then
    begin
         sum:= -1*sum_neg/num_neg;
         write(fout,'среднее арифметическое значение под главной диагональю = ',sum:4:3);
    end
    else
         write(fout,'отрицательных элементов под  главной диагональю нет');
    close(fout);
    writeln('результаты программы сохранены в файле OUTPUT.TXT');
    writeln ('для завершении работы нажмите клавишу Enter');
    readln;
end;
var
    matr:Matrix_din;
    dim: integer;
    sum_neg: double;
    num_neg: integer;
    fin:text;
    input_name:string;
    size:longint;
begin
 Send;
 InputFile(dim,input_name,fin,matr);
 InputMatrix (fin,dim,matr);
 OutputMatrix(dim,matr);
 AverageArithmeticsValueOfMatrix (size,dim,matr,num_neg,sum_neg);
 OutputInFileAverageArithmeticsValueOfMatrix (num_neg,sum_neg);
 close(fin);
end.
world12_tk вне форума Ответить с цитированием
Старый 21.04.2009, 06:04   #4
Скандербег
Форумчанин
 
Регистрация: 04.04.2009
Сообщений: 438
По умолчанию

Это, скорее, я туповат. Схитрил в коде, а потом про это забыл. От того и матрица читалась корректно.
Более тщательное исследование и попытки вспомнить что-то про TP окончательно подтвердили прежде смутное опасение.
Индексировать таким образом размещенный в памяти двумерный массив нельзя. Одномерный можно, а с размерностью более 1 - нет.
Так что придется переделывать.
В своем примере выше, опять же по забывчивости, указал, что Integer занимает 4 байта, а на самом деле 2 (речь про TP).
Кстати, понятия "динамический массив" в TP тоже нет, если говорить о прямом смысле термина, т.е. возможность изменять размер массива при работе программы. Поэтому, если это задание от преподавателя, то препод либо такой же забывчивый как я, либо "коварный" и дал некорректное задание с использованием несуществующих возможностей.

Последний раз редактировалось Скандербег; 21.04.2009 в 06:19.
Скандербег вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
динамический массив Dimon Паскаль, Turbo Pascal, PascalABC.NET 3 21.03.2008 18:08
Динамический массив _ares_ Паскаль, Turbo Pascal, PascalABC.NET 3 26.12.2007 23:54
динамический массив Diller Помощь студентам 48 07.10.2007 16:43
Динамический массив. Mickle Помощь студентам 9 21.06.2007 20:31