Командами в GAP называются: присваивания,
вызовы процедур, структуры if, while, repeat, for, а также
команда return. Все команды заканчиваются знаком « ;
».
Присваивания имеют формат
var := expr;
Пример:
gap> S6 := rec( size := 720 );; S6;
rec(
size := 720 )
gap> S6.generators := [ (1,2), (1,2,3,4,5) ];; S6;
rec(
size := 720,
generators := [ (1,2), (1,2,3,4,5) ] )
gap> S6.generators[2] := (1,2,3,4,5,6);; S6;
rec(
size := 720,
generators := [ (1,2), (1,2,3,4,5,6) ] )
Формат:
procedure-var();
procedure-var( arg-expr {, arg-expr} );
Различие между процедурами и функциями введено
для удобства, GAP же их не различает. Функция
возвращает значение, но не производит побочных
эффектов. Процедура не возвращает никакого
значения, но производит какое-либо действие
(например, процедуры Print, Append, Sort).
Формат:
if bool-expr1 then statements1
{ elif bool-expr2 then statements2 }
[ else statements3 ]
fi;
При этом частей elif может быть произвольное
количество или ни одной. Часть else также может
отсутствовать.
Пример 1: в командах
if expr1 then
if expr2 then stats1
else stats2 fi;
fi;
else относится ко второму if, тогда как в командах
if expr1 then
if expr2 then stats1 fi;
else stats2
fi;
else относится к первому if.
Пример 2:
gap> i := 10;;
gap> if 0 < i then
> s := 1;
> elif i < 0 then
> s := -1;
> else
> s := 0;
> fi;
gap> s;
1 # знак i
Формат:
while bool-expr do statements od;
Последовательность команд statements выполняется,
пока истинно условие bool-expr. При этом сначала
проверяется условие, а затем, если оно истинно,
выполняются команды. Если уже при первом
обращении условие ложно, то последовательность
команд statements не выполнится ни разу.
Пример:
gap> i := 0;; s := 0;;
gap> while s <= 200 do
> i := i + 1; s := s + i^2;
> od;
gap> s;
204
Формат:
repeat statements until bool-expr;
Последовательность команд statements выполняется,
пока истинно условие bool-expr. При этом сначала
выполняются команды, а затем проверяется
условие. Таким образом, при любом начальном
значении условия набор команд statements выполнится,
по крайней мере, один раз.
Пример (вычисление наименьшей суммы
квадратов первых n последовательных
натуральных чисел, превышающей 200):
gap> i := 0;; s := 0;;
gap> repeat
> i := i + 1; s := s + i^2;
> until s > 200;
gap> s;
204
Формат:
for simple-var in list-expr do statements od;
При этом последовательность команд statements
выполняется для каждого элемента из списка list-expr.
Цикл for эквивалентен циклу while:
loop-list := list;
loop-index:= 1;
while loop-index <= Length(loop-list) do
variable := loop-list[loop-index];
...
statements
...
loop-index := loop-index+1;
od;
Список list часто является последовательностью.
Команда
for variable in [from..to] do statements od;
соответствует распространенной в других
языках команде
for variable from from to to do statements od;
Пример:
gap> s := 0;;
gap> for i in [1..100] do
> s := s + i;
> od;
gap> s;
5050
В следующем примере изменение списка приводит
к выполнению команд для новых его элементов:
gap> l := [ 1, 2, 3, 4, 5, 6 ];;
gap> for i in l do
> Print( i, " " );
> if i mod 2 = 0 then Add( l, 3*i/2 ); fi;
> od; Print( "\n" );
1 2 3 4 5 6 3 6 9 9
gap> l;
[ 1, 2, 3, 4, 5, 6, 3, 6, 9, 9 ]
А в следующем — не приводит:
gap> l := [ 1, 2, 3, 4, 5, 6 ];;
gap> for i in l do
> Print( i, " " );
> l := [];
> od; Print( "\n" );
1 2 3 4 5 6
gap> l;
[ ]
Формат:
function ( [ arg-ident {, arg-ident} ] )
[ local loc-ident {, loc-ident} ; ]
statements
end
Пример функции, которая определяет n-е число
Фибоначчи:
gap> fib := function ( n )
> local f1, f2,
f3, i;
> f1 := 1; f2 := 1;
> for i in [3..n] do
> f3 := f1 +
f2; f1 := f2; f2 := f3;
> od;
> return f2;
> end;;
gap> List( [1..10], fib );
[ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]
Ту же функцию можно определить рекурсивно:
gap> fib := function ( n )
> if n < 3 then
> return 1;
> else
> return
fib(n-1) + fib(n-2);
> fi;
> end;;
gap> List( [1..10], fib );
[ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]
Заметим, что рекурсивная версия требует 2 * fib(n)-1
шагов для вычисления fib(n), тогда как итеративная
требует только n-2 шага. Обе, однако, не являются
оптимальными, так как библиотечная функция Fibonacci
требует порядка Log(n) шагов.
Запись arg-ident -> expr является краткой записью для
функции
function ( arg-ident ) return expr;
end.
Здесь arg-ident - один идентификатор, т.е. таким
образом нельзя задать функцию от нескольких
переменных.
Пример типичного использования такой записи:
gap> Sum( List( [1..100], x -> x^2 ) );
338350
Формат:
return;
return expr;
Первая форма прерывает выполнение внутренней
(при вызове одной функции из другой) функции и
передает управление вызывающей функции, не
возвращая при этом никакого значения. Вторая,
кроме того, возвращает значение выражения expr.
|