Программирование для Linux. Профессиональный подход
Шрифт:
printf("%u\n", number_to_unsigned_int(answer));
destroy_number(answer);
clear_stack(&number_stack);
}
}
return 0;
}
Функции, приведенные в листинге А.4 выполняют операции над унарными числами, представленными в виде связных списков.
Листинг А.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, реализуют стек унарных чисел, представленных в виде связных списков.
Поделиться с друзьями: