Помощь - Поиск - Пользователи - Календарь
Полная версия: Процедурный тип
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Selena
Помогите мне пожалуйста найти ошибку.

У меня такая задача.
Даны матрицы А[1:5,1:6] и В[1:5,1:6]. Из произведений нечетных элементов строк матрицы В сформировать вектор D. Если минимальный элемент 1-ой строки матрицы А больше минимального элемента 2-ой строки матрицы А, то в матрицу А добавить 3-ий столбец, являющийся значениями вектора D, иначе в матрице В поменять местами 1 и 5 столбцы. В п/п (подпрограмме) формирования вектора D использовать п/п нахождения произведений элементов вектора.

Модуль типов MyType

Unit MyType;
 Interface
  Uses Wincrt;
  Type
    mas1=array[1..50] of integer;
    mas2=array[1..10,1..10] of integer;
    func=function(Aa:Mas1;na:Byte):integer;
  Var
    f:text;
    priz,priz1,priz2:Byte;
    A:Mas2;B:Mas2; C,D:Mas1;
  Implementation
  End.



Модуль ввода элементов массивов VVod1

Unit Vvod1;
 Interface
   Uses Mytype;
   Procedure FormMatr(na,ma:Byte;Pa,Qa:Integer;Var Aa:mas2);
 Implementation
   Procedure FormMatr;
    Var i,j:Byte;
     Begin
      For i:=1 to na do For j:=1 to ma do
       Begin Aa[i,j]:=Random(Qa-Pa)+Pa; End;
     End;
 End.



Модуль вывода элементов Vyvod

Unit Vyvod;
 Interface
   Uses MyType,WinCrt;
   Procedure VyvodVek(na:Byte;Var Aa:mas1);
   Procedure VyvodMatr(na,ma:Byte;Var Ba:mas2);
 Implementation
   Procedure VyvodVek;
    Var i:Byte;
    Begin
     For i:=1 to na do
      Write(f,Aa[i]:10,' ');
     writeLn(f,'');
    End;
   Procedure VyvodMatr;
    Var i,j:Byte;
    Begin
     For i:=1 to na do
      begin
       For j:=1 to ma do
       Write(f,Ba[i,j]:3,' '); writeLn(f,'');
      end;
    End;
   End.



Модуль типовых алгоритмов TypAlg1
Исходный код

Unit TipAlg1;
Interface
Uses Wincrt,MyType;
Procedure FormD(Aa:mas2;na,ma:Byte;Proiz:Func;Var Da:mas1;Var k:Byte);
Procedure Vstavka(Aa:mas2;na,ma,k2:Byte;Var Ba:mas2);
Procedure zamena(Aa:mas2;ma:Byte;nomer1,nomer2:Byte;Var Ba:mas2);
Function Proiz(na,ma:Byte; Aa:mas1):integer;Far;
Function MinStr(Aa:mas2;nomer,ma:Byte):integer;
Implementation
{Получение произведений}
Function Proiz;
Var i:Byte; Pr:integer;
Begin
Pr:=1;
For i:=1 to na do
If i mod 2=0
Then Pr:=Pr*Aa[i];
Proiz:=Pr;
End;

{Формирование вектора D}
Procedure FormD;
Var i,j:Byte;C:Mas1;
Begin
For i:=1 to na do
Begin
For j:=1 to ma do
C[j]:=Aa[i,j];
Da[i]:=Proiz(C,ma);k:=k+1;
End;
End;

{Поиск минимального элемента в строке}
Function MinStr;
Var i,j:Byte; minchStr,minchStol:Integer;
Begin
minchStr:=Aa[nomer,1];
For j:=1 to ma do
If Aa[nomer,1]<minchStr Then minchStr:=Aa[i,j];
MinStr:=minchStr;
End;


Procedure Vstavka;
Var i,j:Byte;
Begin
For i:=na+1 downto k2 do
For j:=1 to ma do
Aa[i,j]:=Aa[i-1,j];
For j:=1 to ma do
Aa[k2,j]:=D[i];
End;

Procedure zamena;
Var i,j:Byte;Pa:Byte;
Begin
For j:=1 to ma do
Begin
Pa:=A[nomer1,j]; A[nomer1,j]:=A[nomer2,j];A[nomer2,j]:=Pa;
End;
End;
end.


Головная программа
Исходный код

Program Lab3;
Uses WinCrt,MyType,Vvod1,Vyvod,TipAlg1;
Var
min1,min2:integer;
Begin
Assign(f,'C:\Rezlab\lab3.txt');ReWrite(f);
Randomize;
FormMatr(5,6,0,30,A);
WriteLn(f,‘Матрица А’);
VyvodMatr(5,6,A);
FormMatr(5,6,0,20,B);
WriteLn(f,‘Матрица В’);
VyvodMatr(5,6,B); WriteLn(f,’’);
FormD(B,5,6,Proiz,D,k);
VyvodVek(5,D);
Writeln('');
Min1:=MinStr(A,1,6);
Min2:=MinStr(A,2,6);
WriteLn(f,'min1=',min1:5,'min2=',min2:5); WriteLn(f,‘’);
If min1>min2 then
Begin
Vstavka(A,5,7,3,A);
WriteLn(f,'Матрица с добавленным столбцом');
VyvodMatr(5,7,A);
End
Else
Begin
Writeln(f,'Матрица с перестановленными столбцами');
Zamena(B,6,1,5,B)
VyvodMatr(5,6,B);
End; close(f); End.


Когда я компилирую мне выдает ошибку, что что-то не вторядке с тродцедурным типом Proiz (FormD(B,5,6,Proiz,D,k)). Я уже все перепробывола что мне в голову пришло, но ничего не получается.
Atos
blink.gif blink.gif blink.gif
A, собственно, почему Proiz - это процедурный тип? У тебя это просто название конкретной функция. К тому же ты пытаешься вызвать её без входных параметров
Цитата
Function Proiz(na,ma:Byte; Aa:mas1):integer;
Selena
Входные параметры у меня в модуле MyType
func=function(Aa:Mas1;na:Byte):integer;
Atos
blink.gif Вообще не понял. Причём здесь func, если мы говорим о Proiz?
klem4
Selena,
Function Proiz(na,ma:Byte; Aa:mas1):integer;Far;

Function Proiz;
      Var i:Byte; Pr:integer;
      Begin
       Pr:=1;
       For i:=1 to na do
         If i mod 2=0
          Then Pr:=Pr*Aa[i];
       Proiz:=Pr;
End;


Так этот самы Proiz у тебя описан как самая обыкновенная процедура, и процедурный тип func ты тут не используешь, по крайней в преведенном тобом коде, который я представил выше его нету

М
Atos, опередил smile.gif
klem4

Selena
А как ее записать в процедурном типе? Я тут разбиралась и еще больше запуталась. Объясните пожалуйста.
Selena
Ну помогите кто-нибудь! Очень надо! unsure.gif
volvo
Selena, вот начало той программы, которая тебе нужна (формирование матриц A и B, и вектора D и вывода их на монитор... Если нужен вывод в файл - просто открой его и передавай вместо Output)... Процедурный тип присутствует. Все рабочее, проверено. Если что-то непонятно, спрашивай... rolleyes.gif

P.S. К сожалению, все в одном файле, но главное - алгоритм...

const
  size_vector = 6; { n_cols }
  size_matrix = 5; { n_rows }
type
  tvector = array[1 .. size_vector] of integer;
  tmatrix = array[1 .. size_matrix] of tvector;

  my_func = function(v: tvector; n_cols: integer): integer;

procedure CreateMatrix(n_rows, n_cols: integer;
          start, finish: Integer; var mx: tmatrix);
var i, j: integer;
begin
  for i := 1 to n_rows do
    for j := 1 to n_cols do
      mx[i][j] := integer(random(finish - start)) + start;
end;

procedure PrintVector(var f: text; var v: tvector;
          n_cols: integer);
var i: integer;
begin
  for i := 1 to n_cols do
    write(f, v[i]:10);
  writeln(f);
end;

procedure PrintMatrix(var f: text; var mx: tmatrix;
          n_rows, n_cols: integer);
var j: integer;
begin
  for j := 1 to n_rows do
    PrintVector(f, mx[j], n_cols);
end;


function mult_odds(v: tvector; n_cols: integer): integer; far;
var
  i: integer;
  p: integer;
begin
  p := 1;
  for i := 1 to n_cols do
    if odd(v[i]) then p := p * v[i];
  mult_odds := p
end;

procedure FormVector(from: tmatrix; n_rows, n_cols: integer;
          func: my_func; var v: tvector);
var
  i: integer;
begin
  for i := 1 to n_rows do
    v[i] := func(from[i], n_cols);
end;

var
  A, B: tmatrix;
  D: tvector;

begin
  Randomize;

  CreateMatrix(size_matrix, size_vector, 0, 30, A);
  WriteLn('A matrix:');
  PrintMatrix(output, A, size_matrix, size_vector);

  CreateMatrix(size_matrix, size_vector, 0, 20, B);
  WriteLn('B matrix:');
  PrintMatrix(output, B, size_matrix, size_vector);

  FormVector(B, size_matrix, size_vector, mult_odds, D);
  WriteLn('D matrix:');
  PrintVector(output, D, size_matrix);
end.
Selena
For Volvo.
Огромное спасибо. Именно то что мне было не понятно. good.gif wink.gif
Selena
Я переделала задачу по твоему алгоритму, он мне выдает ошибку при компиляции(в том месте, где выжелено жирным шрифтом). Да, еще. Объясни что такое from: tmatrix, какую функчию выполняет в пвоем примере.

Вот что у меня получилось:

Program l1;
Uses Wincrt;
  Type
    mas1=array[1..50] of integer;
    mas2=array[1..10,1..10] of integer;
    my_func=function(Aa:Mas1;ma:Byte):integer;
  Var
    A:Mas2;B:Mas2; C,D:Mas1;

 Procedure FormMatr(na,ma:Byte;Pa,Qa:Integer;Var Aa:mas2);
    Var i,j:Byte;
     Begin
      For i:=1 to na do For j:=1 to ma do
       Begin Aa[i,j]:=Random(Qa-Pa)+Pa; End;
     End;

 Procedure VyvodMatr(na,ma:Byte;Var Ba:mas2);
    Var i,j:Byte;
    Begin
     For i:=1 to na do
      begin
       For j:=1 to ma do
       Write(Ba[i,j]:3,' '); writeLn('');
      end;
    End;

  Procedure VyvodVek(na:Byte;Var Aa:mas1);
    Var i:Byte;
    Begin
     For i:=1 to na do
      Write(Aa[i]:3,' ');
     writeLn('');
    End;

   Function Proiz(Aa:mas1;na:Byte):integer;Far;
    Var i:Byte; p:integer;
      Begin
       p:=1;
       For i:=1 to na do
         If i mod 2<>0
          Then p:=p*Aa[i];
       Proiz:=p;
      End;

   Procedure  FormD(from:mas2;na,ma:Byte;Func: my_func;Var Da:mas1);
     Var i:Byte;
      Begin
       For i:=1 to na do
        Da[i]:=Func(from[i],ma); { <-- Здесь !!! }
      End;

Begin
  Randomize;
  FormMatr(5,6,0,30,A);
  WriteLn('Matrix A');
  VyvodMatr(5,6,A);Writeln;
  FormMatr(5,6,0,20,B);
  WriteLn('Matrix B');
  VyvodMatr(5,6,B);WriteLn;
  FormD(B,5,6,Proiz,D);
  WriteLn('Vektor B');
  VyvodVek(5,D);
End.


volvo
Selena, обрати внимание, как у тебя описана функция Proiz:
Function Proiz(na,ma:Byte; Aa:mas1):integer;Far;

Она принимает 3 параметра(2 байта и один массив) ...

и что ты передаешь в нее:
Da[i]:=Func(from[i],ma);

2 параметра (массив и байт)... Конечно будет несоответствие типов... Данные должны передаваться в том порядке, в котором они следуют в описании...

Цитата
что такое from: tmatrix, какую функчию выполняет в пвоем примере
У тебя задание - сформировать вектор из матрицы, так? Вот я и передаю, из КАКОЙ матрицы будет формироваться вектор... Ну не люблю я глобальные переменные...
Selena
Последний вопрос. Я нашла ошибку. Программа работает. Но почему-то она считае вектор D не из нечетных элементов, а вообще непонятно из каких элементов.
Вот переделанная.

Program l1;
Uses Wincrt;
  Type
    mas1=array[1..50] of integer;
    mas2=array[1..10,1..10] of integer;
    my_func=function(Aa:Mas1;ma:Byte):integer;
  Var
    A:Mas2;B:Mas2; C,D:Mas1;

 Procedure FormMatr(na,ma:Byte;Pa,Qa:Integer;Var Aa:mas2);
    Var i,j:Byte;
     Begin
      For i:=1 to na do For j:=1 to ma do
       Begin Aa[i,j]:=Random(Qa-Pa)+Pa; End;
     End;

 Procedure VyvodMatr(na,ma:Byte;Var Ba:mas2);
    Var i,j:Byte;
    Begin
     For i:=1 to na do
      begin
       For j:=1 to ma do
       Write(Ba[i,j]:3,' '); writeLn('');
      end;
    End;

  Procedure VyvodVek(na:Byte;Var Aa:mas1);
    Var i:Byte;
    Begin
     For i:=1 to na do
      Write(Aa[i]:3,' ');
     writeLn('');
    End;

   Function Proiz(Aa:mas1;na:Byte):integer;Far;
    Var i:Byte; p:integer;
      Begin
       p:=1;
       For i:=1 to na do
         If i mod 2<>0
          Then p:=p*Aa[i];
       Proiz:=p;
      End;

   Procedure  FormD(Aa:mas2;na,ma:Byte;Func: my_func;Var Da:mas1);
     Var i,j:Byte; C:mas1;
      Begin
       For i:=1 to na do
       begin
        For j:=1 to ma do
         C[j]:=Aa[i,j];
       Da[i]:=Func(C,ma);
       end;
      End;

Begin
  Randomize;
  FormMatr(5,6,0,30,A);
  WriteLn('Matrix A');
  VyvodMatr(5,6,A);Writeln;
  FormMatr(5,6,0,20,B);
  WriteLn('Matrix B');
  VyvodMatr(5,6,B);WriteLn;
  FormD(B,5,6,Proiz,D);
  WriteLn('Vektor B');
  VyvodVek(5,D);
End.


volvo
To: Selena
Function Proiz(Aa:mas1;na:Byte):integer; Far;
Var i:Byte; p:integer;
Begin
  p:=1;
  For i:=1 to na do
  If Aa[i] mod 2<>0 { <--- Внимательно !!! }
    Then p:=p*Aa[i];
  Proiz:=p;
End;
Selena
Спасибо. cool.gif
Selena
Не подскажете что здесь не так? Замена стобца вектором D не происходит, а выдает одни нули вместо матрицы А1


..
   Procedure Vstavka(Aa:mas2;from:mas1;na,ma,nstl:Byte;Var Ba:mas2);
       Var i,j:Byte;
       begin
       for i:=1 to na do
       for j:=1 to ma do
       Aa[i,nstl]:=Da[i]; {Da это должен быть вектор D, nstl=3}
       end;
.......

Begin
Vstavka(A,D,5,6,3,A1);
      WriteLn('Матрица с измененым 3 столбцом');
      VyvodMatr(5,6,A1);

volvo
blink.gif А зачем вложенные циклы? Вот этого достаточно:
...
  for i:=1 to na do
    Aa[i, nstl]:=Da[i];
...
Это во-первых. А во вторых, ты же меняешь матрицу Aa, а хочешь, чтобы изменилась Ba no1.gif Не пойдет...

Я бы сделал так:
Procedure Vstavka(Aa:mas2;from:mas1;na,ma,nstl:Byte;Var Ba:mas2);
Var i: Byte;
begin
  Move(Aa, Ba, sizeof(Aa));
  for i:=1 to na do
    Ba[i, nstl] := Da[i];
end;

blum.gif
Selena
В матрицу В добавить 3-ью строку, являющуюся суммой элементов с одинаковыми индексами 1,4 и 5 строк.

Не подскажите как сделать? Это к это же задачи
volvo
Selena, что значит "Добавить"? У тебя есть матрица из 5 строк. Что будет с 3, 4 и 5 из них, когда ты добавишь новую 3-ю строку?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.