Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tekhnologia_programmirovania.pdf
Скачиваний:
182
Добавлен:
08.04.2015
Размер:
1.76 Mб
Скачать

23416

Вфайл SumNumb.cpp необходимо поместить объявления используемых в main функций strtof и readline, иначе при компиляции данного файла будет выдана ошибка вида:

•Error LECTC_~1\SUMNUMB.CPP 18: Function 'readline' should have a prototype

Ниже приведен пример работы программы

33.21

33.21 -10.12 23.09 65.66 88.75 ^Z

Часто кажется удобным делать переменные внешними потому, что в этом случае становятся короче списки аргументов функций, так как переменные видны везде. Например, в программе 51 массив для вводимой строки и его размер не передаются в функцию readline потому, что они доступны в этой функции как внешние переменные. Однако чрезмерное использование внешних переменных приводит к программам, в которых связи по данным не очевидны, поэтому такие программы трудны для понимания и модификации, их трудно отлаживать, так как сложно следить за изменениями внешних переменных.

Кроме того, функции, в которые данные передаются с помощью внешних переменных, являются менее общими, так как в них используются конкретные имена. Это относится, например, к функции readline, в которой использовано имя конкретного внешнего массива line. При изменении имени массива придется переписывать и функцию

readline.

16.3. Заголовочные файлы

При написании программы 51 нужно было заботиться об объявлениях внешних функций и переменных в файлах программы. Для облегчения этого, принято размещать необходимые объявления в отдельных файлах с расширениями .h, которые называют заголовочными (от header – заголовок), так как их основное содержание составляют объявления или заголовки функций.

Программы из нескольких файлов 235

Страж включения

Заголовочные файлы вставляются в другие файлы директивами препроцессора #include, причем делать это надо однократно, так как при повторном включении возможны ошибки из-за дублирования определения какого-либо объекта. Чтобы не было повторного включения заголовочных файлов, используется прием, называемый

стражем включения.

Заголовочный файл оформляется в виде

// Файл HEADER.H

 

#ifndef HEADERH

// Страж

#define HEADERH

// включения

//Содержимое HEADER.H

//

#endif

Условная директива препроцессора #ifndef проверяет, определен или нет макрос HEADERH. Если этот макрос не определен, то в текст программы включаются все строки, вплоть до строки #endif, при этом определяется макрос HEADERH. Если же обнаружится, что макрос HEADERH определен, то в обработанный препроцессором текст не включаются все строки, расположенные между строками

#ifndef HEADERH

и

#endif

благодаря чему не будет повторного включения файла HEADER.H.

Имя макроса, который фигурирует в страже включения, совершенно произвольно, но принято выбирать его похожим на имя заголовочного файла.

Таким образом, если в некотором файле будут две директивы:

// Файл File1.cpp #include HEADER.H #include HEADER.H

то файл HEADER.H будет вставлен только одной первой директивой, а вторая будет фактически проигнорирована благодаря стражу включения.

Понятие стека

Стеком называется набор элементов одного типа, организованный по принципу “последний пришел – первый вышел” или LIFO (last infirst out). Английское слово stack переводится как копна сена, стопа

236 16

бумаги. Для стопы бумаги действительно легче всего взять верхний лист, который попадает в стопу последним. Место, куда помещаются и из которого извлекаются элементы стека, называется вершиной.

Для работы со стеком определяют два основных действия или операции:

push – поместить новый элемент в стек и

pop – извлечь последний элемент, помещенный в стек.

Для наглядности стек можно представлять себе как вертикальную стопку книг или кирпичей, положенных друг на друга. Очередной кирпич кладется на верх стопки, извлекается же из стопки проще всего самый верхний кирпич. Таким образом, LIFO – это естественная дисциплина работы со стопкой кирпичей. В программировании стеки часто бывают полезны для решения различных задач.

Реализовать стек можно различными способами. В приводимой далее программе элементы стека размещаются в массиве.

Модули

Объявления функций для работы со стеком поместим в заголовочном файле Stack.h, определения функций и переменных поместим в файл реализации Stack.cpp. Совокупность заголовочного файла и файла реализации принято называть модулем. В C++ Builder для этого используется термин unit. В C++Builder создание модулей автоматизировано: заготовка нового модуля добавляется в проект командой File, New, Unit, при этом заголовочный файл модуля будет

иметь страж включения. В TC заголовочный файл и файл реализации создаются по отдельности.

Программа 52. Реализация стека в виде массива

Рассмотрим стек, элементами которого являются символы. Программа состоит из трех файлов: Stack.h, Stack.cpp и Brackets.cpp. Файл Stack.h содержит объявления функций для работы со стеком.

// Файл Stack.h

 

#ifndef STACKH

// Страж

#define STACKH

// включения

void push(int c);

// Поместить c в стек

int pop();

// Извлечь элемент из вершины стека

#endif

 

Реализация функций для работы со стеком находится в файле

Stack.cpp.

// Файл Stack.cpp

 

Программы из нескольких файлов

237

#include <iostream.h>

 

 

#include ”stack.h”

 

 

static const int SZ = 100;

// Максимальный размер стека

 

static char s[SZ];

// Массив под элементы стека

 

static int sp = 0;

// Позиция свободного элемента массива

// push: поместить c в стек

 

 

void push(int c)

 

 

{

 

 

if(sp < SZ)

// Если в массиве есть место,

 

s[sp++] = c;

// помещаем символ в стек

 

else

 

 

cerr << "Стек полон," << char(c) << "не помещается \n";

 

}

 

 

// pop: извлечь элемент из вершины стека

 

int pop()

 

 

{

 

 

if(sp > 0)

// Если в стеке есть символы,

 

return s[--sp];

// берем символ с вершины стека

 

else{

 

 

cerr << "Стек пуст\n"; return EOF;

}

}

В функции main организовано посимвольное чтение текста и его анализ на правильность расстановки скобок. Все открывающие скобки, встреченные в тексте, помещаются в стек. Если встречается закрывающая скобка, то из вершины стека извлекается последняя встреченная открывающая скобка и сравнивается с закрывающей. Если скобки соответствуют друг другу, продолжается анализ, если не соответствуют, то это ошибка. Ошибкой являются также случаи, когда закрывающая скобка идет раньше открывающей и когда открывающих скобок больше чем закрывающих.

// Файл Brackets.cpp #include <iostream.h> #include <stdlib.h> #include <conio.h> #include "stack.h"

int main()

 

{

 

int c, bro;

 

while((c = cin.get()) != EOF)

// Чтение символов

if('(' == c || '[' == c || '{' == c)

// Открывающие скобки

push(c);

// помещаем в стек