- •3.8. Упражнения 49
- •Введение
- •1. Базовые элементы
- •1.1. Комментарии
- •1.2. Функция «main»
- •1.3. Идентификаторы и пространства имен
- •1.4. Типы
- •1.5. Переменные
- •1.7. Константы
- •1.6. Преобразование типов
- •1.8. Потоковый ввод – вывод
- •1.9. Операции
- •1.9.1. Арифметические операции
- •1.9.2. Поразрядные операции
- •1.9.3. Условный оператор
- •1.9.4. Операции отношения
- •1.9.5. Логические операции
- •1.10. Стандартные математические функции
- •1.11. Упражнения
- •2. Базовые конструкции
- •2.1 Ветвление
- •2.1.1. Конструкция «if – else»
- •2.1.2. Конструкция «switch»
- •2.2. Циклы
- •2.2.1. Цикл «for»
- •2.2.2. Цикл «while»
- •2.2.3. Цикл «do – while»
- •2.2.4. Операторы циклов
- •2.2.5. Вложенность
- •2.3. Упражнения
- •2.3.1. Ветвления
- •2.3.2. Циклы
- •2.3.3. Вложенность
- •3. Указатели. Массивы. Структуры
- •3.1. Указатели
- •3.2. Массивы
- •3.2.1. Статические массивы
- •3.2.2. Динамические массивы
- •3.4. Ссылки
- •3.5. Структуры
- •3.6. Объединение
- •3.7. Переопределение типов
- •3.8. Упражнения
- •3.8.1. Статические и динамические массивы
- •3.8.2. Многомерные массивы
- •3.8.3. Строки
- •4. Функции
- •4.1. Простые функции
- •4.2. Рекурсия
- •4.3. Указатели и ссылки
- •4.3.1. Передаваемые параметры
- •4.3.2. Возвращаемые значения
- •4.3.3. Ссылки и структуры в функциях
- •4.3.4. Указатели и массивы в функциях
- •4.3.5. Указатели и ссылки на функцию
- •4.4. Шаблоны функций
- •4.5. Упражнения
- •4.5.1. Простые функции
- •4.5.2. Параметры – ссылки и параметры — указатели
- •5. Стандартные классы
- •5.1. Класс «pair»
- •5.2. Класс «complex»
- •5.3. Класс «string»
- •5.4. Контейнеры. Алгоритмы. Итераторы
- •5.5. Класс «vector»
- •5.6. Упражнения
- •5.6.1. Класс «string»
- •5.6.2. Класс «vector»
- •6. Файловый ввод – вывод
- •6.1. Операции
- •6.2. Методы
- •6.3. Флаги
- •6.4. Двоичный режим
- •6.5. Упражнения
- •Ллитература
1.6. Преобразование типов
При работе с переменными часто возникают ситуации, когда переменной одного типа необходимо присвоить значение переменной другого типа. В большинстве случаев компилятор корректно выполняет преобразование типов, и нет необходимости во вмешательстве программиста. Такие случаи называются неявным преобразованием и выполняются в соответствии с приоритетами типов.
Особым случаем при неявном преобразовании можно считать преобразование с участием типа «bool». Переменные этого типа, имеющие значение «true», преобразуются к «1», а «false» – к значению «0», при этом любое значение, отличное от «0», будет интерпретироваться как «true», а нулевое как «false». Еще одним особым случаем является преобразование с участием типа «char». При преобразовании его к любому числовому типу, переменная получит в качестве результата – ASCII – код символа, хранящегося в переменной типа «char», а при обратном преобразовании число будет интерпретироваться как ASCII – код.
При использовании макроопределений проверка соответствия типов не выполняется вовсе, по этому и рекомендуется пользоваться «const» – переменными.
Явное преобразование типов используется, в основном, при работе с пользовательскими типами данных, когда компилятор не в состоянии выполнить преобразование автоматически. При таком преобразовании используются операторы «const_cast», «static_cast», «reinterpret_cast» и «dynamic_cast». Конструкция преобразования типов языка С, где тот тип, к которому требуется преобразовать, указывался в круглых скобках перед выражением, также допустима, но не рекомендуется к применению в С++. Оператор «const_cast» позволяет отменить признак постоянства. Оператор «static_cast» используется, если преобразование поддерживается языковыми средствами напрямую. Так в случае деления целочисленных переменных результат также является целочисленным, чего и помогает избежать «static_cast». Оператор «reinterpret_cast» является более мощным по сравнению со «static_cast», но и менее безопасным, и применяется в случаях, когда формально преобразование неразрешено, но имеет определенный смысл, как при преобразовании типов указателей и ссылок. Оператор «dynamic_cast» обеспечивает динамический контроль типов при работе с классами, но применим и к обычным ссылкам и указателям.
Листинг 1.2. Использование static_cast.
#include <iostream>
using std::cout;
int main (void)
{
float z;
z = (10 - 2) / 3;
cout << z << "\n";
z = static_cast<float>(10 - 2) / 3;
cout << z << "\n";
return 0;
}
1.7. Константы
При инициализации переменных и в ряде других случаев могут использоваться константы. Целочисленные константы могут задаваться в различных системах счисления. Десятичные числа записываются цифрами обычным образом. Перед шестнадцатеричными ставится символы «0х», а восьмеричные — нулем. Дробные константы состоят из целой части, разделяющей точки, дробной части, символа «е» или «Е» и экспоненты в виде целой константы. Так запись «3.5e2» равносильна записи «350.0». Строковые константы записываются в двойных кавычках «""», а символьные — в одинарных «''». Символьными константами называются также и управляющие последовательности, специальные символы, регулирующие вывод информации на экран. В примере – это символ перевода строки «\n». Так как символы «"», «'» и «\» используются в служебных целях, то их непосредственный вывод осуществляется при помощи экранирования символом «\». Также, с помощью «\» можно выводить символы, используя их ASCII – код: «\xHH», где «HH» – это шестнадцатеричный код требуемого символа.
Таблица 1.3. Специальные символы.
Символ |
Описание |
Символ |
Описание |
\a |
Сигнал |
\'' |
Двойные кавычки |
\b |
Возврат на шаг |
\' |
Одинарные кавычки |
\n |
Перевод строки |
\\ |
Обратная косая черта |
\r |
Возврат в начало строки |
\xHH |
Символ с ASCII – кодом HH |
\t |
Табуляция |
|
|
При задании констант можно явным образом определять их тип, указывая после значения определенный символ. Для литерала «long» – это «L» или «l», для «unsigned» – это – «U» или «u», для типа «float» – «F» или «f».
В случае, если в программе не должно происходить изменения значения какой-либо переменной, ее объявляют как «const». В таком случае попытка изменить ее вызовет ошибку компиляции. В языке С для этого использовались макроопределения директивой «#define», что сохранилось и в С++, однако такой подход несет в себе потенциальные проблемы, связанные с преобразованиями типов, и затрудняет последующее сопровождение кода.
Унаследованным из языка С является особый тип констант «enum» – перечисление. Он представляет из себя список целочисленных констант. Если значения констант не заданы, то первая приравнивается к нулю, следующая – к единице и т.д.
Листинг 1.3. Перечисления.
#include <iostream>
using namespace std;
enum Esc {BEL='\a', BSP='\b', NEW='\n', RET='\r', TAB='\t' }; //спецсимволы;
enum Errors { OK, ER_FILE, ER_VALUE }; //ошибки;
int main (void)
{
cout << static_cast<char>(NEW) << endl;
return OK;
}
Важным является тот факт, что в пространство имен добавляется не только идентификатор перечисления, но и имена всех его элементов. Обычно, идентификаторы элементов перечисления состоят из символов в верхнем регистре, чтобы отличать их от других идентификаторов.
