Я только что нашел код, который по существу делает следующее:
int a = (1, 2, 3);
Я раньше этого не видел. Что это значит?
Я только что нашел код, который по существу делает следующее:
int a = (1, 2, 3);
Я раньше этого не видел. Что это значит?
Это оператор запятой: оценка a, b
сначала вызывает a
, затем b
, а результат - результат b
.
int a = (1, 2, 3);
сначала оценивает 1
, затем 2
, наконец 3
, и использует последний 3
для инициализации a
. Это бесполезно здесь, но может быть полезно, когда левый операнд ,
имеет побочные эффекты (обычно: когда он вызывает функцию).
Он использует оператор запятая, которая просто оценивает каждое выражение операнда последовательно (вводя соответствующие точки последовательности между ними) и возвращает последний. Таким образом, ваш пример фактически эквивалентен int a = 3;
.
Но это действительно один из наименее используемых операторов в C и С++ и не следует путать с запятыми, используемыми в выражениях вызова функций, списках инициализаторов и во всех других местах. Не столь редкий случай использования будет иметь несколько приращений для циклов (for(...; ...; ++i,++j)
), даже если вы, вероятно, никогда не думали об этом, используя так называемый оператор запятой.
Еще один интересный случай использования заключается в попытке поместить несколько концептуально связанных выражений в один оператор (например, возврат) для ясности и лаконичности, например, в реализации старого старого frexp
с его странным аргументом возврата указателя (игнорируйте тот факт, что правильный С++ просто вернул пару):
double frexp(double arg, int *exp)
{
if(...)
return *exp=..., result;
...
}
который намного более упорядочен, чем эквивалентный
double frexp(double arg, int *exp)
{
if(...)
{
*exp = ...;
return result;
}
...
}
Wiki: Comma operator
i = (a, b, c); // stores c into i
Это оператор запятой. Стандарт C11 сообщает об одном случае использования такого типа оператора.
C11 стандарт 6: 5: 17
Командный оператор
Левый операнд оператора запятой оценивается как пустота выражение; между его оценкой и точкой правого операнда. Затем оценивается правый операнд; результат имеет свой тип и значение .114)
Оператор запятой (как описано в этом подпункте) не могут появляться в контекстах, где запятая используется для отдельные элементы в списке (например, аргументы для функций или списки Инициализаторы). С другой стороны, он может использоваться в пределах в скобках или во втором выражении условный оператор в таких контекстах. В вызове функции f (a, (t = 3, t + 2), c) функция имеет три аргумента, вторая из которых имеет значение 5.
Он просто оценивает 1, 2 и 3 (поскольку они являются только значениями, но также могут быть вызовами функций) и устанавливает значение (или возвращаемое значение) последнего в левый операнд (в вашем примере).
Возможно, это поможет вам понять, как это работает:
#include <stdio.h>
int toto()
{
printf("toto()\n");
return (21);
}
int tata()
{
printf("tata()\n");
return (42);
}
int main()
{
int a = (toto(), tata());
printf("%d\n", a);
return (0);
}
Вывод:
toto()
tata()
42
Изменить: Tha C, работает на С++
Это запятая. Он "обертывает" несколько выражений, оценивает их слева направо, а значение всего выражения определяется последним подвыражением. В вашем примере он оценивается как 3
.
Ситуация, в которой оператор запятой особенно удобен, - это если вы хотите сделать несколько вещей в выражении "increment" for-loop, например, чтобы увеличить две переменные.
Пример. Итерируйте изображение по диагонали, используя x
и y
в качестве отдельных переменных. Я использую две отдельные переменные для x
и y
, потому что я мог бы изменить один из них в цикле независимо друг от друга (помните, это просто глупый пример). Поэтому я хочу увеличивать как x
, так и y
в инструкции "increment" for-loop:
for(int x = 0, y = 0; x < width && y < height; ++x, ++y) {
// ... ^^^^^^^^
}
Обратите внимание, что выражение "инициализация" for-loop использует не, используя оператор запятой; он просто объявляет две переменные.