CбИС++ «БИТ»
   О ПРОГРАММЕ   
   О КОМПАНИИ   
   ЗАГРУЗИТЬ   
   ДОКУМЕНТАЦИЯ   
   · Руководство пользователя 
   · СБиС news
   · Статьи
   · Функции
   ПРАЙС-ЛИСТ   
   ВАКАНСИИ   
   АВТОМАТИЗАЦИЯ ТОРГОВЛИ   
СБиС news №16/30.10.98

Новинка сезона - функции, задаваемые пользователем

   В грядущей версии СБиС++ под номером 1.4 появился один принципиально новый механизм – механизм функций. Обсуждению функций и посвящен данный выпуск. Итак…
   Очень часто при настройке правил операций или отчетов возникает необходимость использовать одни и те же фрагменты кода то тут, то там. До появления версии 1.4 эта проблема частично решалась при помощи функции “Выполнить”, хотя и не всегда это было удобно. Теперь все стало проще. Вы просто выделяете повторяющийся фрагмент правила операции, присваиваете ему определенное имя. И всё! После этого везде, где нужно выполнить этот фрагмент, достаточно указать присвоенное ему имя. Такой поименованный фрагмент кода принято называть функцией. В следующих пунктах рассказывается, как описывать и применять функции.


Делаем раз! Описываем функцию

   Чтобы хоть что-нибудь стало понятно, давайте рассмотрим простой пример. Допустим, Вам очень часто требуется получать большее из трех чисел. Пишем так:

функция Макс3( А, Б, В )
{
   Если( А > Б )
   {
      Если( А > В )
         вернуть А;
      иначе
         вернуть В;
   }
   иначе
   {
      Если( Б > В )
         вернуть Б;
      иначе
         вернуть В;
   }
}

   Здесь описана функция с именем “Макс3”, принимающая три параметра, и возвращающая значение максимального из них. Разберем этот пример поподробнее. Описание функции начинается с ключевого слова “функция”. Далее указывается имя функции, и в круглых скобках через запятую перечисляются имена параметров.
   За списком параметров в фигурных скобках идет уже непосредственно код функции. Таким образом, описание функции в общем случае выглядит так:

функция ИмяФункции( ИмяПараметра1, ИмяПараметра2, … )
{
   КодФункции
}

   Полученное в результате выполнения функции значение возвращается при помощи оператора “вернуть”. На самом деле функция может и ничего не возвращать. Тогда оператор “вернуть” просто не используется.


Делаем два! Используем функцию

   Ну хорошо, функция описана. Как же ее теперь использовать? Да точно так же, как и любую обычную функцию, например, “Проводка” или “Сообщить”. Так, чтобы получить в переменную “П” максимум из трех чисел 1,2,3, достаточно написать:

П = Макс3(1,2,3);

   Что происходит при выполнении этой строки? Находится функция с именем “Макс3”. Параметру с именем “А” присваивается значение 1, параметру с именем “Б” - 2, параметру с именем “В” - 3. После этого выполняется код функции. При выполнении оператора “вернуть” функция заканчивает свою работу, а в переменную “П” помещается значение выражения, стоящего после оператора “вернуть”.
   Тут уместно будет сделать одно важное замечание: старые правила операций, в которых использовалась функция “Вернуть”, необходимо пересохранить. Это связано с тем, что до версии 1.4 была внутренняя функция “Вернуть”, теперь же это стал оператор языка. В связи с этим, кстати, можно не заключать выражение, стоящее за словом “вернуть” в круглые скобки.


Лирическое отступление: оптимизация функции

   Немного отвлечемся и попробуем упростить функцию “Макс3”. Во-первых, можно использовать стандартную функцию “Макс”.

функция Макс3( А, Б, В )
{
   вернуть Макс( А, Макс(Б,В) );
}

   Если код функции состоит только из одной строки, то фигурные скобки можно не писать, получится еще короче:

функция Макс3( А, Б, В )
   вернуть Макс( А, Макс(Б,В) );

   На самом деле, если уж идти совсем до конца, слово “вернуть” можно и опустить:

функция Макс3( А, Б, В )
   Макс( А, Макс(Б,В) );

   То есть, если выполнение функции доходит до конца, не встретив оператор “вернуть”, то результатом выполнения функции считается результат последней операции. В нашем случае это будет значение выражения “Макс(А,Макс(Б,В))”.


Делаем три! Собираем всё вместе

   Оптимизация это, конечно, хорошо, но вернемся к функциям. Если в правиле операций просто написать:

П = Макс3(1,2,3);

…то будет выдано сообщение “Не найдена функция!”. Дело в том, что на момент прочтения программой этой строки, программа уже должна “знать” о существовании функции с именем “Макс3” и сколько у этой функции может быть параметров. То есть программа уже должна прочитать описание функции. Проще всего это сделать, поместив описание функции в том же правиле до строки с вызовом функции.

функция Макс3( А, Б, В )
{ вернуть Макс( А, Макс(Б,В) ); }
П1 = Макс3(1,2,3);
П2 = Макс3(23,12,44);
П2 = Макс3(43,1,78);
П3 = Макс3(П1,П2,П3);

   Вот это уже будет работать. Но, скорее всего, захочется вызывать функцию из нескольких правил операций и отчетов. Для этого описания функций нужно поместить в некоторое общее место. Таким общим местом для описаний функций являются файлы с расширением “*.PRG”. Это обычные текстовые файлы, содержащие только описания функций.
   При загрузке программа последовательно прочитывает все файлы с расширением “*.PRG” в алфавитном порядке и “запоминает” все встретившиеся функции. Причем сначала просматриваются файлы в каталоге “PRG”, лежащем “рядом” с каталогом базы данных, а потом в каталоге, откуда был запущен файл “SBIS.EXE”. Если будет встречено две одноименные функции, то будет действовать та, которая была прочитана позже.
   Итак, создаем текстовым редактором в каталоге со SBIS.EXE файл SBIS.PRG, содержащий описание нашей многострадальной функции “Макс3”.

SBIS.PRG
функция Макс3( А, Б, В )
{ вернуть Макс( А, Макс(Б,В) ); }

   Вот теперь можно в любом правиле операции или отчете написать:

П = Макс3(1,2,3);

… не получая сообщения об ошибке.


Копаем вглубь: локальные переменные

   Конечно, в теории всё всегда выглядит значительно лучше, чем бывает на практике. Начав работать с функциями, Вы наверняка столкнетесь с какими-нибудь проблемами. Например, как Вы думаете, какое число будет сообщено, если выполнить следующий фрагмент?

функция Макс4( А, Б, В, Г )
{
   П1 = Макс( А, Б );
   П2 = Макс( В, Г );
   вернуть Макс( П1, П2 );
}
П1 = 300;
П2 = 200;
П3 = 100;
П4 = Макс4( 13, 66, 18, 12 );
Сообщить( П1 + П2 + П3 + П4 );

   Если не смотреть на описание функции, то вроде бы должно быть сообщено “666” (300+200+100+66). Но не тут-то было! Будет сообщено “250”. А всё потому, что в функции “Макс4” используются переменные “П1” и “П2”, на которые мы рассчитывали. Хорошо еще здесь виден код функции, а если бы функция была описана во внешнем PRG-файле? Представляете, как бы Вы помучались, прежде чем поняли, почему 300+200+100+66 не равно 666!
   Но не все так плохо. Такой ситуации можно легко избежать, если сказать программе, что переменные “П1” и “П2” используются в функции “Макс4” для её внутренних нужд и не должны влиять на что-либо вне функции. Переменные такого типа принято называть локальными (они живут как бы локально внутри функции).
   Чтобы переменная стала локальной, нужно перед первым присваиванием этой переменной написать ключевое слово “перем”. Например, следующий подправленный фрагмент сообщит наконец-то искомое число “666”.

функция Макс4( А, Б, В, Г )
{
   перем П1 = Макс( А, Б );
   перем П2 = Макс( В, Г );
   вернуть Макс( П1, П2 );
}
П1 = 300;
П2 = 200;
П3 = 100;
П4 = Макс4( 13, 66, 18, 12 );
Сообщить( П1 + П2 + П3 + П4 );

   При помощи ключевого слова “перем” можно также объявлять, какие переменные в данной функции будут локальными. Для этого просто через запятую перечисляются имена этих переменных. Функцию “Макс4” можно было бы написать и так:

функция Макс4( А, Б, В, Г )
{
   перем П1,П2;
   П1 = Макс( А, Б );
   П2 = Макс( В, Г );
   вернуть Макс( П1, П2 );
}

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


<<< Предыдущий выпуск | Архив выпусков | Следующий выпуск >>>