Чтение онлайн

ЖАНРЫ

UNIX — универсальная среда программирования
Шрифт:

Таблица П.2.3. Встроенные константы

Операторы и поток управления

Операторы

hoc
имеют следующую грамматику:

оператор : выражение

 | переменная выражение

 | процедура (список, аргументов)

 | while (выражение) оператор

 | if (выражение) оператор

 | if (выражение) оператор else оператор

 | список_операторов

 | print список_выражений

 | return
возможное_выражение

список_операторов : (пусто)

 | список_операторов оператор

Присваивание распознается по умолчанию как оператор, а не как выражение, поэтому после ввода в диалоге присваиваний их значения не печатаются.

Отметим, что символ

;
не является для
hoc
специальным: оператор оканчивается символом перевода строки. Это обусловливает некоторые особенности. Ниже показан допустимый оператор
if
:

if (x < 0) print(у) else print (z)

if (x < 0) {

 print(y)

} else {

 print(z)

}

Во втором примере скобки не обязательны: символ перевода строки после

if
оканчивал бы оператор и вызывал бы синтаксическую ошибку там, где опущены скобки.

Синтаксис и семантика средств управления в

hoc
в основном те же, что и в Си. Одинаковы также
while
и
if
, однако в
hoc
нет операторов
break
и
continue
.

Ввод и вывод:
read
и
print

Функция ввода

read
(читать) имеет, подобно другим встроенным функциям, один аргумент: однако он не является выражением: это имя переменной. Следующее число, как определено выше, читается из стандартного входного потока и присваивается поименованной переменной. Функция
read
возвращает значения 1 (истина), если величина была прочитана, и 0 (ложь), если
read
встретила конец файла либо ошибку.

Выходной поток порождается оператором

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

Отметим, что

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

while (read (x)) {

 print "value is", x, "\n"

}

Функции и процедуры

Функции и процедуры в

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

Синтаксис определения таков:

function: func имя оператор

procedure: proc имя оператор

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

помещаться на одной строке, как в приведенном выше операторе
if
.

В отличие от Си тело функции или процедуры может быть любым оператором, не обязательно составным (в скобках). Поскольку символ ; не имеет своего значения в

hoc
, пустое тело процедуры формируется пустой парой скобок.

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

shell
:
$3
относится к третьему, индексируемому, начиная с единицы, аргументу. Они передаются значениями и внутри функций семантически эквивалентны переменным. Ссылка на аргумент с помощью числа, превышающего число аргументов, переданных процедуре, считается ошибкой. Контроль ошибок динамический, поскольку подпрограмма может иметь переменное число параметров, если ее начальные аргументы влияют на это число (см. функцию
printf
в Си).

Функции и процедуры могут быть рекурсивными, но стек имеет ограниченную глубину (около сотни вызовов).

Примеры

• Ниже показано определение функции Аккерманна в

hoc
:

$ hoc

time ack {

 if ($1 == 0) return $2+1

 if ($2 ==0) return ack($1 - 1, 1)

 return ack($1 - 1, ack($1, $2 - 1))

}

ack(3,2)

 29

ack(3,3)

 61

ack(3,4)

 hoc: стек слишком велик (строка 8)

...

• Формула Стирлинга:

$ hoc

func stirl {

 return sqrt(2 * $1 * PI) * ($1 / E) ^ $1 * (1 + 1 / (12 * $1))

}

stirl(10) 3628684.7

stirl(20) 2.4328818e+18

• Функция факториал n!

func fac if ($1 <= 0) return 1 else return $1 * fac($1 - 1)

Отношение факториала к приближению Стирлинга:

i = 9

while ((i = i + 1) <= 20) {

 print i, " ", fac(i)/stirl(i), "\n"

}

10 1.0000318

11 1.0000265

12 1.0000224

13 1.0000192

14 1.0000166

15 1.0000146

16 1.0000128

17 1.0000114

18 1.0000102

19 1.0000092

20 1.0000083

Приложение 3

Исходные тексты калькулятора

hoc

These files contain all the code from "The Unix Programming Environment", by Brian Kernighan and Rob Pike (Prentice Hall, 1984, ISBN 0-13-937681-X). A separate hoc6 distribution contains any fixes that we have applied to that; the version in this file is from the book.

Поделиться с друзьями: