- •1 Понятие алгоритма формы представления алгоритмов
- •2 Линейные и разветвляющиеся алгоритмы.
- •3 Циклические алгоритмы
- •4 Понятие прикладного и системного программирования
- •5 Структура программ на языке си
- •6 Арифметико-логические операции над переменными
- •Арифметические операции
- •Операции увеличения и уменьшения
- •Операции "увеличить на", "домножить на" и т.П.
- •Логические операции
- •Операции сравнения
- •Побитовые логические операции
- •7 Два вида оператора выбора Оператор if
- •8 Понятие цикла
- •1.4.6. Оператор break
- •1.4.7. Оператор for
- •1.4.8. Оператор while
- •1.4.9. Оператор do while
- •1.4.10. Оператор continue
- •1.4.11. Оператор return
- •9 Массив
- •12 Указатели
- •13 Адресная арифметика
- •14 Операции над указателями
- •15 Массивы указателей
- •16 Указатели на функции Указатели на функции
- •17 Структуры
- •18 Доступ к элементам структуры
- •19 Структуры как аргументы
- •6.2. Структуры и функции
- •20 Динамические структуры на массиве
- •21 Динамическое распределение памяти Функции динамического распределения
- •Динамическое выделение памяти для массивов
- •23 Организация доступа к файлам
- •Закрытие потока при помощи fclose
- •Чтение из потока при помощи fgetc
- •«Ловушка» eof
- •При помощи fgets
- •24 Форматированный ввод –вывод Функции форматированного ввода и вывода в си
- •Спецификатор типа
- •Спецификатор типа
- •25 Верификация тестирование отладка программ
- •Введение
- •26 Причины и последствия появления ошибок
- •27 Идея модульного программирования
- •28 Технология проектирования сверху-вниз
- •29 Итерация рекурсия
- •30 Методы сортировки
- •34 Способы защиты информации
6 Арифметико-логические операции над переменными
Арифметико-логические операции
Приведенные ниже операции упорядочены по убыванию приоритета.
I. Операции с наивысшим приоритетом
1. () вызов функции;
2. [] выбор элемента массива; 7
3. -> косвенный выбор элемента;
4. . прямой выбор элемента.
II. Унарные операции
1. ! логическое отрицание (NOT);
2. ~ побитовая инверсия;
3. – унарный минус;
4. ++ увеличение на единицу;
5. - - уменьшение на единицу;
6. & получение адреса переменной;
7. * получение значения по адресу;
8. sizeof размер операнда в байтах.
III. Мультипликативные
1. * умножение;
2. / деление;
3. % вычисление остатка от деления (для целочисленных операндов).
IV. Аддитивные
1. + бинарный плюс;
2. - бинарный минус.
При равном приоритете бинарные операции группируются слева напра-
во.
V. Сдвиги
1. >> cдвиг вправо;
2. << cдвиг влево.
VI. Сравнения
1. < меньше;
2. <= меньше или равно;
3. > больше;
4. >= больше или равно.
VII. Равенство
1. = = равно;
2. != не равно.
Результатом выражений с данными операциями является истина (ненулевое
значение) или ложь (0).
VIII. Побитовые
1. & побитовое И (AND);
2. ^ побитовое исключающее ИЛИ (XOR);
3. | побитовое ИЛИ (OR).
IX. Логические 8
1. && логическое И (AND);
2. || логическое ИЛИ (OR).
Логические операции служат для связывания выражений, включающих в
себя операции отношения.
Арифметические операции
К четырем обычным арифметическим операциям сложения +, вычитания -, умножения * и деления / в Си добавлена операция нахождения остатка от деления первого целого числа на второе, которая обозначается символом процента %. Приоритет у операции вычисления остатка % такой же, как и у деления или умножения. Отметим, что операция % перестановочна с операцией изменения знака (унарным минусом), например, в результате выполнения двух строк
x = -(5 % 3);
y = (-5) % 3;
обеим переменным x и y присваивается отрицательное значение -2.
Операции увеличения и уменьшения
В Си добавлены операции увеличения и уменьшения на единицу, которые, к примеру, очень удобно применять к счетчикам. Операция увеличения записывается с помощью двух знаков сложения ++, операция уменьшения - с помощью двух минусов --. Например, операция ++, примененная к целочисленной переменной i, увеличивает ее значение на единицу:
++i; эквивалентно i = i+1
Операции увеличения и уменьшения на единицу можно применять только к дискретным типам - целочисленным переменным различного вида и указателям. Операцию нельзя применять к вещественным переменным! Например, следующий фрагмент программы является ошибочным:
double x;
. . .
++x; // Ошибка! Операция ++ неприменима
// к вещ. переменной
Операция ++ увеличивает значение переменной на "минимальный атом". Так как для вещественных переменных такого "атомарного" значения нет, операции увеличения и уменьшения для них запрещены.
Для указателей операция ++ увеличивает значение переменной на размер одного элемента того типа, на который ссылается указатель. Для указателя "атомом" является один элемент заданного типа, поэтому размер одного элемента и является шагом изменения значения указателя. Это очень естественно, т.к. после увеличения указатель будет содержать адрес следующего элемента данного типа, а после уменьшения - адрес предыдущего элемента. Пример:
double a[100];
double *p = &(a[15]); // в p записывается адрес
// элемента массива a[15]
++p; // в p будет адрес элемента a[16]
// (адрес увеличивается на sizeof(double) == 8)
Описаны массив a вещественных чисел типа double и указатель p на элементы типа double. При описании указателя p в него заносится начальное значение, равное адресу элемента a[15] массива a. После выполнения операции увеличения ++ в переменной p будет содержаться адрес следующего элемента a[16]. Физически содержимое переменной p увеличивается на размер одного элемента типа double, т.е. на 8.
Операции увеличения ++ и уменьшения -- на единицу имеют префиксную и суффиксную формы. В префиксной форме операция записывается перед переменной, как в приведенных выше примерах. В суффиксной форме операция записывается после переменной:
++x; // Префиксная форма
x--; // Суффиксная форма
Разница между префиксной и суффиксной формами проявляется только при вычислении сложных выражений. Если используется префиксная форма операции ++, то сначала переменная увеличивается, и только после этого ее новое значение используется в выражении. При использовании суффиксной формы значение переменной сначала используется в выражении и только затем увеличивается. Примеры:
int x = 5, y = 5, a, b;
a = (++x) + 2; // переменной a присваивается значение 8
b = (y++) + 2; // переменной b присваивается значение 7
С логической точки зрения, префиксная операция более естественна (при использовании суффиксной формы надо сперва вычислить сложное выражение и только затем вернуться к увеличению переменной, т.е. операция ++ выполняется не в момент ее использования, а как бы откладывается на потом). Забегая вперед, отметим, что это различие весьма существенно при программировании на C++ в случае переопределения операторов увеличения для классов. Тем не менее, в большинстве книг по Си суффиксная форма используется чаще (скорее всего, эта традиция, связаная с эстетикой текста).
Дадим два совета (возможно, не бесспорные) по использованию операций ++ и --:
никогда не применяйте эти операции в сложных выражениях! Ничего, кроме путаницы, это не дает. Например, вместо фрагмента
double *p, x, y;
. . .
y = *p++ + x;
лучше использовать фрагмент
double *p, x, y;
. . .
y = *p + x;
++p;
С точки зрения компилятора, они абсолютно эквивалентны, но второй фрагмент проще и понятнее (и, значит, вероятность ошибки программирования меньше);
всегда отдавайте предпочтение префиксной форме операций ++ и --. Например, вместо фрагмента
int x, y;
. . .
x++; y--; // Используется суффиксная форма
лучше использовать фрагмент
int x, y;
. . .
++x; --y; // Лучше применять префиксную форму