Раздел: Как стать программистом / Секреты программирования /

Функция возвращает несколько значений

Lazarus IDE: Основы программирования в Windows Lazarus IDE: Основы программирования в Windows

Несмотря на то, что всё потихоньку уходит в сеть, программирование для настольных компьютеров остаётся востребованным. И будет таковым ещё долго. Ну а самая распространённая операционная система для настольных компьютеров – это по-прежнему Windows. Поэтому любой программист, даже если он собирается стать веб-разработчиком, должен знать хотя бы основы создания программ для Windows. Подробнее...

Я нередко слышу от новичков, что функция может возвращать только одно значение, и что процедуры в Паскале возвращать значения не могут. Заблуждения - это обычное дело в начале изучения какого-нибудь предмета. Но чем быстрее вы начнёте от них избавляться, тем лучше. И сегодня я как раз помогу вам это сделать. Итак:

  • Процедуры в Паскале могут возвращать значения
  • Функции и процедуры могут возвращать несколько значений

А теперь рассмотрим несколько способов.

Используем запись

Не самый удобный способ, но во многих случаях его можно и нужно использовать. Функция при этом будет возвращать одно значение, но это значение будет иметь тип записи, а запись, как вы понимаете, может содержать в себе множество переменных разных типов. Пример:

type TCoord = record
  X, Y : Integer;
end;

//*******************************************************************
// Способ 1: использование записи
//*******************************************************************
function GetCoordRec(Point : TCoord) : TCoord;
begin
  Point.X := 10;
  Point.Y := 5;
  Result := Point;
end;

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

var Point : TCoord;

begin
  //Способ 1
  Point := GetCoordRec(Point);
  WriteLn('X, Y : ', Point.X, ', ', Point.Y);
end.

Используем массив

Принцип действия тот же, что и при использовании записи. Отличие в том, что в записи могут быть переменные разных типов, а в массиве только однотипные. И сначала надо будет объявить новый тип для массива, потому что функция может возвращать только данные определённого типа, а массив сам по себе типом не является. То есть вот это не прокатит:

function GetCoordMas : array[1..2] of Integer;

и компилятор выдаст ошибку. Поэтому делать надо так:

type AInteger = array[1..2] of Integer;  

//*******************************************************************
// Способ 2: использование массива
//*******************************************************************
function GetCoordMas : AInteger;
begin
  Result[1] := 15;
  Result[2] := 16;
end;

Это будет работать, и в программе можно использовать, например, так:

var A : AInteger;

begin
  //Способ 2
  A := GetCoordMas;
  WriteLn('X, Y : ', A[1], ', ', A[2]);
end.

Используем var

Это самый простой способ вернуть из функции или процедуры любое количество значений любых типов. И в большинстве случаев использовать надо именно этот способ:

//*******************************************************************
// Способ 3: использование var
//*******************************************************************
function GetCoordVar(var X : Integer) : Integer;
begin
  X := 11;
  Result := 6;
end;

Здесь я немного поизвращался. Но это для наглядности. Если в списке параметров функции или процедуры перед именем переменной указать слово var, то это будет означать, что через эту переменную будет не только передано значение в подпрограмму, но и получено значение из подпрограммы. Подробнее об этом здесь.

Используем указатели

Для новичков это самый сложный способ. Да и я в подавляющем большинстве случаев не вижу смысла его использовать. Но знать об этом надо, потому что многие стандартные функции, особенно системные и особенно в С++, используют именно его.

Суть его в том, чтобы передавать в подпрограмму не переменную, а её адрес. Тогда изменение данных в памяти, на которые указывает этот адрес, автоматически приведёт к изменению значений всех переменных, которые ссылаются на эту область в памяти.

Пример:

type PInteger = ^Integer;

//***************************************************************
// Способ 4: использование указателей
//***************************************************************
procedure GetCoordP(x, y : PInteger);
begin
  x^ := 100;
  y^ := 200;
end;

Здесь тоже придётся объявить отдельный тип, потому что вот это не прокатит:

procedure GetCoordP(x, y : ^Integer);

Компилятор выдаст ошибку.

В программе использовать такую процедуру (или функцию) можно так:

var  Px, Py: PInteger;

begin
  //Способ 4
  New(Px);
  New(Py);
  GetCoordP(Px, Py);
  WriteLn('X, Y : ', Px^, ', ', Py^);
  Dispose(Px);
  Dispose(Py);

  //Ждём нажатия ENTER
  ReadLn;
end.

Как вы понимаете, при работе с указателями надо выделять память перед её использованием и освобождать после использования. Вот здесь вы можете найти больше сведений об указателях.

На этом останавливаюсь. Основные мысли я изложил. При желании вы можете подключить воображение и придумать что-нибудь ещё. Ну и, разумеется, описанные выше способы можно комбинировать. Также скажу, что всё это в той или иной степени справедливо и для других языков программирования. Разумеется, с учётом их особенностей.

Подписывайтесь на новости, чтобы ничего не пропустить (ссылки под видео), а если что-то ещё не вполне понятно, то см. видео:


Первые шаги в программирование Первые шаги в программирование

Очень небольшая книга, которую можно прочитать буквально за 15 минут. Но эти 15 минут дадут вам представление о том, что такое программирование. И вы даже напишите свою первую программу. Для тех, кто интересуется программированием, но ещё не знает, что это такое, и не пробовал создавать программы (или пробовал, но не получилось). Подробнее...
Помощь в технических вопросах Помощь в технических вопросах

Помощь студентам. Курсовые, дипломы, чертежи (КОМПАС), задачи по программированию: Pascal/Delphi/Lazarus; С/С++; Ассемблер; языки программирования ПЛК; JavaScript; VBScript; Fortran; Python и др. Разработка (доработка) ПО ПЛК (предпочтение - ОВЕН, CoDeSys 2 и 3), а также программирование панелей оператора, программируемых реле и других приборов систем автоматизации. Подробнее...

Инфо-МАСТЕР ®
Все права защищены ©
e-mail: mail@info-master.su

Яндекс.Метрика