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

ЖАНРЫ

Программирование для 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, реализуют стек унарных чисел, представленных в виде связных списков.

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