Язык программирования Си




Внешние переменные - часть 3


Главный вопрос, который мы еще не рассмотрели, - это вопрос о том, где расположить стек и каким функциям разрешить к нему прямой доступ. Стек можно расположить в функции main и передавать сам стек и текущую позицию в нем в качестве аргументов функциям push ("послать в стек") и pop ("взять из стека"). Но функции main нет дела до переменных, относящихся к стеку, - ей нужны только операции по помещению чисел в стек и извлечению их оттуда. Поэтому мы решили стек и связанную с ним информацию хранить во внешних переменных, доступных для функций push и pop, но не доступных для main.

Переход от эскиза к программе достаточно легок. Если теперь программу представить как текст, расположенный в одном исходном файле, она будет иметь следующий вид:

#include /* могут быть в любом количестве */ #define /* могут быть в любом количестве */

объявления функций для main

main() {...} внешние переменные для push и pop

void push (double f) {...} double pop (void) {...}

int getop(char s[]) {...}

подпрограммы, вызываемые функцией getop

Позже мы обсудим, как текст этой программы можно разбить на два или большее число файлов.

Функция main - это цикл, содержащий большой переключатель switch, передающий управление на ту или иную ветвь в зависимости от типа оператора или операнда. Здесь представлен более типичный случай применения переключателя switch по сравнению с рассмотренным в параграфе 3.4.

#include <stdio.h> #include <stdlib.h> /* для atof() */

#define MAXOP 100 /* макс. размер операнда или оператора */ #define NUMBER '0' /* признак числа */

int getop (char []); void push (double); double pop (void);

/* калькулятор с обратной польской записью */ main() { int type; double op2; char s[MAXOP];

while ((type = getop (s)) != EOF) { switch (type) { case NUMBER: push (atof(s)); break; case '+': push (pop() + pop()); break; case '*': push (pop() * pop()); break; case '-': op2 = pop(); push (pop() - op2); break; case '/': pop2 = pop(); if (op2 != 0.0) push (pop() / op2); else printf("ошибка: деление на нуль\n"); break; case '\n': printf("\t%.8g\n", pop()); break; default: printf("ошибка: неизвестная операция %s\n", s); break; } } return 0; }




Содержание  Назад  Вперед