Что ,
оператор делает в C?
c
operators
comma-operator
lillq
источник
источник
Ответы:
Выражение:
Сначала вычисляется выражение1, затем вычисляется выражение2, и значение выражения2 возвращается для всего выражения.
источник
i
значений 5, 4, 3, 2 или 1. Это просто 0. Это практически бесполезно, если выражения не имеют побочных эффектов.i = b, c;
эквивалентно(i = b), c
потому что, потому что присваивание=
имеет более высокий приоритет, чем оператор запятой,
. Оператор запятой имеет самый низкий приоритет из всех.expression1, expression2;
сначалаexpression1
оценивается, предположительно, на наличие побочных эффектов (таких как вызов функции), затем идет точка последовательности, затемexpression2
оценивается и возвращается значение…Я видел, используется больше всего в
while
циклах:Он выполнит операцию, а затем проведет тест на основе побочного эффекта. Другим способом было бы сделать это так:
источник
while (read_string(s) && s.len() > 5)
. Очевидно, что это не сработало бы, если быread_string
не иметь возвращаемого значения (или не иметь значащего значения). (Изменить: Извините, не заметил, сколько лет было этому сообщению.)while (1)
сbreak;
утверждением в теле. Попытка форсировать выделенную часть кода во время теста во время теста или во время теста, часто является пустой тратой энергии и усложняет понимание кода.while(1)
иbreak
;Оператор запятой оценит левый операнд, отбросит результат, а затем оценит правый операнд, и это будет результат. Идиоматично использование , как указано в ссылке, когда инициализации переменных , используемые в
for
цикле, и это дает следующий пример:В противном случае не так много хороших вариантов использования оператора запятой , хотя его легко использовать для создания кода, который трудно читать и обслуживать.
Из проекта стандарта C99 грамматика выглядит следующим образом:
и параграф 2 говорит:
Сноска 97 гласит:
это означает, что вы не можете присвоить результат оператора запятой .
Важно отметить, что оператор запятой имеет самый низкий приоритет, и поэтому существуют случаи, когда использование
()
может иметь большое значение, например:будет иметь следующий вывод:
источник
Оператор запятой объединяет два выражения по обе стороны от него в одно, оценивая их оба в порядке слева направо. Значение правой части возвращается как значение всего выражения.
(expr1, expr2)
Это как,{ expr1; expr2; }
но вы можете использовать результатexpr2
в вызове функции или назначении.Это часто встречается в
for
циклах для инициализации или поддержки нескольких переменных, например:Кроме того, я использовал его «в гневе» только в одном другом случае, когда оборачивал две операции, которые всегда должны идти вместе в макросе. У нас был код, который копировал различные двоичные значения в байтовый буфер для отправки по сети, и указатель сохранялся там, где мы получили:
Где значения были
short
s илиint
s, мы сделали это:Позже мы читаем, что это не был действительно C, потому что
(short *)ptr
он больше не является l-значением и не может быть увеличен, хотя наш компилятор в то время не возражал. Чтобы исправить это, мы разделили выражение на две части:Тем не менее, этот подход основывался на том, что все разработчики всегда помнили, что нужно использовать оба утверждения. Мы хотели функцию, в которой вы могли бы передать выходной указатель, значение и и тип значения. Это C, а не C ++ с шаблонами, у нас не могло быть функции, принимающей произвольный тип, поэтому мы остановились на макросе:
Используя оператор запятой, мы могли использовать это в выражениях или в выражениях, как нам хотелось:
Я не предполагаю, что любой из этих примеров - хороший стиль! Действительно, мне кажется, что Стив Макконнелл в Code Complete советует даже не использовать запятые операторы в
for
цикле: для удобства чтения и поддержки цикл должен управляться только одной переменной, а выражения в самойfor
строке должны содержать только код управления циклом, не другие дополнительные биты инициализации или обслуживания цикла.источник
Он вызывает оценку нескольких операторов, но использует только последнее в качестве результирующего значения (я думаю, что это значение r).
Так...
должно привести к тому, что x будет установлен на 8.
источник
Как указывалось в предыдущих ответах, он оценивает все утверждения, но использует последнее в качестве значения выражения. Лично я нашел это полезным только в выражениях цикла:
источник
Единственное место, где я увидел, что это полезно, - это когда вы пишете какой-то интересный цикл, в котором вы хотите сделать несколько вещей в одном из выражений (возможно, в выражении init или в выражении цикла.
Извините, если есть какие-либо синтаксические ошибки или я смешал что-то, что не является строгим C. Я не утверждаю, что оператор, является хорошей формой, но это то, для чего вы могли бы его использовать. В приведенном выше случае я бы, вероятно, использовал
while
цикл вместо этого, чтобы множественные выражения в init и loop были бы более очевидными. (И я бы инициализировал i1 и i2 inline вместо объявления, а затем инициализации .... бла-бла-бла.)источник
Я возрождаю это просто для того, чтобы ответить на вопросы @Rajesh и @JeffMercado, которые, я думаю, очень важны, поскольку это один из самых популярных хитов в поисковых системах.
Возьмите следующий фрагмент кода, например
Будет печатать
i
Случай рассматривается как объяснено в большинстве ответов. Все выражения оцениваются в порядке слева направо, но назначается только последнееi
. Результат(
выражения )is
1`.j
Случай следует различным правилам приоритета , поскольку,
имеет самый низкий приоритет оператора. Из - за этих правил, компилятор видит присваивания-выражение, константа, постоянная ... . Выражения снова оцениваются в порядке слева направо, и их побочные эффекты остаются видимыми, поэтомуj
является5
результатомj = 5
.Интересно,
int j = 5,4,3,2,1;
что не допускается языковой спецификацией. Инициализатор ожидает присвоения самовыражения поэтому прямой,
оператор не допускаются.Надеюсь это поможет.
источник