.
До настоящего момента каждый создаваемый вами объект имел свой собственный набор элементов данных. В зависимости от назначения вашего приложения могут быть ситуации, когда объекты одного и того же класса должны совместно использовать один или несколько элементов данных. Например, предположим, что вы пишете программу платежей, которая отслеживает рабочее время для 1000 служащих. Для определения налоговой ставки программа должна знать условия, в которых работает каждый служащий. Пусть для этого используется переменная класса state_of_work. Однако, если все служащие работают в одинаковых условиях, ваша программа могла бы совместно использовать этот элемент данных для всех объектов типа employee. Таким образом, ваша программа уменьшает необходимое количество памяти, выбрасывая 999 копий одинаковой информации. Для совместного использования элемента класса вы должны объявить этот элемент как static (статический). Этот урок рассматривает шаги, которые вы должны выполнить для совместного использования элемента класса несколькими объектами. К концу этого урока вы освоите следующие основные концепции:
C++ позволяет иметь объекты одного и того же типа, которые совместно используют один или несколько элементов класса.
Если ваша программа присваивает значение совместно используемому элементу, то все объекты этого класса сразу же получают доступ к этому новому значению.
Для создания совместно используемого элемента данных класса вы должны предварять имя элемента класса ключевым словом static.
После того как программа объявила элемент класса как static, она должна объявить глобальную переменную (вне определения класса), которая соответствует этому совместно используемому элементу класса.
Ваши программы могут использовать ключевое слово static, чтобы сделать метод класса вызываемым в то время, как программа, возможно, еще не объявила каких-либо объектов данного класса.
Если функция не изменяет структуру, вы можете передать структуру в функцию по имени. Например, следующая программа SHOW_EMP.CPP использует функцию show_employee для вывода элементов структуры типа employee:
cout "Номер служащего: " worker. employee_id endl;
Как видите, программа передает переменную типа данной структуры worker в функцию show__employee по имени. Далее функция show_employee выводит элементы структуры. Однако обратите внимание, что программа теперь определяет структуру employee вне main и до функции show_employee. Поскольку функция объявляет переменную worker типа employee, определение структуры employee должно располагаться до функции.
Как вы уже знаете, C++ позволяет вам обращаться к элементам массивов, используя указатели. Следующая программа ARGVPTR.CPP трактует argv как указатель на указатель символьной строки (другими словами, указатель на указатель), чтобы вывести содержимое командной строки:
Первая звездочка в объявлении сообщает компилятору C++, что argv представляет собой указатель. Вторая звездочка сообщает компилятору, что argv представляет собой указатель на указатель — в данном случае указатель на указатель типа char. Представьте argv как массив указателей. Каждый элемент массива в данном случае указывает на массив типа char.
Как вы уже знаете, программы на C++ хранят переменные в памяти. Указатель представляет собой адрес памяти, который указывает (или ссылается) на определенный участок. Из урока 10 вы узнали, что для изменения параметра внутри функции ваша программа должна передать адрес параметра (указатель) в функцию. Далее функция в свою очередь использует переменную-указатель для обращения к участку памяти. Некоторые программы, созданные вами в нескольких предыдущих уроках, использовали указатели на параметры. Аналогично этому, когда ваши программы работают с символьными строками и массивами, они обычно используют указатели, чтобы оперировать элементами массива. Так как применение указателей является общепринятым, очень важно, чтобы вы хорошо понимали их использование. Таким образом, этот урок рассматривает еще один аспект применения указателей. К концу данного урока вы освоите следующие основные концепции:
Для простоты (для уменьшения кода) многие программы трактуют символьную строку как указатель и манипулируют содержимым строки, используя операции с указателями.
Когда вы увеличиваете переменную-указатель (переменную, которая хранит адрес), C++ автоматически увеличивает адрес на требуемую величину (на 1 байт для char, на 2 байта для int, на 4 байта для float и т.д.).
Ваши программы могут использовать указатели для работы с массивами целочисленных значений или значений с плавающей точкой.
Операции с указателями широко используются в C++. Выберите время для эксперимента с программами, представленными в этом уроке.
Чтобы определить конец символьной строки, каждая из предыдущих программ использовала следующий цикл while:
Как уже обсуждалось, символ NULL ('\0') представляет собой значение ASCII 0. Так как C++ использует значение 0, чтобы представить ложь, ваши программы могут записать предыдущий цикл следующим образом:
В данном случае пока символ, определяемый указателем строки, не равен 0 (NULL), условие оценивается как истинное и цикл будет продолжаться. Из урока 5 вы узнали, что постфиксная операция увеличения C++ позволяет вам использовать значение переменной, а затем увеличивает это значение. Многие программы на C++ используют постфиксные операции увеличения и уменьшения, чтобы сканировать массивы с помощью указателей. Например, использование постфиксной операции увеличения делает следующие циклы while идентичными:
Оператор cout *string++, заставляет C++ вывести символ, указываемый указателем string, а затем увеличить текущее значение string, чтобы он указывал на следующий символ. С помощью этих методов следующая программа SMARTPTR.CPP иллюстрирует новую реализацию функций show_string и string_length:
Если вы встретите функции C++, которые манипулируют строками с помощью указателей, то они с большой долей вероятности будут использовать подобную краткую запись.
Если вы используете cout для вывода значения с плавающей точкой, то обычно не можете сделать каких-либо предположений о том, сколько цифр будет выводить cout no умолчанию. Однако, используя манипулятор setprecision, вы можете указать количество требуемых цифр- Следующая программа SETPREC.CPP использует манипулятор setprecision для управления количеством цифр, которые появятся справа от десятичной точки:
Когда вы откомпилируете и запустите эту программу, на экране дисплея появится следующий вывод:
Если вы используете манипулятор setprecision для изменения точности, ваша установка действует до тех пор, пока программа повторно не использует setprecision.
В примерах программ, представленных в данном уроке, файловые операции ввода и вывода выполнялись с начала файла. Однако, когда вы записываете данные в выходной файл, вероятно, вы захотите, чтобы программа добавляла информацию в конец существующего файла. Для открытия файла в режиме добавления вы должны при его открытии указать второй параметр, как показано ниже:
В данном случае параметр ios::app указывает режим открытия файла. По мере усложнения ваших программ они будут использовать сочетание значений для режима открытия файла, которые перечислены в табл. 34.
Таблица 34. Значения режимов открытия.
|
Режим открытия
|
Назначение
ios::app |
|
Открывает файл в режиме добавления, располагая файловый указатель в конце файла.
ios::ate |
Располагает файловый указатель в конце файла. |
ios::in |
Указывает открыть файл для ввода. |
ios::nocreate |
|
Если указанный файл не существует, не создавать файл и возвратить ошибку.
ios::noreplace |
Если файл существует, операция открытия должна быть прервана и должна возвратить ошибку. |
ios::out |
Указывает открыть файл для вывода. |
ios::trunc |
Сбрасывает (перезаписывает) содержим, з существующего файла. |
Следующая операция открытия файла открывает файл для вывода, используя режим ios::noreplace, чтобы предотвратить перезапись существующего файла:
ifstream output_file("FIlename.EXT", ios::out | ios::noreplace);
Управление порядком, в котором C++ выполняет операции
Как вы уже знаете, C++ назначает операциям различный приоритет, который и управляет порядком выполнения операций. К сожалению, иногда порядок, в котором C++ выполняет арифметические операции, не соответствует порядку, в котором вам необходимо их выполнить. Например, предположим, что вашей программе необходимо сложить две стоимости и затем умножить результат на налоговую ставку:
cost = price_a + price_b * 1.06;
К сожалению, в этом случае C++ сначала выполнит умножение (price_b * 1.06), а затем прибавит значение price_a.
Если ваши программы должны выполнять арифметические операции в определенном порядке, вы можете заключить выражение в круглые скобки. Когда C++ оценивает выражение, он сначала всегда выполняет операции, сгруппированные в круглых скобках. Например, рассмотрим следующее выражение:
result =(2+3)* (3+4);
C++ вычисляет данное выражение в следующем порядке:
result = (2 + 3) * (3 + 4);
= (5) * (3 + 4);
= 5 * (7);
=5*7;
= 35;
Подобным образом группируя выражения внутри круглых скобок, вы можете управлять порядком, в котором C++ выполняет арифметические операции. Аналогично предыдущему примеру, ваша программа может сложить две стоимости внутри круглых скобок, как показано ниже:
cost = (price_a + price_b) * 1.06;
УПРАВЛЕНИЕ ШИРИНОЙ ВЫВОДА
Несколько предыдущих программ выводили числа на экран. Чтобы гарантировать правильное отображение этих чисел (с правильной расстановкой пробелов), программы включали пробелы до и после чисел. При выводе на cout или cerr ваши программы могут указать ширину вывода каждого числа, используя модификатор setw (установка ширины). С помощью setw программы указывают минимальное количество символов, занимаемое числом. Например, следующая программа SETW.CPP использует модификатор setw для выбора ширины 3, 4, 5 и 6 для числа 1001. Чтобы использовать модификатор setw, ваша программа должна включать заголовочный файл iomanip.h:
#include iostream.h
#include iomanip.h
void main (void)
{
cout "Мое любимое число равно" setw(3) 1001 endl;
cout "Мое любимое число равно" setw(4) 1001 endl;
cout "Мое любимое число равно" setw(5) 1001 endl;
cout "Мое любимое число равно" setw(6) 1001 endl;
}
Когда вы откомпилируете и запустите эту программу, на экране появится следующий вывод:
С:\ SETW ENTER
Мое любимое число равно1001
Мое любимое число равно1001
Мое любимое число равно 1001
Мое любимое число равно 1001
Если вы указываете ширину с помощью setw, вы указываете минимальное количество символьных позиций, занимаемых числом. В предыдущей программе модификатор setw(3) указывал минимум три символа. Однако, так как число 1001 потребовало больше трех символов, cout использовал реально требуемое количество, которое в данном случае равнялось четырем. Следует отметить, что при использовании setw для выбора ширины, указанная ширина действительна для вывода только одного числа. Если вам необходимо указать ширину для нескольких чисел, вы должны использовать setw несколько раз.
Замечание: Предыдущая программа использует заголовочный файл IOMANIP.H. Вам, возможно, понадобится сейчас напечатать и исследовать содержимое этого файла. Как и в случае с заголовочным файлом IOSTREAM.H вы найдете данный файл внутри подкаталога INCLUDE, который находится в каталоге с файлами вашего компилятора.
Управление свободной памятью
Из урока 31 вы узнали, что при выполнении ваши программы могут использовать оператор new для динамического распределения памяти из свободной памяти. Если оператор new успешно выделяет память, ваша программа получает на нее указатель. Если оператор new не может выделить требуемую память, он присваивает вашей переменной-указателю значение NULL. В зависимости от назначения вашей программы, вы, возможно, захотите, чтобы программа выполнила определенные операции, если new не может удовлетворить запрос на память. Из этого урока вы узнаете, как заставить C++ вызвать специальную функцию, если new не может удовлетворить запрос на память. К концу данного урока вы освоите следующие основные концепции:
Вы можете создать свой собственный обработчик ситуации, когда памяти недостаточно — функции, которую C++ вызывает, если new не может удовлетворить запрос на память.
C++ позволяет вам определить собственный оператор new для выделения и, возможно, инициализации памяти.
C++ позволяет вам определить собственный оператор delete для освобождения памяти.
Как вы узнаете, с помощью собственных операторов new и delete вы можете лучше управлять ошибками при недостаточности памяти.
Обычной операцией, которую вы будете
Обычной операцией, которую вы будете выполнять при программировании, является прибавление 1 к значению целой переменной. Например, предположим, что ваша программа использует переменную с именем count, чтобы сохранить данные о количестве напечатанных файлов. Каждый раз, когда программа печатает файл, 1 будет добавляться к текущему значению count. Используя оператор присваивания C++, ваша программа может увеличивать значение count, как показано ниже:
count = count + 1;
В данном случае программа сначала выбирает значение count, а затем добавляет к нему единицу. Далее программа записывает результат сложения обратно в переменную count. Следующая программа INTCOUNT.CPP использует оператор присваивания для увеличения переменной count (которая первоначально содержит значение 1000) на единицу (присваивая переменной результат 1001):
#include iostream.h
void main(void)
{
int count = 1000;
cout "начальное значение count равно" count endl;
count = count + 1;
cout "конечное значение count равно" count endl;
}
Когда вы откомпилируете и запустите эту программу, на вашем экране появится следующий вывод:
С:\ INCCOUNT ENTER
начальное значение count равно 1000
конечное значение count равно 1001
Так как увеличение значения переменной представляет собой обычную операцию в программах, в C++ есть операция увеличения — двойной знак плюс (++). Операция увеличения обеспечивает быстрый способ прибавления единицы к значению переменной. Следующие операторы, например, увеличивают значение переменной count на 1:
count = count + 1; count++;
Следующая программа INC_OP.CPP использует операцию увеличения для наращивания значения переменной count на 1:
#include iostream.h
void main(void)
{
int count = 1000;
cout "начальное значение count равно " count endl;
count++;
cout "конечное значение count равно " count endl;
}
Эта программа работает так же, как INCCOUNT.CPP, которая использовала оператор присваивания для увеличения значения переменной. Когда C++ встречает операцию увеличения, он сначала выбирает значение переменной, добавляет к этому значению единицу, а затем записывает результат обратно в переменную.
является то, что истина представляется
Достоинством C++ является то, что истина представляется как любое ненулевое значение, а ложь как 0. Предположим, ваша программа использует переменную с именем user_owns_a_dog, чтобы определить, есть ли у пользователя собака или нет. Если у пользователя нет собаки, вы можете присвоить этой переменной значение 0 (ложь), как показано ниже:
user_owns_a_dog = 0;
Если у пользователя есть собака, вы можете присвоить этой переменной любое ненулевое значение, например 1:
user_owns_a_dog = 1;
Затем ваши программы могут проверить эту переменную, используя оператор if, как показано ниже:
if (user_owns_a_dog)
Если переменная содержит ненулевое значение, условие оценивается как истина; в противном случае, если переменная содержит 0, условие ложно. Исходя из того, как C++ представляет истину и ложь, предыдущий оператор идентичен следующему:
if (user_owns_a_dog == 1)
Следующая программа DOG_CAT.CPP использует переменные user_owns_a_dog и user_owns_a_cat внутри оператора if, чтобы определить, какие животные есть у пользователя.
#include iostream.h
void main(void)
{
int user_owns_a_dog = 1;
int user_owns_a_cat = 0;
if (user_owns_a_dog)
cout "Собаки великолепны" endl;
if (user_owns_a_cat)
cout "Кошки великолепны" endl;
if ((user_owns_a_dog) (user_owns_a_cat))
cout "Собаки и кошки могут ужиться" endl;
if {(user_owns_a_dog) II (user_owns_a_cat))
cout "Домашние животные великолепны!" endl;
}
Экспериментируйте с этой программой, присваивая обоим переменным значение 1 или 0, а затем одной 1, а другой 0 и наоборот. Как видите, проверить два условия очень легко, используя логические операции И и ИЛИ.
ВСТРОЕННЫЕ ФУНКЦИИ
Когда вы определяете в своей программе функцию, компилятор C++ переводит код функции в машинный язык, сохраняя только одну копию инструкций функции внутри вашей программы. Каждый раз, когда ваша программа вызывает функцию, компилятор C++ помещает в программу специальные инструкции, которые заносят параметры функции в стек и затем выполняют переход к инструкциям этой функции. Когда операторы функции завершаются, выполнение программы продолжается с первого оператора, который следует за вызовом функции. Помещение аргументов в стек и переход в функцию и из нее вносит издержки, из-за которых ваша программа выполняется немного медленнее, чем если бы она размещала те же операторы прямо внутри программы при каждой ссылке на функцию. Например, предположим, что следующая программа CALLBEEP.CPP вызывает функцию show_message, которая указанное число раз выдает сигнал на динамик компьютера и затем выводит сообщение на дисплей:
#include iostream.b
void show_message(int count, char *message)
{
int i;
for (i = 0; i count; i++) cout '\a';
cout message endl;
}
void main(void)
{
show_message(3, "Учимся программировать на языке C++");
show_mes sage(2, "Урок 35");
}
Следующая программа NO_CALL.CPP не вызывает функцию show_message. Вместо этого она помещает внутри себя те же операторы функции при каждой ссылке на функцию:
#include iostream.h
void main (void)
{
int i;
for (i = 0; i 3; i++) cout '\a';
cout " Учимся программировать на языке C++" endl;
for (i = 0; i 2; i++) cout '\a';
cout "Урок 35" endl;
}
Обе программы выполняют одно и то же. Поскольку программа NO_CALL не вызывает функцию show_message, она выполняется немного быстрее, чем программа CALLBEEP. В данном случае разницу во времени выполнения определить невозможно, но, если в обычной ситуации функция будет вызываться 1000 раз, вы, вероятно, заметите небольшое увеличение производительности. Однако программа NO_CALL более запутана, чем ее двойник CALL_BEEP, следовательно, более тяжела для восприятия.
При создании программ вы всегда должны попытаться определить, когда лучше использовать обычные функции, а когда лучше воспользоваться встроенными функциями. Для более простых программ предпочтительно использовать обычные функции. Однако, если вы создаете программу, для которой производительность имеет первостепенное значение, вам следовало бы уменьшить количество вызовов функций. Один из способов уменьшения количества вызовов функций состоит в том, чтобы поместить соответствующие операторы прямо в программу, как только что было сделано в программе NO_CALL. Однако, как вы могли убедиться, замена только одной функции внесла значительную путаницу в программу. К счастью, C++ предоставляет ключевое слово inline, которое обеспечивает лучший способ.
Встроенные функции и ассемблерные коды
Начиная с урока 8, ваши программы интенсивно использовали функции. Как вы уже знаете, единственное неудобство при использовании функций состоит в том, что они увеличивают издержки (увеличивают время выполнения), помещая параметры в стек при каждом вызове. Из данного урока вы узнаете, что для коротких функций можно использовать метод, называемый встроенным кодом, который помещает операторы функции для каждого ее вызова прямо в программу, избегая таким образом издержек на вызов функции. Используя встроенные (inline) функции, ваши программы будут выполняться немного быстрее. К концу этого урока вы освоите следующие основные концепции:
Для улучшения производительности за счет уменьшения издержек на вызов функции вы можете заставить компилятор C++ встроить в программу код функции, подобно тому, как это делается при замещении макрокоманд.
Используя встроенные (inline) функции, ваши программы остаются удобными для чтения (читающий программу видит вызов функции), но вы избегаете издержек на вызов функции, которые вызваны помещением параметров в стек и их последующим извлечением из стека, а также переходом к телу функции и последующим возвратом из нее.
В зависимости от требований, предъявляемых к вашей программе, иногда вам потребуется использовать язык ассемблера для решения определенной задачи.
Для упрощения применения программирования на языке ассемблера C++ позволяет определить функции на встроенном языке ассемблера внутри ваших программ на C++.
ВСТРОЕННЫЕ ФУНКЦИИ И КЛАССЫ
Как вы уже знаете, при определении класса вы определяете функции этого класса внутри или вне класса. Например, класс employee определяет свои функции внутри самого класса:
class employee
{
public:
employee(char *name, char *position, float salary)
{
strcpy(employee::name, name);
strcpy(employee::position, position);
employee::salary = salary;
}
void show_employee(void)
{
cout "Имя: " name endl;
cout "Должность: " position endl;
cout "Оклад: $" salary endl;
}
private:
char name [64];
char position[64];
float salary;
};
Размещая подобным образом функции внутри класса, вы тем самым объявляете их встроенными {inline). Если вы создаете встроенные функции класса этим способом, C++ дублирует функцию для каждого создаваемого объекта этого класса, помещая встроенный код при каждой ссылке на метод (функцию) класса. Преимущество такого встроенного кода состоит в увеличении производительности. Недостатком является очень быстрое увеличение объема самого определения класса. Кроме того, включение кода функции в определение класса может существенно запугать класс, делая его элементы трудными для восприятия.
Для улучшения читаемости определений ваших классов вы можете вынести функции из определения класса, как вы обычно и делаете, и разместить ключевое слово inline перед определением функции. Например, следующее определение заставляет компилятор использовать встроенные операторы для функции show_employee:
inline void employee::show_employee(void)
{
cout "Имя: " name endl;
cout "Должность: " position endl;
cout "Оклад: $" salary endl;
}
Второй пример
Если ваша программа передает указатели на параметры, параметры могут быгь любого типа, например int, float или char. Функция, которая использует указатели, объявляет переменные соответствующего типа, предваряя имя каждой переменной звездочкой, подтверждающей, что такая переменная является указателем. Следующая программа SWAPVALS.CPP передает адреса двух параметров типа float в функцию swap_values. Функция в свою очередь использует указатели на каждый параметр, чтобы обменять значения параметров:
#include iostream.h
void swap_values(float *a, float *b)
{
float temp;
temp = *a;
*a = *b;
*b = temp;
}
void main(void)
{
float big = 10000.0;
float small = 0.00001;
swap_values(big, small);
cout "Big содержит " big endl;
cout "Small содержит " small endl;
}
Как видите, программа передает параметры в функцию swap_values по адресу. Внутри функции программа использует указатели на ячейки памяти параметров. Давайте более внимательно посмотрим на действия внутри функции swap_values. Как видите, функция объявляет а и b как указатели на значения типа float:
void swap_values(float *a, float *b)
Однако функция объявляет переменную temp просто как float, а не как указатель на float. float temp;
Рассмотрим следующий оператор:
temp = *а;
Этот оператор побуждает C++ присвоить переменной temp значение указываемое переменной а (т. е. значение переменной big, равное 10000.0). Поскольку temp имеет тип float, присваивание корректно. Переменная-указатель представляет собой переменную, которая хранит адрес. Следующий оператор объявляет temp как указатель на ячейку памяти, содержащую значение типа float.
float *temp;
В данном случае temp может хранить адрес значения с плавающей точкой но не само значение.
Если вы удалите оператор разыменования (*), стоящий перед переменной а внутри присваивания, то оператор будет пытаться присвоить значение, хранимое в а (которое является адресом), переменной temp. Поскольку temp может содержать значение с плавающей точкой, но не адрес значения с плавающей точкой, возникнет ошибка.
Не беспокойтесь, если вы не можете свободно обращаться с указателями, вы будете изучать их более подробно в части 3. На настоящий момент, однако, просто поймите, что, если хотите изменить в ваших функциях значения параметров, вы должны использовать указатели.
Использование ассемблерных листингов для лучшего понимания работы компилятора
Лучшим способом понять, как компилятор C++ трактует указатели, является исследование ассемблерного вывода компилятора. Большинство компиляторов C++ обеспечивают ключ командной строки, который вы можете использовать, чтобы указать компилятору выводить ассемблерный листинг. Читая ассемблерный листинг, вы можете лучше понять, как компилятор использует стек, когда передает параметры в функцию.
Вы только что узнали, что, используя указатель, ваша функция может сканировать строку символов, пока не будет обнаружен символ NULL. Следующая программа PTR_LEN.CPP использует указатель на строку в функции string_length для определения количества символов в строке:
#include iostream.h
int string_length(char *string)
{
int length = 0;
while (*string != '\0')
{
length++;
string++;
}
return(length);
}
void main(void)
{
char title[] = "Учимся программировать на языке C++";
cout title " содержит " string_length(title) " символов";
}
Как видите, функция string_length сканирует символы строки до тех пор, пока не встретит символ NULL.
Увеличение указателя на символьную строку
Когда программа передает массив в функцию, C++ передает адрес памяти первого элемента этого массива. Используя переменную-указатель, функция может перемещаться по содержимому массива, просто увеличивая значение указателя. Например, предположим, что программа передает в функцию символьную строку "Привет". Внутри функции переменная-указатель сначала указывает на участок памяти, который содержит букву 'П'. Когда функция увеличивает указатель, то он далее указывает на участок памяти, который содержит букву 'р'. По мере увеличения функцией значения указателя, он поочередно указывает на каждую букву в строке и наконец указывает на символ NULL.
При создании ваших собственных типов данных с помощью классов наиболее общей операцией будет проверка, являются ли два объекта одинаковыми. Используя перегрузку, ваши программы могут перегрузить операторы равенства (==), неравенства (!=) или другие операторы сравнения. Следующая программа COMP_STR.CPP добавляет новый оператор в класс string, который проверяет, равны ли два объекта string. Используя перегрузку операторов, ваши программы могут проверять, содержат ли строковые объекты одинаковые строки, как показано ниже:
if (some_string == another_string)
Ниже приведена реализация программы COMP_STR.CPP:
#include iostream.h
#include string.h
class string
{
public:
string(char *); // конструктор
char * operator +(char *);
char * operator -(char);
int operator ==(string);
void show_string(void);
private:
char data[256];
};
string::string(char *str)
{
strcpy(data, str);
}
char * string::operator +(char *str)
{
return(strcat(data, str));
}
char * string::operator -(char letter)
{
char temp[256];
int i, j;
for (i = 0, j = 0; data[i]; i++) if (data[i] 1= letter) temp[j++] = data[i];
temp[j] = NULL;
return(strcpy(data, temp));
}
int string::operator ==(string str)
{
int i;
for (i = 0; data[i] == str.data[i]; i++)
if ((data[i] == NULL) (str.data[i] == NULL)) return(1); // Равно
return (0); //He равно
}
void string::show_string(void)
{
cout data endl;
}
void main(void)
{
string title( "Учимся программировать на C++");
string lesson("Перегрузка операторов");
string str( "Учимся программировать на C++");
if (title == lesson) cout "title и lesson равны" endl;
if (str == lesson) cout "str и lesson равны" endl;
if (title == str) cout "title и str равны" endl;
}
Как видите, перегружая операторы подобным образом, вы упрощаете понимание ваших программ.
Следующая программа PEDIGREE.CPP создает класс dog, который содержит несколько полей данных и функцию show_breed. Программа определяет функцию класса вне определения самого класса. Затем программа создает два объекта типа dog и выводит информацию о каждой собаке:
#include iostream.h
#include string.h
class dogs
{
public:
char breed[64];
int average_weight;
int average_height;
void show_dog(void) ;
};
void dogs::show_breed(void)
{
cout "Порода: " breed endl;
cout "Средний вес: " average_weight endl;
cout "Средняя высота: " average_height endl;
}
void main(void)
{
dogs happy, matt;
strcpy(happy.breed, "Долматин") ;
happy.average_weight = 58;
happy.average_height = 24;
strcpy(matt.breed, "Колли");
matt.average_weight =22;
matt.average_height = 15;
happy.show_breed() ;
matt.show_breed();
}
Предположим, например, что вы используете следующий базовый класс book внутри существующей программы:
class book
{
public:
book (char *, char *, int);
void show_book(void);
private:
char title[64];
char author[б 4];
int pages;
};
Далее предположим, что программе требуется создать класс library_card, который будет добавлять следующие элементы данных в класс book:
char catalog[64];
int checked_out; // 1, если проверена, иначе О
Ваша программа может использовать наследование, чтобы породить класс library _card из класса book, как показано ниже:
class library_card : public book
{
public:
library_card(char *, char *, int, char *, int);
void show_card(void);
private:
char catalog[64] ;
int checked_out;
};
Следующая программа BOOKCARD.CPP порождает класс library_card из клacca book:
#include iostream.h
#include string.h
class book
{
public:
book(char *, char *, int);
void show_book(void);
private:
char title [64];
char author[64];
int pages;
};
book::book(char •title, char *author, int pages)
{
strcpy(book::title, title);
strcpy(book::author, author);
book::pages = pages;
}
void book::show_book(void)
{
cout "Название: " title endl;
cout "Автор: " author endl;
cout "Страниц: " pages endl;
}
class library_card : public book
{
public:
library_card(char *, char *, int, char *, int);
void show_card(void) ;
private:
char catalog[64];
int checked_out;
};
library_card::library_card(char *title, char *author, int pages, char *catalog, int checked_out) : book(title, author, pages)
Следующая программа ALLOCARR.CPP выделяет память для хранения массива из 1000 целочисленных значений. Затем она заносит в массив значения от 1 до 1000, выводя их на экран. Потом программа освобождает эту память и распределяет память для массива из 2000 значений с плавающей точкой, занося в массив значения от 1.0 до 2000.0:
#include iostreain.h
void main(void)
{
int *int_array = new int[1000];
float *float_array;
int i;
if (int_array 1= NULL)
{
for (i = 0; i 1000; i++) int_array[i] = i + 1;
for (i = 0; i 1000; i++) cout int_array[i] ' ';
delete int_array;
}
float_array = new float[2000];
if (float_array != NULL)
{
for (i = 0; i 2000; i++) float_array[i] = (i + 1) • 1.0;
for (i = 0; i 2000; i++) cout float_array[i] ' ' ;
delete float_array;
}
}
Как правило, ваши программы должны освобождать память с помощью оператора delete по мере того, как память становится программам не нужна.
ВЫПОЛНЕНИЕ ЦИКЛА, ПОКА argv НЕ СОДЕРЖИТ NULL
Как вы уже знаете, программы C++ используют символ NULL для завершения символьной строки. Подобным способом C++ использует символ NULL, чтобы отметить последний элемент массива argv. Следующая программа ARGVNULL.CPP изменяет оператор for предыдущей программы, чтобы выполнять цикл по элементам argv, пока текущий элемент argv не будет равен NULL:
#include iostream.h
void main(int argc, char *argv[])
{
int i;
for (i = 0; argv[i] != NULL; i++) cout "argv[" i "] содержит " argv[i] endl;
}
ВЫПОЛНЕНИЕ ОПЕРАЦИЙ ЧТЕНИЯ И ЗАПИСИ
Все программы, представленные в данном уроке, выполняли файловые операции над символьными строками. По мере усложнения ваших программ, возможно, вам понадобится читать и писать массивы и структуры. Для этого ваши программы могут использовать функции read и write. При использовании функций read и write вы должны указать буфер данных, в который данные будут читаться или из которого они будут записываться, а также длину буфера в байтах, как показано ниже:
input_file.read(buffer, sizeof(buffer)) ;
output_file.write(buffer, sizeof(buffer));
Например, следующая программа STRU_OUT.CPP использует функцию write для вывода содержимого структуры в файл EMPLOYEE.DAT:
#include iostream.h
#include fstream.h
void main(void)
{
struct employee
{
char name[64];
int age;
float salary;
} worker = { "Джон Дой", 33, 25000.0 };
ofstream emp_file("EMPLOYEE.DAT") ;
emp_file.write((char *) worker, sizeof(employee));
}
Функция write обычно получает указатель на символьную строку. Символы (char *) представляют собой оператор приведения типов, который информирует компилятор, что вы передаете указатель на другой тип. Подобным образом следующая программа STRU_IN.CPP использует метод read для чтения из файла информации о служащем:
#include iostream.h
#include fstream.h
void main(void)
{
struct employee
{
char name [6 4] ;
int age;
float salary;
} worker = { "Джон Дой", 33, 25000.0 };
ifstream emp_file("EMPLOYEE.DAT");
emp_file.read((char *) worker, sizeof(employee));
cout worker.name endl;
cout worker.age endl;
cout worker.salary endl;
}
ВЫПОЛНЕНИЕ ОПЕРАТОРОВ ПО КРАЙНЕЙ МЕРЕ ОДИН РАЗ
Как вы уже знаете, цикл C++ while позволяет вашим программам повторять набор операторов, пока данное условие удовлетворяется. Когда программа встречает оператор while, она сначала оценивает заданное условие. Если условие истинно, программа входит в цикл. Если условие ложно, операторы цикла while никогда не выполняются. В зависимости от назначения ваших программ, возможны ситуации, когда некоторый набор операторов должен выполняться по крайней мере один раз, а затем выполнение, основываясь на некотором условии, может повторяться. В подобном случае ваши программы могут использовать цикл do while:
do
{
операторы;
}
while (условие_истинно);
Если программа встречает цикл do while, она входит в цикл и запускает выполнение операторов, содержащихся в цикле. Затем программа оценивает заданное условие. Если условие истинно, программа возвращается к началу цикла:
do ----------------------------------------
{ |
операторы; |
}|
while (условие_истинно); ----------
Если условие ложно, программа не повторяет инструкции цикла, продолжая вместо этого выполнение с первого оператора, следующего за циклом. Обычно цикл do while используется для отображения пунктов меню и затем обработки выбора пользователя. Вам требуется, чтобы программа отобразила меню по крайней мере один раз. Если пользователь выбирает какой-либо пункт меню, кроме Quit, программа выполнит пункт, а затем отобразит меню снова (повторяя оператор цикла). Если пользователь выбирает Quit, цикл завершится и программа продолжит свое выполнение с первого оператора после цикла.
Повторение операторов, если условие истинно
В зависимости от назначения программы, возможно, потребуется выполнить набор операторов, по крайней мере, один раз, и повторить операторы, если заданное условие истинно. В таких случаях ваши программы используют оператор C++ do while:
do {
оператор;
} while (условие);
Когда программа встречает оператор do while, она сразу же выполняет операторы, содержащиеся в цикле. Затем программа исследует условие цикла. Если условие истинно, программа повторяет операторы цикла и процесс продолжается. Если условие цикла становится ложным, программа продолжает свое выполнение с первого оператора, следующего за оператором do while.
Выполнение простых операций
Из урока 4 вы узнали, как объявлять и использовать переменные в своих программах. По мере усложнения программ вы будете выполнять арифметические операции, такие как сложение, вычитание, умножение и деление, над значениями, содержащимися в переменных. Данный урок описывает, как использовать арифметические операторы C++ для выполнения этих операций. К тому времени, когда вы закончите изучение данного урока, вы освоите следующие основные концепции:
Для выполнения математических операций используйте в своих программах арифметические операторы C++.
Чтобы гарантировать последовательность операций, C++ назначает приоритет каждому оператору.
Используя круглые скобки в арифметических выражениях, вы можете управлять порядком, в котором C++ выполняет операции.
Многие программы на C++ прибавляют или вычитают единицу, используя операции увеличения (++) или уменьшения (--).
После того как вы научитесь распознавать разные арифметические операторы C++, вы поймете, что выполнять математические операции очень легко!
ВЫВОД И ВВОД ОДНОГО СИМВОЛА ЗА ОДИН РАЗ
В зависимости от назначения вашей программы вам, возможно, потребуется выводить символы на дисплей или читать с клавиатуры по одному символу за один раз. Для вывода одного символа за один раз ваши программы могут использовать функцию cout.put. Следующая программа COUTPUT.CPP использует эту функцию для вывода на экран сообщения Учимся программировать на языке C++! по одному символу за раз:
#include iostream.h
void main(void)
{
char string[] = "Учимся программировать на языке C++!";
int i;
for (i = 0; string[i]; i++) cout.put(string[i]) ;
}
Библиотека этапа выполнения предоставляет функцию с именем toupper, которая возвращает заглавный эквивалент строчной буквы. Следующая программа COUTUPPR.CPP использует функцию toupper для преобразования символа в верхний регистр, а затем выводит эту букву с помощью cout.put.
#include iostream.h
#include ctype.h // прототип toupper
void main(void)
{
char string[] = "C++ language";
int i;
for (i = 0; string[i]; i++) cout.put(toupper(string[i]));
cout endl "Результирующая строка: " string endl;
}
Если вы откомпилируете и запустите эту программу, на экране дисплея появится следующий вывод*:
С:\ COUTUPPR ENTER
C++ LANGUAGE
Результирующая строка: C++ language
* К сожалению, функция toupper применима только к английским буквам. Прим. перев.
ВЫВОД НА СТАНДАРТНОЕ УСТРОЙСТВО ОШИБОК
Как вы уже знаете, используя cout, вы можете перенаправить вывод программы на устройство или файл с помощью операторов переназначения вывода операционной системы. Однако, если ваши программы сталкиваются с ошибкой, вы, вероятно, не захотите, чтобы сообщение об ошибке было перенаправлено с экрана. Перенаправление сообщений об ошибках в файл может скрыть от пользователя факт появления ошибки.
Если вашей программе нужно вывести сообщение об ошибке, вы должны использовать выходной поток cerr. C++ связывает cerr со стандартным устройством ошибок операционной системы. Следующая программа CERR.CPP использует выходной поток cerr для вывода на экран сообщения "Это сообщение появляется всегда ":
#include iostream.h
void main(void)
{
cerr "Это сообщение появляется всегда";
}
Откомпилируйте и запустите эту программу. Далее попытайтесь перенаправить вывод программы в файл, используя оператор переназначения вывода:
С:\ CERR FILENAME.EXT ENTER
Так как операционная система не позволит вашим программам перенаправить вывод, записываемый на стандартное устройство ошибок, сообщение появится на вашем экране.
ВЫВОД НЕСКОЛЬКИХ ЗНАЧЕНИЙ ОДНОВРЕМЕННО
Как вы уже знаете, двойной знак "меньше" является операцией вставки (эта операция вставляет символы в выходной поток для отображения). С помощью cout вы можете использовать несколько операций вставки в пределах одного оператора. Например, следующая программа 1001ТОО.СРР использует эту операцию четыре раза для отображения числа 1001 на вашем экране:
#include iostream.h
void main(void)
(
cout 1 0 0 1;
}
Когда вы откомпилируете и запустите эту программу, на вашем экране появится следующее:
С:\ 1001TOO ENTER
/b>
Каждый раз, когда в C++ встречается операция вставки, число или символы просто добавляются к тем, что находятся в настоящее время в выходном потоке. Следующая программа SHOW1001.CPP с помощью cout выводит символьную строку и число:
#include iostream.h
void main(void)
{
cout "Мое любимое число равно " 1001;
}
Обратите внимание, что пробел, следующий за словом равно (внутри кавычек), служит для отделения числа 1001 от этого слова. Без пробела число сливается со следующим словом (равно 1001). Подобным образом следующая программа 1001MID.CPP отображает число 1001 в середине символьной строки:
#include iostream.h
void main(void)
{
cout "Число " 1001 " мне очень нравится";
}
Как и ранее, обратите внимание на расстановку пробелов до и после числа 1001.
Наконец, следующая программа MIXMATCH.CPP комбинирует строки, символы, целые числа и числа с плавающей точкой внутри одного и того же выходного потока:
#include iostream.h
void main(void)
{
cout "B " 20 " лет мой оклад был " 493.34 endl;
}
Когда вы откомпилируете и запустите эту программу, на вашем экране появится следующий вывод:
С:\ MIXMATCH ENTER
В 20 лет мой оклад был 493.34
Вывод сообщений на экран
Все программы на C++, созданные вами в уроках 1 и 2, использовали выходной поток cout для вывода сообщений на экран. В этом уроке вы будете использовать cout для вывода символов, целых чисел, например 1001, и чисел с плавающей точкой, например 0.12345. К концу данного урока вы освоите следующие основные концепции:
Для вывода символов и чисел на экран вы можете использовать выходной поток cout.
В C++ можно использовать с cout специальные символы для вывода табуляции или новой строки и даже для воспроизведения звука на вашем компьютере.
В C++ можно легко отображать числа в десятичном, восьмеричном (по основанию 8) или шестнадцатеричном (по основанию 16) формате.
Используя в командной строке операционной системы операторы переназначения, вы можете перенаправить выходные сообщения своей программы, посылаемые в cout, с экрана в файл или на принтер.
Используя выходной поток cerr, ваши программы могут посылать сообщения на стандартное устройство ошибок, избавляя пользователей от необходимости переназначения сообщений.
Вы можете форматировать вывод вашей программы, используя модификатор setw внутри выходного потока.
Почти все создаваемые вами программы на C++ используют cout для вывода сообщений на экран. Из этого урока вы узнаете, как лучше использовать сом/.
ВЫВОД В ФАЙЛОВЫЙ ПОТОК
Из урока 33 вы узнали, что cout представляет собой объект типа ostream (выходной поток). Используя класс ostream, ваши программы могут выполнять вывод в cout с использованием оператора вставки или различных методов класса, например cout.put. Заголовочный файл iostream.h определяет выходной поток cout. Аналогично, заголовочный файл fstream.h определяет класс выходного файлового потока с именем ofstream. Используя объекты класса ofstream, ваши программы могут выполнять вывод в файл. Для начала вы должны объявить объект типа ofstream, указав имя требуемого выходного файла как символьную строку, что показано ниже:
ofstream file_object("FILENAME.EXT");
Если вы указываете имя файла при объявлении объекта типа ofstream, C++ создаст новый файл на вашем диске, используя указанное имя, или перезапишет файл с таким же именем, если он уже существует на вашем диске Следующая программа OUT_FILE.CPP создает объект типа ofstream и затем использует оператор вставки для вывода нескольких строк текста в файл BOOKINFO.DAT:
#include fstream.h
void main(void)
{
ofstream book_file("BOOKINFO.DAT");
book_file "Учимся программировать на языке C++, " "Вторая редакция" endl;
book_file "Jamsa Press" endl;
book_file "22.95" endl;
}
В данном случае программа открывает файл BOOKINFO.DAT и затем записывает три строки в файл, используя оператор вставки. Откомпилируйте и запустите эту программу. Если вы работаете в среде MS-DOS, можете использовать команду TYPE для вывода содержимого этого файла на экран:
С:\ TYPE BOOKINFO.DAT ENTER
Учимся программировать на языке C++, Вторая редакция
Jamsa Press
$22.95
Как видите, в C++ достаточно просто выполнить операцию вывода в файл.
ВЫВОД ВОСЬМЕРИЧНЫХ И ШЕСТНАДЦАТЕРИЧНЫХ ЗНАЧЕНИЙ
Программы, представленные в этом уроке до сих пор, выводили числа в десятичном виде. В зависимости от назначения ваших программ вам, возможно, потребуется выводить числа в восьмеричном или шестнадцатеричном виде. Для этого можно разместить модификаторы dec, oct и hex внутри выходного потока. Следующая программа ОСТНЕХ.СРР использует эти модификаторы для вывода значений в десятичном, восьмеричном и шестнадцатеричном виде:
#include iostream.h
void main(void)
{
cout "Восьмеричный: " oct 10 ' ' 20 endl;
cout "Шестнадцатеричный: " hex 10 ' ' 20 endl;
cout "Десятичный: " dec 10 ' ' 20 endl;
}
Когда вы откомпилируете и запустите эту программу, на экране появится следующий результат:
С:\ OCTEX ENTER
Восьмеричный: 12 24
Шестнадцатеричный: а 14
Десятичный: 10 20
Примечание: Когда вы используете один из модификаторов для выбора восьмеричного, шестнадцатеричного или десятичного вывода, ваш выбор будет оставаться в силе до тех пор, пока программа не закончится или пока вы не используете другой модификатор.
ВЗГЛЯД НА ЦИКЛ while
Как вы только что узнали, цикл C++ for позволяет вашим программам повторять один или несколько операторов определенное количество раз. Однако в некоторых случаях программе необходимо повторять операторы, пока удовлетворяется (истинно) некоторое условие. Например, в следующих уроках вы узнаете, как читать содержимое файла. Такие программы могли бы повторять цикл, пока не встретится конец файла. В ситуациях, когда программам необходимо выполнять цикл, пока удовлетворяется некоторое условие (но не обязательно определенное количество раз), ваши программы могут использовать оператор C++ while. Общий формат оператора while выглядит так:
while (условие_верно)
оператор;
Если ваша программа встречает оператор while, она проверяет заданное условие. Если условие истинно, программа выполняет операторы цикла while. После выполнения последнего оператора в цикле, цикл while опять проверяет условие. Если условие все еще истинно, повторяются операторы цикла и повторяется данный процесс. Когда условие, наконец, становится ложным, цикл завершается и программа продолжает свое выполнение с первого оператора, следующего за циклом. Следующая программа GET_YN.CPP просит вас ввести Д для да или Н для нет. Затем программа использует цикл while для чтения символов с клавиатуры, пока пользователь не введет Д или Н. Если пользователь вводит значение, отличное от Д или Н, программа сигналит встроенным динамиком, записывая символ сигнала '\а' в выходной поток cout:
#include iostream.h
void main(void)
{
int done = 0; // Устанавливается в состояние „истина", если введены Д или Н char letter;
while (! done)
{
cout "\nВведите Д или Н" " и нажмите Enter для продолжения: ";
cin letter;
if ((letter == 'Д') II (letter == 'д'))
done = 1;
else if ((letter == 'Н') II (letter == 'н'))
done = 1;
else cout '\а'; // Играть сигнал динамика для неверного символа
}
cout "Вы ввели букву " letter endl;
}
Как видите, цикл while тоже поддерживает несколько операторов, сгруппированных внутри левой и правой фигурных скобок. В данном случае программа использует переменную done для управления циклом. Пока программа не завершится (т. е. пока пользователь не введет Д или Н), цикл продолжает выполняться. Когда пользователь вводит Д или Я, программа устанавливает переменную done в значение истина и цикл завершается. Как только ваши программы начнут работать с файлами, вы регулярно будете использовать цикл while.
Повторение цикла до выполнения заданного условия
По мере усложнения ваших программ им, возможно, понадобится выполнять группы связанных операторов, пока не реализуется заданное условие. Например, программа может вычислять суммы платежей для служащих компании. В этом случае цикл будет выполняться до тех пор, пока не обработаны данные для последнего служащего. Для повторения операторов до выполнения заданного условия программы как правило, будут использовать оператор while:
while (условие)
оператор;
Сталкиваясь с оператором while, программа будет оценивать условие цикла. Если условие истинно, ваша программа выполняет операторы цикла while. После выполнения последнего оператора цикла программа снова проводит проверку условия. Если условие истинно, программа повторит этот процесс, выполнит операторы, а затем повторит проверку условия. Если условие оценивается как ложь, программа продолжит свое выполнение с первого оператора, который следует за оператором while.
ВЗГЛЯД НА ОПЕРАТОРЫ ПРОГРАММЫ
В уроке 1 вы создали на C++ программу FIRST.CPP, которая содержала следующие операторы:
#include iostream.h
void main(void)
{
cout "Учимся программировать на языке С++!";
}
В данном случае программа содержит три оператора. Фигурные скобки (называемые группирующими символами) группируют связанные операторы:
#include iostream.h
void main (void)
{
cout "Учимся программировать "на языке С++!";
}
В следующем разделе каждый из операторов программы описывается более подробно.
ЗАКРЫТИЕ ФАЙЛА, ЕСЛИ ОН БОЛЬШЕ НЕ НУЖЕН
При завершении вашей программы операционная система закроет открытые ею файлы. Однако, как правило, если вашей программе файл больше не нужен, она должна его закрыть. Для закрытия файла ваша программа должна использовать функцию close, как показано ниже:
input_file.close ();
Когда вы закрываете файл, все данные, которые ваша программа писала в этот файл, сбрасываются на диск, и обновляется запись каталога для этого файла.
ЗАМЕНА ВЫРАЖЕНИЙ МАКРОКОМАНДАМИ
Если ваши программы выполняют реальные вычисления, то в общем случае ваш код будет содержать сложные выражения типа:
result = (х*у-3) * (х*у-3) * (х*у-3);
В данном случае программа вычисляет куб выражения (х*у-3). Чтобы улучшить читаемость вашей программы и уменьшить вероятность внесения ошибок из-за опечаток, создайте макрокоманду с именем CUBE, которую ваша программа может использовать следующим образом:
result = CUBE(x*y-3);
И опять общепринятым среди программистов считается использование больших букв для имен макрокоманд, чтобы отличить их от функций.
Для создания макрокоманды вы должны использовать директиву препроцессора #define. Например, следующий оператор создает макрокоманду CUBE:
#define CUBE(x) ((х)*(х)*(х))
Как видите, программа определяет макрокоманду CUBE для умножения параметра х на самого себя дважды. Следующая программа SHOWCUBE.CPP использует макрокоманду CUBE для вывода куба значений от 1 до 10:
#include iostream.h
#define CUBE(x) ((x)* (x)* (x))
void main (void)
{
for (int i = 1; i = 10; i++) cout "Для " i " куб равен " CUBE(i) endl;
}
При компиляции этой программы препроцессор C++ заменит каждый экземпляр макрокоманды CUBE соответствующим определением. Другими словами, замена макрокоманды препроцессором приведет к следующему коду:
#include iostream.h
#define CUBE(x) ((х)*(х)*(х))
void main(void)
{
for (int i = 1; i = 10; i++) cout "Для " i " куб равен " ((i) * (i) * (i)) endl;
}
Обратите внимание, что предыдущая макрокоманда поместила параметр х внутрь круглых скобок, использовав запись ((х)*(х)*(х)) вместо (х*х*х). При создании макрокоманд вы должны помещать параметры в круглые скобки, как показано выше, тогда можете быть уверены, что C++ трактует ваши выражения именно так, как вы хотите. Как вы помните из урока 5, C++ использует старшинство операций для определения порядка выполнения арифметических операций. Предположим, например, что программа использует макрокоманду CUBE с выражением 3+5-2, как показано ниже:
result = CUBE(3+5-2);
Если макрокоманда заключает свой параметр в круглые скобки, то препроцессор сгенерирует следующий оператор:
result = ((3+5-2) * (3+5-2) * (3+5-2));
Однако, если в определении макрокоманды опустить круглые скобки, препроцессор сгенерирует следующий оператор:
result = (3+5-2*3+5-2*3+5-2);
Если вы вычислите оба выражения, то обнаружите, что их результаты отличаются. Заключая аргументы макрокоманды в круглые скобки, вы избавитесь от подобных ошибок.
Значения параметров по умолчанию
Как вы уже знаете, C++ позволяет вам с помощью параметров передавать информацию в функции. Из урока 13 вы выяснили, что C++ также обеспечивает перегрузку функций, предусматривая определения, содержащие разное количество параметров или даже параметры разных типов. Кроме этого, в C++ при вызове функций можно опускать параметры. В таких случаях для опущенных параметров будут использоваться значения по умолчанию. Этот урок описывает как устанавливать значения по умолчанию для параметров функций. К концу данного урока вы освоите следующие основные концепции:
• C++ позволяет программам указывать для параметров значения по умолчанию.
• Значения по умолчанию для параметров указываются в заголовке функции при ее определении.
• Если вызов функции опускает значения одного или нескольких параметров, C++ будет использовать значения по умолчанию.
• Если вызов функции опускает значение определенного параметра, то должны быть опущены и значения всех последующих параметров.
Обеспечение значений по умолчанию для параметров упрощает возможность повторного использования функций (их использования несколькими программами).
Знакомство с функциями
По мере увеличения размера и сложности ваших программ вам следует разделить их на небольшие легко управляемые части, называемые функциями. Каждая функция в вашей программе должна выполнять определенную задачу. Например, если вы пишете программу платежей, можете создать одну функцию, определяющую количество часов, отработанных служащим, вторую функцию, определяющую сверхурочную оплату, третью функцию, выводящую на печать и т. д. Если программе необходимо выполнить определенную задачу, то она вызывает соответствующую функцию, обеспечивая эту функцию информацией, которая ей понадобится в процессе обработки. Из этого урока вы узнаете, как создавать и использовать функции в ваших программах на C++. К концу данного урока вы освоите следующие основные концепции:
• Функции группируют связанные операторы для выполнения определенной задачи.
• Ваша программа вызывает функцию, обращаясь к ее имени, за которым следуют круглые скобки, например bеер ().
• После завершения обработки большинство функций возвращают значение определенного типа, например int или float, которое программа может проверить или присвоить переменной.
• Ваши программы передают параметры (информацию) функциям, например имя, возраст или оклад служащего, заключая параметры в круглые скобки, которые следуют за именем функции.
• C++ использует прототипы функций для определения типа возвращаемого функцией значения, а также количества и типов параметров, передаваемых функции.
По мере увеличения ваших программ использование функций становится их неотъемлемой необходимостью. Однако, как вы увидите, создавать и использовать функции в C++ очень легко.
Знакомство с классами C++
Класс представляет собой главное инструментальное средство C++ для объектно-ориентированного программирования. Как вы узнаете из данного урока, класс очень похож на структуру, в которой сгруппированы элементы, соответствующие данным о некотором объекте, и оперирующие этими данными функции (называемые методами). Вы узнаете, что объект представляет собой некоторую сущность, например телефон. Класс C++ позволяет вашим программам определять все атрибуты объекта. В случае, когда объектом является телефон, класс может содержать такие элементы данных, как номер и тип телефона (кнопочный или дисковый) и функции, работающие с телефоном, например dial, answer, и hang_up. Группируя данные об объекте и кодируя их в одной переменной, вы упрощаете процесс программирования и увеличиваете возможность повторного использования своего кода. Этот урок знакомит вас с классами C++ . К концу урока вы освоите следующие основные концепции:
Для определения класса программа должна указать имя класса, элементы данных класса и функции класса (методы).
Определение класса обеспечивает шаблон, с помощью которого ваши программы могут создать объекты типа этого класса, подобно тому, как программы создают переменные типа int, char и т. д.
Программа присваивает значения элементам данных класса, используя оператор точку.
Программа вызывает функцию-элемент класса, используя оператор точку.
ЗНАКОМСТВО С ОПЕРАТОРОМ if
Оператор C++ if позволяет вашим программам осуществлять проверку и затем на основании этой проверки выполнять операторы. Формат оператора if следующий:
if (условие_выполняется) оператор;
Обычно оператор if выполняет проверку, используя операцию сравнения C++. Если результат проверки является истиной, if выполняет оператор, который следует за ним. Следующая программа FIRST_IF.CPP использует оператор if для сравнения значения переменной test_score со значением 90. Если набранные тестовые очки больше или равны 90, программа выведет сообщение пользователю, что он получил А. В противном случае, если значение меньше 90, программа просто завершается:
#include iostream.h
void main(void)
{
int test_score = 95;
if (test_score = 90) cout "Поздравляем, вы получили А!" endl;
}
Как видите, для выполнения проверки программа использует операцию сравнения C++ "больше или равно" (=). Если результат сравнения значений является истиной, программа выполняет оператор, который следует за if, в данном случае вывод сообщения с использованием cout. Если результат сравнения не является истинным, программа не выводит сообщение. Экспериментируйте с этой программой, изменяя проверочные очки (в том числе и меньше 90), и обратите внимание на работу оператора if.