Помощь - Поиск - Пользователи - Календарь
Полная версия: Процедурный тип
Форум «Всё о Паскале» > 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-ю строку?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.