Урок 4: «Константа — величина постоянная»
Ну вот, мы начинаем пробираться к самой сути. Вы уже должны понимать, что такое переменная и как использовать условия в ваших программах. Надеюсь, что это так, иначе все остальное для вас читать бессмысленно.
Когда я рассказывал о переменных, я опустил еще один вид переменной. Эта переменная, в отличие от остальных, хранит свое значение все время выполнения программы. Она инициируется при объявлении и изменить ее нельзя в дальнейшем коде. Называется такая переменная константой.
Для чего нужны константы? Для хранения постоянной информации. Как я не хотел бы приводить математические сравнения, однако они наиболее наглядны. Вспомните физику – гравитационная постоянная, температура по Кельвину, Фаренгейту и т.п. Все это –константы. Фактически, мы объявили раз такую переменную и забыли о ее значении, подставляя ее имя в программе. вы можете спросить, а почему нельзя использовать простую переменную для хранения такой информации? А потому, что этой переменной вы можете присвоить другое значение, а константе – нет.
Давайте рассмотрим синтаксис, а потом я приведу наглядный пример.
В Си константа определялась директивой #define
#define PI 3.14 // PI будет содержать теперь 3.14
Эту директиву можно встретить и во многих нынешних программах, однако это устаревший подход. В С++ был введен новый модификатор const.
const float PI=3.14;\
Этот модификатор рекомендуется всегда использовать с ваших программах на С++.э
const float PI=3.14; int _tmain(int argc, _TCHAR* argv[]) { setlocale (0,""); //установим язык по-умолчанию (русский) int S,R=21; //площадь и радиус окружности S=PI*R*R; system ("pause"); //чтобы окно не закрылось return 0; }
Где бы мы не вызывали эту переменную, везде она будет равняться 3,14. Очень удобно, не так ли? Кстати, ради эксперимента попытайтесь присвоить PI какое-либо значение в программе. Посмотрите, как отреагирует компилятор.
Ну и в заключение по константам могу сказать, что можно в качестве константы использовать арифметическое выражение.
const PROIZV=23*12; // теперь у нас в константе число 276
Кроме того, запомните одно правило – имена констант всегда следует писать прописными буквами! Это упростит и вам жизнь, так как встречая правильно оформленную константу вы сразу поймете, что это постоянная.
Наряду с константами в программировании широко используются перечисления. По своей сути, это набор констант. Они нужны для того, чтобы ограничить переменной выбор дипазона значений. Это может быть день недели, месяц, признак по полу (муж или жен) и т.п. Особенно широко перечисления находят применения в игрописании.
Что ж, давайте теперь забудем о том, что я написал выше и рассмотрим перечисление на примере.
Перечисления дожны объявляться вне функции main. Дело в том, что это тип, определяемый программистом. А такие типы наряду со структурами и классами должны объвляться, желательно, в отдельном модуле. Но мы все это рассмотрим значительно позже. Вот, как объявляется перечисление:
enum Month {Jan, Feb, Marth,April, May, June, Jule, August, Sept, Oct, Nov, Dec};
Начинается перечисление с ключевого слова enum, затем указывается имя перечисления (это не переменная!!!) , а в скобках указывается набор значений.
Теперь мы можем использовать объявленный тип в нашей программе:
int main () { Month curMonth=June; // теперь в переменной curMonth хранится //июль }
Как вы думаете, что хранится в переменной curMonth? Если думаете, что June, то ошибаетесь. Перечисление это числовой тип и он неявно приводится к типу int. Нумерация начинается с 0. Зная это, мы можем предположить, что в curMonth лежит число 5. Иными словами, мы могли присвоить этой переменной вместо названия месяца его числовой аналог в трактовке перечисления и были бы правы.
Конечно, пример с месяцем или днем недели не очень нагляден. Однако вы должны понять, что переменную можно ограничить в диапазоне значений. Попробуйте, присвойте curMonth значение, отличное от перечисления и посмотрите, как вас обзовет компилятор J.
А вот в программировании, например под Windows, мы будем часто сталкиваться с перечислениями и константами. Вот там вы полностью поймете все удобство их иcпользования.
Теперь давайте вернемся к нашему примеру и посмотрим еще, что можно изменить. Месяцы мы нумеруем с единицы, а не с нуля. По нашему коду видно, сто июню присвоено значение 5, а не 6. Что ж, в перечислении можно задать собственную нумерацию.
enum Month {Jan=1, Feb, Marth,April, May, June, Jule, August, Sept, Oct, Nov, Dec};
Я явно присвоил Jan значение 1. Остальным месяцам компилятор уже сам присвоит нужные значения. Конечно, можно и в ручную все поставить, да только нет в этом смысла.
Ну и напоследок. Переменную можно объявить и при задании перечисления:
enum Month {Jan=1, Feb, Marth,April, May, June, Jule, August, Sept, Oct, Nov, Dec} thisMonth;
Затем этой переменной уже можно пользоваться в программе. Объявлять там их можно много. Вот только лично я не люблю такой способ, считая его несколько запутанным. В конце-концов, мы программируем не на С, а на С++.
Приведение типов
Вот здесь читайте внимательно. Дело в том, что С++ славится своими арифметическими погрешностями в расчетах. Нет, он считает все правильно, вот только результат вычисления сильно зависит от типа переменной. Программист, решивший присвоить частному от деления тип int , часто может не получить желаемый результат. Дело в том, что компилятор языка проводит неявные приведения типов.
Вот пример. Нам нужно расчитать зарплату сотрудника. Мы знаем ставку часа. Затем умножаем эту величину на количество отработанных часов и получаем нужный результат. Здесь все просто. Но представьте себе директора, который нанимает сотрудника и не знает, сколько ему нужно платить. Тогда он берет величину зарплаты по региону и делит ее на количество часов.
int zarp, hour, vel; vel=22320; // зарплата в городе равна 22320 рублям hour=22 * 8; //количество часов равно 22 рабочих дня * 8 часовой рабочий день zarp=vel / hour; // наш час cout<<"Час работника стоит =" <<zarp<<endl;
Программа нам выдаст цифру в 126 рублей. Нас это устраивает, однако несложно взять калькулятор и высчитать, что на самом деле число составляет 126, 8. И если сотрудник не обидится на эту недодачу, то вот в расчетах такие погрешности недопустимы. Что же произошло?
zarp – это целое и хранит оно только целое значение. Дробная часть будет отброшена. Иными словами, Нужно было использовать тип double, который хранил бы дробь. А вот здесь ситуация несколько интереснее. Компилятор временно присваивает переменным hour и vel тип double, как бы расширяя их значение. Мы об этом можем не догадываться, хотя это важно понимать. Компилятор, встречая тип большего размера, присвает его операнду с типом меньшего значение. Вот и все правило.
Однако представьте себе ситуацию, когда параноидально настроенный программист напрасно расходует память (вы же помните, что тип double больше int в 2 раза?) и старается везде присвоить именно этот тип. Да, он получает точное значение, жертвуя некоторой производительностью ( операции с дробными типами выполняются медленнее, чем с целыми, но сейчас это уже неактуально), однако искусственно себя загоняте в угол. Давайте вернемся к нашему директору, который все не знает, сколько должен платить за работу. Допустим, что скрупулезный бухгалтер дал ему величину часа в 132,12 рублей. Вы сразу же присвоите ему значение double, начнете расчет и взвоете, когда везде появятся копейки. Ну не нужно же нам работнику их выдавать!
В этом случае, если вы сделали такой ляп, можно сделать явное приведение. В С это делалось так:
(тип приведения)выражение
(int)vel; // искусственно привели тип к целому.
В С++ Страупструп ввел новое преобразование. Вот его описание:
static_cast<тип>(выражение)
или
static_cast<int>(vel);
Рекомендуется использовать именно его, однако сишный вариант широко используется. Кроме того, многие даже и не знают об этом втором варианте преобразования.
Преобразования считаются признаком дурного тона программирования. Если у вас слишком много преобразований, то, скорее всего, нужно поменять все значения в программе.
Тем не менее, при ООП преобразования используются частенько. Зацикливаться на них пока не будем, все равно с практикой вы поймете все сразу.
Итак, пойдите, отдохните. Следующий урок будет сложнее и значительно важнее. Спешу вас обрадовать – осталось несколько уроков этого фундамента и мы приступим уже к нормальному программированию.