Решение задачи на Pascal

Модератор: Модераторы разделов

Аватара пользователя
baldman88
Сообщения: 233

Решение задачи на Pascal

Сообщение baldman88 »

Доброго всем времени суток. Столкнулся с тем, что не могу понять чего от меня хотят. Вот условия задания:
1 Написать программу, которая обнуляет все элементы с чётными значениями над главной диагональю.
2 Ввод-вывод элементов двумерного массива осуществлять с помощью процедур, формальным параметром которых является размерность массива.
3 Реализацию задания выполнить в виде функции.
4 Разработанные процедуры и модули выполнить в виде отдельного программного модуля.

Теперь что я не пойму:
1 Как можно процедуры засунуть в отдельный модуль и потом заполнять или читать с их помощью массив, передавая в них только размерность?
2 Как быть с функцией? Просто передавать ей элемент, она будет проверять его значение на чётность и если нужно обнулять? И тогда это всё в цикле. Смысл такой функции? Если передать в неё массив, то как его вернуть оттуда в Turbo Pascal?

В общем то ли я глупый, то ли задание придумано кем то невменяемым. Можно было бы, наверное, через указатели, но их пока не проходили.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Решение задачи на Pascal

Сообщение watashiwa_daredeska »

baldman88 писал(а):
29.12.2011 00:40
1 Как можно процедуры засунуть в отдельный модуль и потом заполнять или читать с их помощью массив, передавая в них только размерность?
Честно говоря, я уже не шибко помню Паскаль, но:
1. Если можно возвращать из функции массив или указатель на массив, то легко: функция динамически выделяет массив, читает и возвращает.
2. Если нельзя, то в задании не сказано, что размерность — единственный формальный параметр. Т.е. помимо размерности в параметрах можно передавать массив для заполнения.

baldman88 писал(а):
29.12.2011 00:40
Если передать в неё массив, то как его вернуть оттуда в Turbo Pascal?
Не надо возвращать, пусть изменяет массив «на месте».
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Решение задачи на Pascal

Сообщение NickLion »

baldman88 писал(а):
29.12.2011 00:40
2 Как быть с функцией? Просто передавать ей элемент, она будет проверять его значение на чётность и если нужно обнулять? И тогда это всё в цикле. Смысл такой функции? Если передать в неё массив, то как его вернуть оттуда в Turbo Pascal?

Можно передавать парметр по ссылке, при помощи var:
function doZero(var a: array[1..50,1..50] of integer): boolean;
Но выползает подводный камень - размер массива должен быть константным. Тогда
baldman88 писал(а):
29.12.2011 00:40
2 Ввод-вывод элементов двумерного массива осуществлять с помощью процедур, формальным параметром которых является размерность массива.

Размерность передвать смысла не имеет. Динамические массивы - это только в Delphi версии Pascal вроде появилось, в той версии, что в Turbo - либо константные, либо по указателю. Линейные, правда можно как безразмерные передавать, но тут же двумерный.
Так что голосую за то, что
baldman88 писал(а):
29.12.2011 00:40
задание придумано кем то невменяемым



watashiwa_daredeska писал(а):
29.12.2011 09:10
baldman88 писал(а):
29.12.2011 00:40
1 Как можно процедуры засунуть в отдельный модуль и потом заполнять или читать с их помощью массив, передавая в них только размерность?
Честно говоря, я уже не шибко помню Паскаль, но:
1. Если можно возвращать из функции массив или указатель на массив, то легко: функция динамически выделяет массив, читает и возвращает.
2. Если нельзя, то в задании не сказано, что размерность — единственный формальный параметр. Т.е. помимо размерности в параметрах можно передавать массив для заполнения.

baldman88 писал(а):
29.12.2011 00:40
Если передать в неё массив, то как его вернуть оттуда в Turbo Pascal?
Не надо возвращать, пусть изменяет массив «на месте».

Да, но для динамического размера двумерного массива это всё можно только при использовании указателей.
Спасибо сказали:
Аватара пользователя
bormant
Сообщения: 1354

Re: Решение задачи на Pascal

Сообщение bormant »

baldman88 писал(а):
29.12.2011 00:40
В общем то ли я глупый, то ли задание придумано кем то невменяемым. Можно было бы, наверное, через указатели, но их пока не проходили.

В вашем случае:
1) тип элемента можно принять фиксированым;
2) TP7 умеет "array of type", раньше это делали при помощи array [0..65535/sizeof(type)-1] of type;
3) вместо указателей можно использовать наложение на безтиповый параметр линейного массива, см. absolute;
4) модель хранения массива в памяти построчная, поэтому [i,j] элемент в массиве m строк на n колонок -- это k=i*n+j.

Иногда в учебных целях поступают проще: принимают какие-то максимальные размеры массива, а обрабатывают только часть в его пределах. Допустимо ли такое упрощение -- нужно спрашивать у поставившего задачу.

Ещё одно возможное упрощение -- нигде не сказано, что массивов может быть больше одного ;), то есть это может быть заранее известный глобальный массив (да, практического смысла в таких функциях немного, но и задача учебная). Допустимо ли такое упрощение -- нужно спрашивать у поставившего задачу.
Спасибо сказали:
Аватара пользователя
baldman88
Сообщения: 233

Re: Решение задачи на Pascal

Сообщение baldman88 »

Сделал передачу массива и размерности в процедуры (не сказано же что сам массив нельзя передавать). А вот по поводу функции. Что передавать в неё и возвращать из неё же? Просто по одному элементу в цикле?
P.S.: Делаю не для себя. Тот кому это нужно подходил и спрашивал у преподавателя. Тот сказал, что в задании русским языком написано что делать. Видимо он и сам толком не знает, учитывая то, что это всё на кафедре машиностроения. И да, а разве [i,j]-й элемент это не k=(i-1)*n+j ?
Спасибо сказали:
Аватара пользователя
Voral
Сообщения: 1205
ОС: Debian Wheezy (amd64)

Re: Решение задачи на Pascal

Сообщение Voral »

baldman88 писал(а):
29.12.2011 00:40
1 Как можно процедуры засунуть в отдельный модуль и потом заполнять или читать с их помощью массив, передавая в них только размерность?
2 Как быть с функцией? Просто передавать ей элемент, она будет проверять его значение на чётность и если нужно обнулять? И тогда это всё в цикле. Смысл такой функции? Если передать в неё массив, то как его вернуть оттуда в Turbo Pascal?


Кривая какая то задача.
1. Я тоже уже подзабыл тонкости паскаля (тем более для кривых решений). А глобальные переменные не прокатывают?
2. Ну если читать задание то ф-ия должна "Реализацию задания выполнить" (п.3) Заданием является: ввод/вывод и обнуление.... Т.е. строго говоря функция ни должна чего либо принимать в качестве параметра, ни чего возвращать - эдакая вещь в себе.

по 4му пункту у меня даже вкралось сомнение что я знаю что такое "программный модуль" :)
То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
Спасибо сказали:
Аватара пользователя
bormant
Сообщения: 1354

Re: Решение задачи на Pascal

Сообщение bormant »

Если считать от 0, а от него считать удобнее, то k=i*n+j. Если от 1, то k=(i-1)*n+j. Но "array of type" начинается с 0.

Про функцию:

Код: Выделить всё

function Value(A: Integer): Integer;
begin
  if not odd(A)
  then Value := 0
  else Value := A;
end;
...
for i:=0 to M-1 do
  for j:=i+1 to N-1 do
    A[i, j] := Value(A[i, j]);

M - количество строк, N - количество столбцов. Функции в TP не возвращают массивов. Поэтому тупо в лоб, без использования динамической памяти вытанцовывается что-то вроде следующего.

(пишу с листа, допускаю ошибки)

Код: Выделить всё

unit Unit1;
interface
const
  MaxM = 30;
  MaxN = 30;
type
  Matrix: array [0..MaxM-1, 0..MaxN-1] of Integer;
procedure EnterMatrix(var A: Matrix; var M, N: Integer);
procedure PrintMatrix(var A: Matrix; M, N: Integer);
function Value(A: Integer): Integer;
implementation
procedure EnterMatrix(var A: Matrix; var M, N: Integer);
var
  i, j: Integer;
begin
  repeat
    Write('Введите размерность матрицы (через пробел, до ', MaxM, ' х', MaxN, '): ');
    ReadLn(M, N);
  until (M>1) and (m<=MaxM) and (N>1) and (N<=MaxM);
  WriteLn('Введите построчно элементы матрицы (', M, 'x', N, '):');
  for i:=0 to M-1 do for j:=0 to N-1 do Read(M[i,j]);
end;
procedure PrintMatrix(var A: Matrix; M, N: Integer);
var
  i, j: Integer;
begin
  for i:=0 to M-1 do begin
    for j:=0 to N-1 do Write(A[i,j]);
    WriteLn;
  end;
end;
function Value(A: Integer): Integer;
begin
  if not odd(A)
  then Value:=0
  else Value:=A;
end;
end.


program Task1;
var
  A: Matrix;
  M, N, i, j: Integer;
begin
  EnterMatrix(A, M, N);
  WriteLn('Исходная матрица:'); PrintMatrix(A, M, N);
  for i:=0 to M-1 do
    for j:=i+1 to N-1 do
      A[i,j]:=Value(A[i,j]);
  WriteLn('Результат:'); PrintMatrix(A, M, N);
end.
Спасибо сказали:
Аватара пользователя
bormant
Сообщения: 1354

Re: Решение задачи на Pascal

Сообщение bormant »

А можно замену загнать в функцию, а возвратить, например, была ли сделана хоть одна замена.

Код: Выделить всё

...
function DoJob(var A: Matrix; M, N: Integer): Boolean;
var
  i, j: Integer;
begin
  DoJob:=False;
  for i:=1 to M-1 do
    for j:=i+1 to N-1 do
      if not Odd(A[i,j]) then begin
        A[i,j]:=0;
        DoJob:=True;
      end;
end;
procedure PrintMatrix(Txt: string; var A: Matrix; M, N: Integer);
var
  i, j: Integer;
begin
  if Length(Txt)>0 then WriteLn(Txt);
  for i:=0 to M-1 do begin
    for j:=0 to N-1 do Write(A[i,j]);
    WriteLn;
  end;
end;

...
program Task1;
var
  A: Matrix;
  M, N: Integer;
begin
  EnterMatrix(A, M, N);
  PrintMatrix('Исходная матрица:', A, M, N);
  if DoJob(A, M, N)
  then PrintMatrix('Результат:', A, M, N)
  else WriteLn('Исходная матрица удовлетворяет условию и не была изменена.');
end.
Спасибо сказали:
Аватара пользователя
baldman88
Сообщения: 233

Re: Решение задачи на Pascal

Сообщение baldman88 »

Спасибо всем.
bormant, что то очень похожее на то что в 7 посту у меня и вышло. Буду теперь ждать реакции преподавателя :crazy:
Спасибо сказали: