Книга: Программирование для Linux. Профессиональный подход

Листинг А.4. (number.c) Арифметика унарных чисел

Листинг А.4. (number.c) Арифметика унарных чисел

/* Операции над унарными числами */
#include <assert.h>
#include <stdlib.h>
#include <limits.h>
#include "definitions.h"
/* Создание числа, равного нулю. */
number make_zero() {
 return 0;
}
/* Эта функция возвращает ненулевое значение,
   если аргумент равен нулю. */
int zerop(number n) {
 return n == 0;
}
/* Уменьшение числа на единицу. */
number decrement_number(number n) {
 number answer;
 assert(!zerop(n));
 answer = n->one_less_;
 free(n);
 return answer;
}
/* Добавление единицы к числу. */
number add_one(number n) {
 number answer = malloc(sizeof(struct LinkedListNumber));
 answer->one_less_ = n;
 return answer;
}
/* Удаление числа. */
void destroy_number(number n) {
 while (!zerop(n))
 n = decrement_number(n);
}
/* Копирование числа. Эта функция необходима для того,
   чтобы при временных вычислениях не искажались
   исходные операнды. */
number copy_number(number n) {
 number answer = make_zero();
 while (!zerop(n)) {
  answer = add_one(answer);
  n = n->one_less_;
 }
 return answer;
}
/* Сложение двух чисел. */
number add(number n1, number n2) {
 number answer = copy_number(n2);
 number addend = n1;
 while(!zerop(addend)) {
  answer = add_one(answer);
  addend = addend->one_less_;
 }
 return answer;
}
/* Вычитание одного числа из другого. */
number subtract(number n1, number n2) {
 number answer = copy_number(n1);
 number subtrahend = n2;
 while(!zerop(subtrahend)) {
  assert(!zerop(answer));
  answer = decrement_number(answer);
  subtrahend = subtrahend->one_less_;
 }
 return answer;
}
/* Умножение двух чисел. */
number product(number n1, number n2) {
 number answer = make_zero();
 number multiplicand = n1;
 while (!zerop(multiplicand)) {
  number answer2 = add(answer, n2);
  destroy_number(answer);
  answer = answer2;
  multiplicand = multiplicand >one_less_;
 }
 return answer;
}
/* Эта функция возвращает ненулевое значение, если
   ее аргумент является четным числом. */
number even(number n) {
 if (zerop(n))
  return add_one(make_zero());
 else
  return odd(n->one_less_);
}
/* Эта функция возвращает ненулевое значение, если
   ее аргумент является нечетным числом. */
number odd (number n) {
 if (zerop(n))
  return make_zero();
 else
  return even(n->one_less_);
}
/* Приведение строки, содержащей десятичное целое,
   к типу "number". */
number string_to_number(char* char_number) {
 number answer = make_zero();
 int num = strtoul(char_number, (char **)0, 0);
 while (num != 0) {
  answer = add_one(answer);
  --num;
 }
 return answer;
}
/* Приведение значения типа "number"
   к типу "unsigned int". */
unsigned number_to_unsigned_int (number n) {
 unsigned answer = 0;
 while (!zerop(n)) {
  n = n->one_less_;
  ++answer;
 }
 return answer;
}

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

Оглавление книги


Генерация: 0.170. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз