- •Введение
- •Структура программы на языке Си
- •Директивы препроцессора
- •Константы
- •Переменные
- •Арифметические выражения
- •Операция присваивания
- •Ввод информации с клавиатуры и вывод на экран
- •Логические выражения
- •Операторы управления
- •Оператор условного перехода if
- •Оператор выбора варианта
- •Перечисляемый тип данных
- •Циклы
- •Оператор цикла while
- •Оператор цикла do-while
- •Оператор цикла for
- •Локальные и глобальные переменные
- •Переменные с индексами (массивы)
- •Примеры обработки одномерных массивов
- •Многомерные массивы
- •Массивы и указатели
- •Арифметические и логические операции с указателями
- •Обработка массивов с помощью указателей
- •Обработка массивов переменной размерности
- •Обработка матриц переменной размерности
- •Обработка текстовой информации
- •Стандартные строки языка С++
- •Пример 1. Определение длины строки.
- •Пример 2. Копирование одной строки в другую
- •Пример 3. Исключение из строки символа.
- •Пример 4. Вставка в строку символа
- •Пример 5. Проверка правильности расстановки скобок.
- •Строки типа string
- •Массивы указателей
- •Указатели на функции
- •Сводная таблица форм объявления указателей
- •Преобразование типов
- •Ссылки
- •Структуры
- •Объединения
- •Файлы
- •Чтение файла в матрицу
- •Чтение файла в структуру
- •Функции для обработки произвольных полей структур
- •Связные списки
- •Контейнерные классы
- •Стеки
- •Рекурсия
- •Вопросы для самопроверки
- •Литература
21
этой переменной. Такая ситуация рассматривается компилятором, как ошибка. Присваивать значение переменной с атрибутом можно только при ее объявлении, а отсутствие присвоения значения при объявлении тоже рассматривается как ошибка. Пример:
const double z = 0.5;
Изменить значение переменной описанной с атрибутом const можно только принудительно. См. параграф «Преобразование типов».
Арифметические выражения
С помощью арифметических выражений выполняются все основные вычисления в программах. В состав арифметического выражения могут входить константы, переменные, функции, знаки арифметических операций и круглые скобки. Правила составления выражений, при некоторых ограничениях, специфических для программирования (отсутствие альтернативных форм записи операции умножения и деления, запрещение опускать знак операции умножения, ограничения на перечень выполняемых операций и т. д.), позволяют максимально приблизить их к обычным алгебраическим формулам, используемым в математике. В выражениях используются также некоторые специфические знаки операций. Выражения вычисляются слева направо с учетом приоритета операций. Для изменения приоритета операций используются круглые скобки. Выражения могут составляться из констант, переменных разных типов и функций.
Основные арифметические операции обозначаются с помощью следующих знаков:
*умножение
/деление
% вычисление остатка при делении целых чисел. + сложение - вычитание
(операции возведения в степень в языке C++ нет).
Из этих операций более высоким приоритетом обладают операции умножения, деления и вычисление остатка, а сложение и вычитание
22
имеют меньший приоритет. Между собой операции умножения и деления так же, как и операции сложения и вычитания, имеют одинаковый приоритет. Примеры оформления выражений:
2 * x + 0.2 a / (x + y)
(a + 2) * (b - 0.5) sin(x - РI / 2) * cos(y)
Если в выражении записана функция, то ее приоритет наивысший.
Операция % позволяет вычислить остаток от деления двух целых чисел. Например, в результате выполнения операции 17 % 5 будет получено число 2.
Операция % имеет такой же приоритет, как и операции умножения и деления; эта операция не выполняется для чисел с плавающей точкой (хотя в принципе она имеет смысл, так как остаток можно вычислять не только в целых числах, но и в десятых, сотых долях и т.д.). Но этот же результат можно получить при предварительном умножении исходных чисел с плавающей точкой на соответствующую степень десятки с последующим преобразованием чисел в целые. Полученный затем остаток при выполнении операции % будет представлять остаток в десятых, сотых и т. д. в зависимости от выбранной степени десятки.
Особенностью выполнения операции деления для целых чисел является отбрасывание дробной части. Например, если 1 разделить на 2, то результат будет 0. Для получения правильного результата требуется один из операндов преобразовать к типу числа с плавающей точкой. Если 1.0 (это число с плавающей точкой) разделить на 2 (или 1 разделить на 2.0), то в результате будет 0.5. Другие способы описаны в параграфе «Преобразование типов».
Операция присваивания
Формально операция присваивания имеет вид математического равенства a = b, где "a" - имя переменной, а "b" - арифметическое выражение. Фактически операция присваивания засылает численное
23
значение результата, полученное при вычислении арифметического выражения, в ячейку памяти, выделенную для хранения переменной, имя которой записано слева от знака равенства. По этой причине действительными являются операции вида k = k + 2. Действительно, на арифметическое выражение не налагается ограничение, чтобы оно не содержало переменной, записанной слева от знака равенства. Это происходит потому, что сначала вычисляется выражение, а затем выполняется засылка результата в ячейку памяти, обозначенную именем переменной. Допустим, что k в предыдущем примере имеет значение 5, тогда сначала вычисляется 5 + 2 = 7, а затем этот результат засылается в ячейку, обозначенную именем k, т.е. k получит значение 7. В математике такие равенства не имеют смысла, поскольку они и обозначают действительные равенства, тогда как в программировании они обозначают последовательность выполнения сначала вычислений, а затем пересылки информации. Когда имя, записанное слева от знака равенства, не совпадает с именами, имеющимися в выражении справа от знака равенства, тогда оператор присваивания совпадает и по смыслу с математическим равенством.
Этот факт можно выразить и другими словами: знак равенства обозначает пересылку справа налево (но не наоборот) с одновременным выполнением необходимых для этого действий. Но за одну операцию может пересылаться только одно данное. Поэтому, если справа от знака равенства записано выражение, то оно вычисляется, чтобы преобразовать его в одно число. По этой же причине слева от знака равенства не может быть записано число или выражение, хотя такая форма записи в математике применяется.
Если тип данных для вычисленного арифметического выражения не совпадает с типом переменной, записанной слева от знака равенства, то автоматически выполняется преобразование к типу этой переменной.
В языке С++ знак равенства обозначает операцию присваивания, а не оператор присваивания, как это имеет место в других языках
24
программирования. Операция от оператора отличается тем, что операция может применяться в арифметических выражениях, а оператор нет. Благодаря этому в языке C++ возможны такие записи:
a = b = c = d = 0;
(присвоение нескольким переменным одного и того же значения). x = 2 * (a = 3 + b);
(выполнение присваивания в арифметическом выражении). Другими словами, знак равенства может означать как операцию присваивания (в последнем примере a = 3 + b), так и оператор присваивания значения вычисленного выражения
x = 2 * (a = 3 + d);.
В языке C++ используются некоторые специфические формы записи операции присваивания. К таким операциям относятся ++ увеличение на единицу (инкремент) и -- уменьшение на единицу (декремент). Фактически они обозначают соответственно прибавление к переменной 1 или вычитание из переменной 1 с соответствующим изменением переменной.
x++;
можно записать как x = x + 1;
Операция x--;
означает
x = x - 1;
Операции ++ и -- записываются либо перед именем переменной, либо после него. В первом случае сначала выполняется приращение, а затем полученное значение используется в выражении. Во втором случае приращение выполняется после использования значения переменной. Это правило применяется, когда операции записаны в арифметическом выражении. В любом случае, когда выпол-
25
нение программы достигает точки с запятой в операторе, содержащем операцию приращения (или уменьшения), эта операция оказывается выполненной, независимо от места записи знаков ++ или --. Таким образом, записи x++; и ++x; являются равноценными и приводят к одному и тому же результату. Пусть теперь имеется оператор:
z = x * y++;
Если перед выполнением этого оператора x имеет значение 4, а y равен 5, то после выполнения вычислений z получит значение 20, т.е. выражение было вычислено при начальном значении y, но после выполнения оператора y будет иметь значение 6. Но при выполнении оператора:
z = x * ++y;
сначала будет увеличено значение y, и только затем вычислено значение z, т.е. z получит значение 24.
Операции ++ и -- можно рассматривать как редуцированные формы записи операторов присваивания, но выражение
x * y++;
можно записать только с помощью двух операторов присваивания:
y = x * y; y = y + 1;
Для широко распространенных в программировании операторов вида:
n = n + b; n = n * b;
и т. д., где n является именем переменной, а b - выражением. В языке C++ может использоваться сокращенная запись оператора присваивания:
|
26 |
Оператор присваивания |
Форма записи в языке С++: |
n = n + b |
n += b |
n = n - b |
n -= b |
n = n * b |
n *= b |
n = n / b |
n /= b |
n = n + b |
n += b |
Например, оператор |
|
x = x / (k + 1); |
|
можно записать как |
|
x /= k + 1; |
|
Более наглядна была бы запись знака операции после знака равенства, но тогда запись вида
n =- b;
трактовалась бы как изменение знака b, поэтому и принята указанная форма записи. Отметим, что знаки операций при сокращенной записи оператора присваивания нельзя разделять пробелом. Они всегда записываются слитно (+=, но не + =).
Ввыражениях и в операторах присваивания могут использоваться константы и переменные разных типов. Преобразование результатов вычисления выражений к конкретному типу данных выполняется автоматически. При этом окончательный тип данного преобразуется
ктипу данного, входящего в выражение, который позволяет представить результат при наибольшем диапазоне значений. Например, результат вычисления выражения, содержащего величины типа int
и double, будет типа double.
Ввыражениях при вычислениях могут использоваться также величины типа char.
Если в операторе присваивания, в котором используются разнотипные целочисленные переменные, тип переменной, которой присваивается значение, не совпадает с окончательным типом данного для вычисленного выражения, тип вычисленного выражения преоб-