Этот сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

99 бутылок: калькулятор bc

Разбирал одну старенькую научную статью с некоторым количеством математики, а внутри увидел вычисления на bc.

Не особо с ним знаком, но несколько раз пользовался, даже не вникая что он умеет. Честно говоря, не помню зачем он мне тогда понадобился, наверное надо было что-то вычислить в консоли. Из статей в интернете, где он иногда вскользь упоминался, я знал, что это навороченный калькулятор, но не знал насколько.

В общем, оказалось, там внутри целый язык программирования, с циклами, ветвлениями, локальными переменными, строками, массивами и числам. Поддерживаются даже пользовательские функции. Решил попробовать написать на нём очередную «песню о пиве».

82. bc — интерактивный интерпретатор Си-подобного языка, появившийся ещё в 1975 году как интерфейс для утилиты dc, на котором «песню о пиве» я уже писал. Утилита dc выполняла вычисления с произвольной точностью, используя обратную польскую запись, а bc предоставила более привычный Си-подобный синтаксис, транслируя его в команды dc. В 1991 году утилита bc была стандартизирована POSIX, и сегодня существует несколько её реализаций.

/* Beer song. Evgeny Stepanischev, Jan 2025 */

define void bottles(b) {
    if (b) print b else print "No"
    " bottle"
    if (b-1) print "s"
    " of beer"
}

for(beer = 99; beer;) {
    bottles(beer); " on the wall, "
    bottles(beer); print "!\n"

    print "Take one down, pass it around,\n"
    bottles(--beer); print " on the wall!\n\n"
}

print "No more bottles of beer on the wall,\n"
print "No more bottles of beer!\n"
print "Go to the store and buy some more,\n"
bottles(99); " on the wall!"

Единственное, что вызвало у меня затруднение — это как сделать так, чтобы функция ничего не возвращала. Дело в том, что функции в bc по-умолчанию возвращают число. Если не указано какое, вернётся ноль. А в глобальном контексте то, что возвращается из функции будет напечатано на экране. Поэтому у меня выводился лишний ноль. Чтобы это исправить, нужно в определение функции добавить ключевое слово void.

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