Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

1.5. Классы 45

1.5.5 Стандартная библиотека шаблона

Standard Template Library (STL) - коллекция полезных классов для общего

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

очередь стека deque вектор l i Св.

Контейнер с Контейнером доступа метода «последним пришел - первым вышел» с доступом метода «первым пришел - первым вышел» Симметричное множество очереди Изменяемога размера Вдвойне связал список

приоритетная Очередь очереди приказана стоимостью

набор Карта набора Ассоциативное множество (словарь)

Шаблоны и векторный класс STL

Одна из важных особенностей STL - то, что каждый такой объект может хранить объекты

из любого типа. Противопоставьте это классу Vect Раздела 1.5.2, который может только держать целые числа. Такой класс, определение которого зависит от определенного пользователями типа, называют шаблоном. Мы обсуждаем шаблоны более подробно в Главе 2, но мы, которых упоминают briefly, как они используются с контейнерными объектами здесь.

Мы определяем тип объекта, сохраненного в контейнере в угольниках (<...>). Например, мы могли определить векторы, чтобы держать 100 целых чисел, 500 знаков и 20 пассажиров следующим образом:

#include <вектор>

использование namespace станд.; //делают станд. доступным

вектор <интервал> очки (100); //100 векторов очков целого числа <случайная работа> буфер (500); //буфер 500 векторов знаков <Пассажир> passenList (20); //список 20 Пассажиров

Как обычно, включать заявление предоставляет необходимые декларации для использования векторного класса. Каждый случай вектора STL может только держать объекты одного типа.

Векторы STL превосходят стандарт C ++ множества во многих отношениях. Во-первых, как со множествами, отдельные элементы могут быть внесены в указатель, используя обычного оператора индекса ([]). К ним можно также получить доступ в членской функции. Преимущество последнего состоит в том, что это выполняет проверку диапазона и производит ошибочное исключение, если индекс выходит за пределы. (Мы обсуждаем исключения в Разделе 2.4.) Вспоминают, что стандартные множества в C ++ даже не знают свой размер, и следовательно располагаются, проверяя, даже не возможно. Напротив, векторный размер объекта дан его членской функцией размера. В отличие от этого

46

Глава 1. C ++ множества стандарта Учебника для начинающих, один векторный объект может быть назначен на другого, который приводит к содержанию одного векторного объекта, скопированного к другому. Вектор может быть изменен динамично, вызвав изменять размеры членскую функцию. Мы показываем несколько примеров использования векторного класса STL ниже.

интервал i =//...

суд <<очки [я]; bufer.at (i) = bufer.at (2 * i); вектор <интервал> newScores = очки; scores.resize (scores.size () + 10);

Мы обсуждаем STL далее в Главе 3.

Больше на последовательностях STL

// // // //

индекс (неконтролируемый диапазон) индекс (проверенный диапазон) очки копии к newScores добавляет комнату для еще 10 элементов

В Разделе 1.1.3 мы ввели класс последовательности STL. Этот класс обеспечивает много полезных утилит для управления строками символов. Ранее, мы обсудили использование дополнительного оператора (» + «) для связывания последовательностей, оператор «+ =» для добавления последовательности до конца существующей последовательности, размера функции для определения длины последовательности и оператора индексации (» []») для доступа к отдельным знакам последовательности.

Давайте представим еще несколько строковых функций. В столе ниже, позвольте s быть последовательностью STL и позволить p быть или последовательностью STL или стандартом C ++ последовательность. Позвольте мне и m быть неотрицательными целыми числами. Повсюду, мы используем i, чтобы обозначить индекс положения в последовательности, и мы используем m, чтобы обозначить число знаков, вовлеченных в операцию. (Первый характер последовательности в индексе i = 0.)

s.find (p) s.find (p, i)

s.substr (я, m)

s.insert (я, p) s.erase (я, m) s.replace (я, m, p)

getline (s),

Возвратите индекс из первого возникновения последовательности p в Возвращении s индекс первого возникновения последовательности p в s на или после положения я Возвращение, подстрока, начинающаяся в положении i s и состоящая из m p последовательности Вставки знаков только до индекса i в s, Удаляет подстроку длины m начинающийся в индексе, я Заменяю подстроку длины m начинающийся в индексе i с p Рида, который единственная линия от входного потока, и сохраните результат в s

Чтобы указать, что p последовательности образца не найден, функция находки возвращает специальную последовательность стоимости:: npos. Последовательности могут также быть сравнены лексикографически, используя C ++ операторы сравнения: <<=>,> =, ==, и! =.

1.6. C ++ программа и организация файла 47

Вот некоторые примеры использования этих функций.

натяните s = «собака»;

s + = «я s d o g»; суд <<s.find («собака»); суд <<s.find («собака», 3);

если (s.find («doug») == последовательность:: npos)

суд <<s.substr (7, 5);

s.replace (2, 3, «лягушка»); s.erase (6, 3); s.insert (0,);

если (s == «лягушка собака»)

если (s <«лягушка жаба»), если (s <«лягушка кошка»)

//

// // // // // // // // // // //

«g»

«g i s, g «211 истинных» s d» «лягушка является собакой» «лягушка собака», «является лягушкой собака», верная верный ложный

1.6

C ++ программа и организация файла

Давайте теперь рассмотрим более широкую проблему того, как организовать весь C ++ программа. Типичный большой C ++ программа состоит из многих файлов со связанными частями кодекса, проживающего в каждом файле. Например, C ++ программисты обычно помещают каждый главный класс в его собственный файл.

Исходные файлы

Есть два типа общего файла, исходные файлы и заголовочные файлы. Исходные файлы typi-

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

Различные компиляторы используют различные соглашения обозначения файла. У имен исходного файла, как правило, есть отличительные суффиксы, такие как «.cc», «.cpp», и «.C». Исходные файлы могут быть собраны отдельно компилятором, и затем эти файлы объединены в одну программу системной программой, названной компоновщиком.

Каждая непостоянная глобальная переменная и функция могут быть определены только однажды. Другие исходные файлы могут разделить такую глобальную переменную или функцию, если у них есть соответствующая декларация. Чтобы указать, что глобальная переменная определена в другом файле, спецификатор типа «экстерн» добавлен. Это ключевое слово не необходимо для функций. Например, считайте декларации извлеченными из двух файлов ниже. Файл Source1.cpp определяет кошку глобальную переменную и функцию foo. Файл Source2.cpp может получить доступ к этим объектам включением соответствующих деклараций соответствия и добавлением «экстерна» для переменных. Файл: Source1.cpp

международная кошка = 1; //определение интервала кошки foo (интервал x)возвращают x+1; //определение foo

48 Глава 1. C ++ учебник для начинающих

Файл: Source2.cpp

кошка интервал экстерна; //кошка определена в другом месте

интервал foo (интервал x); //foo определен в другом месте

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

Так как исходные файлы, используя общие объекты должны предоставить идентичные декларации, мы com-

monly хранят эти общие декларации в заголовочном файле, который тогда прочитан в каждый такой исходный файл, используя #include заявление. Начало заявлений # обработано специальной программой, названной препроцессором, который призван automati-cally компилятором. Заголовочный файл, как правило, содержит много деклараций, включая классы, структуры, константы, перечисления и typedefs. Заголовочные файлы обычно не содержат определение (тело) функции. Действующие функции - excep-tion, однако, поскольку их тела даны в заголовочном файле.

За исключением некоторых стандартных заголовков библиотеки, соглашение состоит в том, что заголовочный файл называет конец с «.h» суффиксом. Стандартные заголовочные файлы библиотеки обозначены с угольниками, как в <iostream>, в то время как другие местные заголовочные файлы обозначены, используя кавычки, как в «myIncludes.h».

#include <iostream> //система включают файл

#include «myIncludes.h» //определенный пользователями включают файл

Как правило мы должны избежать включая namespace использования директив в

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

1.6.1 Программа в качестве примера

Чтобы сделать это описание более конкретным, давайте рассмотрим пример простого

все же закончите C ++ программа. Наш пример состоит из одного класса, названного CreditCard, который определяет объект кредитной карты и процедуру, которая использует этот класс.

Класс CreditCard

Объект кредитной карты, определенный CreditCard, является упрощенной версией традиционного

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

Главная структура класса представлена в заголовочном файле CreditCard.h и

показанный в Кодовом Фрагменте 1.2.

1.6. C ++ программа и организация файла 49

#ifndef КРЕДИТНАЯ КАРТА H #define КРЕДИТНАЯ КАРТА H

#include <последовательность> #include <iostream>

класс CreditCard

общественность:

CreditCard (константа std::string& не,

//избегите повторенного расширения

//обеспечивает последовательность//обеспечивает ostream

//конструктор

константа std::string& nm, интервал lim, дважды bal=0);

станд.:: станд. последовательности:: натяните удваивают интервал

getNumber () константа getName () константа getBalance () константа getLimit () константа

//функции accessor

возвращают число;

возвращают имя;возвращают баланс;возвращают предел;

bool chargeIt (удваивают цену);

//

предъявите обвинение

пустота makePayment (удваивают оплату);

//

осуществите платеж

частный:

//

данные члена парламента, не занимающего официального поста

станд.:: последовательность

оцепенелый er;

//

номер кредитной карточки

станд.:: последовательность

имя;

//

имя владельца карты

интервал

предел;

//

кредитный лимит

дважды

шахта ance;

//

баланс кредитной карты

;

//информация о карте печати

std::ostream& оператор <<(std::ostream&, константа CreditCard& c); #endif

Кодовый Фрагмент 1.2: CreditCard.h заголовочного файла, который содержит определение класса CreditCard.

50

Глава 1. C ++ учебник для начинающих

Прежде, чем обсудить класс, давайте скажем немного об общей структуре файла. Первые две линии (содержащий #ifndef и #define) и последняя линия (содержащий #endif) используются, чтобы препятствовать тому же самому заголовочному файлу расширяться дважды. Мы обсуждаем это позже. Следующие строки включают заголовочные файлы для последовательностей и стандартного входа и выхода.

У этого класса есть четыре частных участника данных. Мы предоставляем простому конструктору, чтобы инициализировать этих участников. Есть четыре функции accessor, которые обеспечивают доступ, чтобы прочитать текущую стоимость этих членских переменных. Конечно, мы, возможно, поочередно определяли членские переменные, как являющиеся общественным, и экономили работу обеспечения этих функций accessor. Однако это позволило бы пользователям изменять любую из этих членских переменных непосредственно. Мы обычно предпочитаем ограничивать модификацию членских переменных к специальным функциям обновления. Мы включаем два таких обновления func-tions, chargeIt и makePayment. Мы также определили оператора продукции потока для класса.

Функции accessor и makePayment коротки, таким образом, мы определяем их в пределах тела класса. Другой участник функционирует, и оператор продукции определены вне класса в файле CreditCard.cpp, показанный в Кодовом Фрагменте 1.3. Этот подход определения заголовочного файла с определением класса и связанного исходного файла с более длинными членскими определениями функции распространен в C ++.

Главная тестовая программа

Наша главная программа находится в файле TestCard.cpp. Это состоит из главной функции, но этого

функция действительно немного больше, чем вызывает функцию testCard, который делает всю работу. Мы включаем CreditCard.h, чтобы предоставить декларацию CreditCard. Мы не должны включать iostream и последовательность, так как CreditCard.h делает это для нас, но не повредило бы делать так.

Функция testCard объявляет множество указателей на CreditCard. Мы ассигнуем три таких объекта и инициализируем их. Мы тогда выполняем много платежей и печатаем связанную информацию. Мы показываем полный кодекс для Испытательного класса в Кодовом Фрагменте 1.4.

Продукцию Испытательного класса посылают в стандартный поток продукции. Мы показываем эту продукцию в Кодовом Фрагменте 1.5.

Предотвращение многократных расширений заголовка

Типичный C ++ программа включает много различных заголовочных файлов, которые часто включают

другие заголовочные файлы. В результате тот же самый заголовочный файл может быть расширен много раз. Такое повторное расширение заголовка расточительно и может привести к ошибкам компиляции из-за повторных определений. Чтобы избежать этого повторного расширения, большинство заголовочных файлов использует комбинацию команд препроцессора. Давайте объясним процесс, иллюстрированный в Кодовом Фрагменте 1.2.

1.6. C ++ программа и организация файла 51

#include «CreditCard.h» //предоставляет CreditCard

использование namespace станд.; //делают станд.:: доступный

//типичный конструктор

CreditCard:: CreditCard (константа string& не, константа string& nm, интервал lim, удваивает шахту)

ошеломите er = нет;

назовите = nm; шахта ance = шахта; l i ми t = l я;

//предъявите обвинение

bool CreditCard:: chargeIt (удваивают цену)

если (цена + баланс> двойной (предел))

возвратитесь ложный; //по пределу балансируют + = цена; возвратитесь верный; //обвинение проходит

недействительный CreditCard:: makePayment (двойная оплата)//осуществляют платеж

баланс- = оплата;

//информация о карте печати

ostream& оператор <<(ostream&, константа CreditCard& c)

o единое время <<«N u m b e r =» <<c.getNumber () <<«\n»

<<«Имя = « <<c.getName () <<» \n»

<<«Баланс = «<<c.getBalance () <<» \n»

<<«Предел = « <<c.getLimit () <<» \n»;

возвратитесь;

Кодовый Фрагмент 1.3: CreditCard.cpp файла, который содержит определение членских функций из класса для класса CreditCard.

52 Глава 1. C ++ учебник для начинающих

#include <вектор> //обеспечивает вектор STL

#include «CreditCard.h» //предоставляет CreditCard, суду, последовательности

использование namespace станд.; //делают станд. доступным

пустота testCard ()

вектор <CreditCard*> бумажник (10);

//Испытательная функция CreditCard//вектор 10 указателей CreditCard//ассигнует 3 новых карты

бумажник [0] = новый CreditCard («5391 0375 9387 5309», «Джон Боумен», 2500); бумажник [1] = новый CreditCard («3485 0399 3395 1954», «Джон Боумен», 3500); бумажник [2] = новый CreditCard («6011 4902 3294 2994», «Джон Боумен», 5000);

для (интервал j=1; j <= 16; j ++)

бумажник [0]-> chargeIt (двойной (j)); бумажник [1]-> chargeIt (2 * j); бумажник [2]-> chargeIt (дважды (3 * j));

co единое время <<«C r d p y m e n t s: \n»;

//сделайте некоторые обвинения//явно бросок, чтобы удвоиться//неявно бросок, чтобы удвоиться

для (интервал i=0; я <3; я ++)

суд <<*бумажник [я];

в то время как (бумажник [я]-> getBalance ()> 100.0)

бумажник [я]-> makePayment (100.0);

//сделайте больше обвинений

суд <<«Новый баланс = «<<бумажник [я]-> getBalance () <<» \n»;

единое время co <<«\n»; удалите бумажник [я];

//освободите хранение

международное основное () //главная функция

testCard ();

возвратите ВЫХОДНОЙ УСПЕХ; //успешное выполнение

Кодовый Фрагмент 1.4: файл TestCard.cpp.

Давайте начнем со второй линии. #define заявление определяет КРЕДИТНУЮ КАРТУ переменной препроцессора H. Имя этой переменной типично основано на имени заголовочного файла, и в соответствии с соглашением, это написано во всех капиталах. Само имя не важно, пока различные заголовочные файлы используют различные имена. Весь файл приложен в препроцессоре «если» блок, начинающийся с #ifndef на вершине и заканчивающийся #endif в основании. «Ifndef» прочитан, «если не определенный», означая, что содержание заголовочного файла будет расширено, только если КРЕДИТНАЯ КАРТА переменной препроцессора H не определена.

Вот то, как это работает. В первый раз с заголовочным файлом сталкиваются, переменная

1.7. Написание C ++ программа

Платежи по карте: N u mb er = 5 3 9 1 0 3 7 5 9 3 8 7 5 3 0 9 Имен = Джон Боумен Баланс = 136 Пределов = 2 500 Н ew шахта ance = 3 6

N umb er = 3 4 8 5 0 3 9 9 3 3 9 5 1 9 5 4 Имени = Джон Боумен Баланс = 272 Предела = 3 500 Н ew шахта ance = 1 7 2 Н ew шахта ance = 7 2

N umb er = 6 0 1 1 4 9 0 2 3 2 9 4 2 9 9 4 Имени = Джон Боумен Баланс = 408 Пределов = 5 000 Н ew шахта ance = 3 0 8 Н ew шахта ance = 2 0 8 Н ew шахта ance = 1 0 8 Н ew шахта ance = 8

Кодовый Фрагмент 1.5: Типовая программа произведена.

53

КРЕДИТНАЯ КАРТА H еще не была замечена, таким образом, заголовочный файл расширен препроцессором. В процессе выполнения этого расширения вторая линия определяет переменную КРЕДИТНУЮ КАРТУ H. Следовательно, любая попытка включать заголовочный файл найдет, что КРЕДИТНАЯ КАРТА H определена, таким образом, файл не будет расширен.

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

1.7

Написание C ++ программа

Как с любым языком программирования, сочиняя программу в C ++ включает три забавы - damental шаги:

1. Дизайн 2. Кодирование 3. Тестирование и отладка.

Мы briefly обсуждаем каждый из этих шагов в этой секции.

54 Глава 1. C ++ учебник для начинающих

1.7.1 Дизайн

Шаг дизайна является, возможно, самым важным в процессе написания программы.

В этом шаге мы решаем, как разделить работы нашей программы в классы, мы решаем, как эти классы будут взаимодействовать, какие данные каждый будет хранить, и какие действия каждый выполнит. Действительно, одна из главных проблем, что начало C ++ про - grammers лицо решает что классы определить, чтобы сделать работу их программы. В то время как общие предписания тверды прибыть, есть некоторые общие правила большого пальца, что мы можем обратиться, определяя, как определить наши классы.

Обязанности: Разделите работу на различных актеров, каждого с различным

ответственность. Попытайтесь описать обязанности, используя глаголы действия. Они

актеры формируют классы для программы.

Независимость: Определите работу для каждого класса, чтобы быть столь же независимыми от

другие классы как возможные. Подразделите обязанности между классами так, чтобы

у каждого класса есть автономия по некоторому аспекту программы. Дайте данные (как членские переменные) к классу, который обладает юрисдикцией по действиям что пере - доступ печатного листа к этим данным.

Поведения: Определите поведения для каждого класса тщательно и точно, таким образом,

то, что последствия каждого действия, выполненного классом, находятся хорошо под -

поддержанный другие классы, с которыми это взаимодействует. Эти поведения определяют членские функции, которые выполняет этот класс. Набор поведений для класса иногда упоминается как протокол, так как мы ожидаем, что поведения для класса скрепят как связная единица.

Определение классов, вместе с их членскими переменными и участником func-tions, определяет дизайн C ++ программа. Хороший программист естественно разовьет большее умение в выполнении этих задач в течение долгого времени, поскольку опыт учит его или ее замечать образцы в требованиях программы, которые соответствуют образцам, которые он или она видел прежде.

1.7.2 Псевдокодекс

Программистов часто просят описать алгоритмы в пути, который предназначен для

человеческие глаза только, до написания фактического кодекса. Такие описания называют псевдо - кодекс. Псевдокодекс не компьютерная программа, но более структурирован чем обычно проза. Псевдокодекс - смесь естественного языка и программных конструкций высокого уровня, которые описывают главные идеи позади универсального внедрения структуры данных или алгоритма. Действительно нет никакого точного определения псевдокодовой LAN - guage, однако, из-за ее уверенности в естественном языке. В то же время, чтобы помочь достигнуть ясности, псевдокодекс смешивает естественный язык со стандартной программой - ming языковые конструкции. Конструкции языка программирования, которые мы выбираем, являются совместимыми с современными языками высокого уровня, такими как C, C ++, и Ява.

1.7. Написание C ++ программа 55

Эти конструкции включают следующее:

Выражения: Мы используем стандартные математические символы, чтобы выразить числовой

и Булевы выражения. Мы используем левый знак (к) стрелы в качестве назначения

оператор в операторах присваивания (эквивалентный = оператор в C ++) и

мы используем равный знак (=) как отношение равенства в Булевых выражениях (эквивалентный «==» отношение в C ++).

Декларации функции: имя Алгоритма (arg1, arg2...) объявляет новое

функционируйте «имя» и его аргументы.

Структуры решения: если условие тогда истинные действия [еще ложные действия]. Мы

используйте углубление, чтобы указать на то, какие действия должны быть включены в истинные действия

и ложные действия.

В-то-время-как-петли: в то время как условие делает действия. Мы используем углубление, чтобы указать

какие действия должны быть включены в действия петли.

Повторные петли: повторите действия до условия. Мы используем углубление, чтобы указать

какие действия должны быть включены в действия петли.

Для петель: поскольку переменное определение приращения делает действия. Мы используем углубление

указать на то, какие действия должны быть включены среди действий петли.

Индексация множества: [я] представляет ith клетку во множестве A. Клетки

A множества n-celled внесены в указатель от [0] к [n- 1] (совместимый с C ++).

Членские вызовы функции: object.method (args) (объект дополнительный, если это не -

derstood).

Прибыль функции: возвращаемое значение. Эта операция возвращает определенную стоимость

к методу, который названный этим.

Комментарии:Комментарий идет сюда.. Мы прилагаем комментарии в скобах.

Когда мы пишем псевдокодекс, мы должны иметь в виду, что пишем для a

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

1.7.3 Кодирование

Как упомянуто выше, один из ключа ступает в кодирование ориентированного на объект про -

грамм кодирует описания классов и их соответствующих данных и членских функций. Чтобы ускорить развитие этого умения, мы обсуждаем vari-ous шаблоны для проектирования ориентированных на объект программ (см. Раздел 2.1.3) в различных пунктах всюду по этому тексту. Эти образцы обеспечивают шаблоны для определения классов и взаимодействий между этими классами.

Много программистов делают свое кодирование начальной буквы не на компьютере, а при помощи карт CRC. Карты Class-Responsibility-Collaborator (CRC) - простые учетные карточки, которые подразделяют работу, требуемую программы. Главная идея позади этого инструмента к

56

Глава 1. C ++ у Учебника для начинающих есть каждая карта, представляют компонент, который в конечном счете станет классом в нашей программе. Мы написали имя каждого компонента на вершине учетной карточки. Слева карты, мы начинаем писать обязанности по этому com-ponent. Справа, мы перечисляем сотрудников для этого компонента, то есть, другие компоненты, что этот компонент должен будет взаимодействовать с выполнить его обязанности. Процесс проектирования повторяет через цикл действия/актера, где мы сначала определяем действие (то есть, ответственность), и мы тогда определяем актера (то есть, компонент), который подходит лучше всего, чтобы выполнить то действие. Дизайн завершен, когда мы назначили все действия актерам.

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

Альтернатива картам CRC - использование UML (Объединенный Язык Моделирования) диаграммы, чтобы выразить организацию программы и использование псевдокодекса, чтобы описать алгоритмы. Диаграммы UML - стандартное визуальное примечание, чтобы выразить ориентированное на объект проектирование программного обеспечения. Несколько автоматизированных инструментов доступны, чтобы построить диаграммы UML. Описание алгоритмов в псевдокодексе, с другой стороны, является техникой, которую мы используем всюду по этой книге.

Как только мы выбрали классы и их соответствующие обязанности по нашим программам, мы готовы начать кодировать. Мы создаем фактический кодекс для классов в нашей программе или при помощи независимого редактора текста (таких как emacs, блокнот, или при помощи vi), или редактор, включенный в интегрированную среду проектирования (IDE), таких как Визуальная Студия и Затмение Microsoft.

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

Удобочитаемость и стиль

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

• Используйте значащие названия идентификаторов. Попытайтесь выбрать имена, которые могут быть прочитаны

вслух и reflect действие, ответственность или данные каждый идентификатор является nam -

луг. Традиция в большей части C ++ круги должна использовать для своей выгоды первое письмо от каждого слова в идентификаторе, за исключением первого слова в идентификаторе для переменной или метода. Так, в этой традиции, «Дате», «Векторе» и «DeviceManager»

1.7. Написание C ++ программа 57

определил бы классы и «isFull», «insertItem», «studentName», и «stu -

dentHeight» соответственно определил бы членские функции и переменные.

• Используйте названные константы и перечисления вместо вложенных ценностей. Читайте -

способность, надежность и модифицируемость увеличены, если мы включаем серию

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

МИНИМАЛЬНЫЕ КРЕДИТЫ интервала константы = 12; //минимальные кредиты в интервале константы термина КРЕДИТЫ МАКСА = 24; //максимальные кредиты в термине

//перечисление в течение года

Год enumНОВИЧОК, ВТОРОКУРСНИК, ЖУНИОР СТАРШий;

• Блоки заявления заявки. Как правило, заявка программистов каждый блок заявления

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

наш кодекс наводняет края книги.)

• Организуйте каждый класс в последовательном заказе. В примерах в этой книге, нас

обычно используйте следующий заказ:

1. Общественность печатает и вложенные классы

2. Общественный участник функционирует 3. Защищенный участник функционирует (внутренние утилиты) 4. Данные члена парламента, не занимающего официального поста

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

• Используйте комментарии, которые добавляют значение к программе и объясняют неоднозначный или

путание конструкций. Действующие комментарии хороши для быстрых объяснений и

не должны быть предложения. Комментарии блока хороши для объяснения цели метода и сложных кодовых разделов.

1.7.4 Тестирование и отладка

Тестирование - процесс подтверждения правильности программы, отлаживая

процесс прослеживания выполнения программы и обнаружения ошибок в нем. Тестирование и отладка часто - самая отнимающая много времени деятельность в развитии программы.

Тестирование

Тщательный план тестирования - основная часть написания программы. Проверяя

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

58

Глава 1. C ++ Учебник для начинающих, по крайней мере, однажды (освещение метода). Еще лучше каждое кодовое заявление в программе должно быть выполнено, по крайней мере, однажды (освещение заявления).

Программы часто имеют тенденцию терпеть неудачу на особых случаях входа. Такие случаи должны быть тщательно определены и проверены. Например, проверяя метод, который сортирует множество целых чисел (то есть, устраивает их в порядке возрастания), мы должны рассмотреть следующие входы:

У множества есть нулевая длина (никакие элементы)

У множества есть один элемент все элементы множества - то же самое множество уже сортировано множество обратное сортированный

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

Есть иерархия среди классов и функций программы, вызванной отношениями «посетителя-вызываемого». А именно, функция A выше функции B в иерархии если требования B. Есть две главных стратегии тестирования, нисходящие и восходящие, которые отличаются по заказу, в котором проверены функции.

Восходящее тестирование продолжается от функций низшего уровня до более высокого уровня func-tions. А именно, функции нижнего уровня, которые не призывают другие функции, проверяются сначала, сопровождаются функциями, которые вызывают только функции нижнего уровня и так далее. Эта стратегия гарантирует, что ошибки, найденные в методе, вряд ли будут вызваны функциями низшего уровня, вложенными в пределах нее.

Сверху вниз проверяя доходы от вершины до основания иерархии метода. Это, как правило, используется вместе с гашением, метод самонастройки, который заменяет метод низшего уровня окурком, заменой для метода что simu-последний продукция оригинального метода. Например, если функция требования функционируют B, чтобы получить первую линию файла, мы можем заменить B окурком, который возвращает фиксированную последовательность, проверяя A.

Отладка

Самый простой метод отладки состоит из использования заявлений печати (как правило, нас -

луг поток произвел оператора, «<<») отслеживать ценности переменных во время выполнения программы. Проблема с этим подходом состоит в том, что государство печати - монетные дворы должны быть удалены или прокомментированы, прежде чем программа может быть выполнена как часть «производственной» системы программного обеспечения.

1.7. Написание C ++ программа 59

Лучший подход должен управлять программой в пределах отладчика, который является специальным предложением -

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

Много ИД, таких как Microsoft Visual Studio и Затмение обеспечивают встроенный de - педерасты.

60 Глава 1. C ++ учебник для начинающих

1.8

Упражнения

Для помощи с упражнениями, пожалуйста, посетите веб-сайт, www.wiley.com/college/goodrich. <www.wiley.com/college/goodrich>

Укрепление

R-1.1 Какое из следующего не является действительным C ++ имя переменной? (Может быть

больше чем один.)

a. я думаю, что я - действительный b., который я могу иметь 2 много цифр, чтобы быть действительным c. Я начинаю и заканчиваю, подчеркивает d. У меня Есть Долларовый $ign e. Я ДЛИНЕН И НЕ ИМЕЮ НИКАКИХ ПИСЕМ О НИЖНЕМ РЕГИСТРЕ

R-1.2 Напишите псевдокодовое описание метода для нахождения самого маленького и

наибольшие числа во множестве целых чисел и сравнивают это с C ++ функция, которая сделала бы ту же самую вещь.

R-1.3 Дайте C ++ определение struct под названием Пара, которая состоит из двух мадам -

bers. Первым является целое число, названное сначала, и второй является двойная названная секунда.

R-1.4 Что является содержанием последовательности s после выполнения следующих заявлений.

натяните s = «ABC»; натяните t = «cde»; s + = s + t[1] + s;

R-1.5 Рассмотрите выражение y + 2 * z ++ <3 - w / 5. Добавьте круглые скобки

показать точный заказ оценки, данной C ++, управляет для предшествования оператора.

R-1.6 Рассмотрите следующую попытку ассигновать множество с 10 элементами указателей

к удваивается, и инициализируйте связанные двойные ценности к 0,0. Перепишите следующий (неправильный) кодекс, чтобы сделать это правильно. (Намек: Хранение для удваивает потребности, которые будут ассигнованы.)

удвойтесь* разность потенциалов [10] для (интервал i = 0; я <10; я ++) разность потенциалов [я] = 0.0;

R-1.7 Напишите короткий C ++ функция, которая берет целое число n и возвращает сумму

все целые числа, меньшие, чем n.

R-1.8 Напишите короткий C ++ функция, isMultiple, который берет две положительных длинных ценности,

n и m и прибыль, верная, если и только если n - кратное число m, то есть, n = ми для некоторого целого числа i.