- •Введение
- •Язык программирования Си Элементы языка программирования.
- •Множества символов
- •Буквы и цифры
- •Пробельные символы
- •Знаки пунктуации и специальные символы
- •Операции
- •Константы
- •Целые константы
- •Константы с плавающей точкой
- •Константа-символ
- •Строковые литералы
- •Идентификаторы
- •Ключевые слова
- •Комментарии
- •Лексемы
- •Структура программы
- •Исходная программа
- •Исходные файлы
- •Выполнение программ
- •Время жизни и видимость
- •Классы имен
- •Объявления
- •Спецификаторы типов
- •Область значений величин
- •Деклараторы
- •Деклараторы массивов, функций и указателей
- •Составные деклараторы
- •Объявления переменной
- •Объявление простой переменной
- •Объявление перечисления
- •Объявления структур
- •Объявление совмещений
- •Объявление массива
- •Объявление указателей
- •Объявление функций
- •Объявление классов
- •Классы памяти
- •Объявления переменной на внешнем уровне
- •Объявление переменной на внутреннем уровне
- •Объявление функции на внешнем и внутреннем уровнях
- •Инициализация
- •Базовые типы и типы указателей
- •Составные типы
- •Строковые инициализаторы
- •Объявления типов
- •Типы структур, совмещений и перечислений
- •Объявления typedef
- •Имена типов
- •Выражения и присваивания
- •Введение
- •Операнды
- •Константы
- •Идентификаторы
- •Вызовы функций
- •Индексные выражения
- •Выражение выбора структурного элемента
- •Выражения с операциями
- •Выражения в скобках
- •Type-cast выражения
- •Константные выражения
- •Операции
- •Обычные арифметические преобразования.
- •Операции дополнения
- •Операция адресации и разадресации
- •Операция sizeof
- •Мультипликативные операции
- •Аддитивные операции
- •Операции сдвига
- •Операции отношений
- •Побитовые операции
- •Логические операции
- •Операция последовательного вычисления
- •Условная операция
- •Операции присваивания
- •Lvalue-выражения
- •Унарные инкремент и декремент
- •Простое присваивание
- •Составное присваивание
- •Старшинство и порядок выполнения
- •Побочные эффекты
- •Преобразования типов
- •Преобразование типов при присваивании
- •Преобразования type-cast
- •Преобразования, выполняемые операциями
- •Преобразования при вызовах функций
- •Операторы
- •Введение
- •Оператор break
- •Составной оператор
- •Оператор continue
- •Оператор do
- •Оператор-выражение
- •Оператор for
- •Goto и помеченные операторы
- •Оператор if
- •Оператор null
- •Оператор return
- •Оператор switch
- •Оператор while
- •Функции
- •Введение
- •Определение функции
- •Класс памяти
- •Тип возврата
- •Формальные параметры
- •Тело функции
- •Объявления функции
- •Вызовы функций
- •Фактические аргументы
- •Вызовы с переменным числом аргументов
- •Рекурсивные вызовы
- •Директивы препроцессора и указания компилятору
- •Поименованные константы и макросы
- •Директива # define
- •Директива #undef
- •#Include файлы
- •Условная компиляция
- •Директивы #if, #elif, #else, #endif
- •Директивы #ifdef и #ifndef
- •Управление нумерацией строк
Операция последовательного вычисления
Операция последовательного вычисления "," вычисляет два своих операнда последовательно слева направо. Результат операции имеет значение и тип второго операнда. Типы операндов не ограничиваются. Преобразования не выполняются.
Примеры:
/* ... example 1 ... */
for ( i = j = 1; i + j < 20; i += i, j --);
/* ... example 2 ...*/
funk_one (x,y+2,z);
funk_two ((x--,y+2),z);
В первом примере каждый операнд третьего выражения оператора for вычисляется независимо. Левый операнд i+=i вычисляется первым, затем вычисляется j--.
Во втором примере показано, что символ "запятая" используется как разделитель в двух контекстах. В вызове функции funk_one три аргумента, разделенных запятыми, посылаются в вызываемую функцию: x, y+2,z. Использование симовола "запятая" как разделителя не нужно путать с ее использованием как операции. Оба использования совершенно различны.
В вызове функции funk_two скобки вынуждают компилятор интерпретировать первую запятую как операцию последовательного вычисления. Этот вызов функции посылает два аргумента к funk_two. Первый аргумент - это результат операции последовательного вычисления (x--,y+2), имеющий значение и тип выражения y+2 . Второй аргумент есть z.
Условная операция
В Си есть одна тернарная операция - это условная операция "?:". Она имеет следующее синтаксическое представление:
<operand 1>?<operand 2>:<operand 3>
Выражение <operand 1> вычисляется с точки зрения его эквивалентности нулю. Оно может быть целого, плавающего или адресного типа. Если <operand 1> имеет ненулевое значение, то вычисляется <operand 2> и результатом условной операции является значение выражения <operand 2>. Если <operand 1> равен нулю, то вычисляется <operand 3> и результатом является значение выражения <operand 3>. Заметим, что вычисляется один из операндов <operand 2> или <operand 3>, но не оба.
Тип результата зависит от типов второго и третьего операндов следующим образом:
Если второй и третий операнды имеют целый или плавающий тип (их типы могут быть отличны), то выполняются обычные арифметические преобразования. Типом результата является тип операнда после преобразования.
Второй и третий операнды могут быть одного и того же структурного, совмещения или адресного типа. Тип результата будет тем же самым типом структуры, совмещения или адреса.
Один из второго или третьего операндов может быть указателем, а другой константным выражением со значением 0. Типом результата является адресный тип.
Пример
j = (i<0) ? (-i) : (i);
В примере j присваивается абсолютное значение i. Если i меньше нуля, то j присваивается -i. Если i больше или равно нулю, то j присваивается i.
Операции присваивания
Операции присваивания в Си могут вычислять и присваивать значения в одной операции. Используя составные операции присваивания вместо двух отдельных операций, можно сократить код программы и улучшить ее эффективность.
Операциями присваивания являются следующие:
Операция |
Действие |
++ |
Унарный инкремент |
-- |
Унарный декремент |
= |
Простое присваивание |
*= |
Умножение с присваиванием |
/= |
Деление с присваиванием |
%= |
Остаток от деления с присваиванием |
+= |
Сложение с присваиванием |
-= |
Вычитание с присваиванием |
<<= |
Сдвиг влево с присваиванием |
>>= |
Сдвиг вправо с присваиванием |
&= |
Побитовое and с присваиванием |
|= |
Побитовое включающее ИЛИ с присваиванием |
^= |
Побитовое исключающее ИЛИ с присваиванием |
При присваивании тип правого операнда преобразуется к типу левого операнда. Специфика преобразования детально описана в разделе 5.7.