Оператор запятая (,), встречающийся в языке C, является бинарным оператором, приоритет которого ниже большинства других операторов. Его основное назначение — последовательное выполнение выражений слева направо с возвращением значения только самого правого выражения. Используется он редко, но в конструкциях, требующих одновременного вычисления нескольких выражений в одной строке, бывает полезен.
История вопроса: Оператор запятая был введён в C для предоставления возможности дополнительно комбинировать выражения в присваиваниях, циклах for и вызываемых функциях. Исторически — из стремления создать как можно более выразительный, но минималистичный язык для системного программирования.
Проблема: Многие начинающие путают оператор запятая с простым разделителем аргументов и не учитывают его правила приоритета и ассоциативности; из-за этого возникают ошибки вычисления выражений и неожиданные побочные эффекты. Использование может вести к снижению читаемости кода.
Решение: Оператор запятая оправдан внутри тела цикла for (в инициализации и шаге), а также в макросах и конструкциях с побочными эффектами. В остальных случаях рекомендуется избегать нежелания спутать с разделителем или ухудшения читаемости.
Пример кода:
int i = 0, j = 10; while (i < 10) i++, j--; // i увеличивается, j уменьшается int a; a = (i = 1, j = 2, i + j); // a == 3, потому что возвращается результат последнего выражения
Ключевые особенности:
В чём разница между оператором запятая (,) и запятой как разделителем аргументов функции?
Запятая между аргументами функции — часть синтаксиса вызова, а не оператор: аргументы не вычисляются слева направо строго по приоритету оператора, а в независимости от компилятора. Оператор запятая — именно оператор, действующий в выражении.
Можно ли использовать оператор запятая вне выражений, например, в объявлении переменных?
Нет, при объявлении переменных запятая — разделитель, оператором она становится только внутри выражения. В объявлении:
int x = 1, y = 2;
Что вернёт выражение (a = 10, b = 20, a + b)?
Оно выполнит a = 10; затем b = 20; и вернёт значение выражения a + b, то есть 30.
int a, b, result; result = (a = 10, b = 20, a + b); // result == 30
Разработчик объединяет несколько выражений с побочными эффектами через запятую внутри одной строки, усложняя дебаг и понимание потока исполнения.
Плюсы:
Минусы:
Применение оператора запятая только в инициализации и шаге for, с явными комментариями и прозрачными изменениями переменных.
Плюсы:
Минусы: