Что означает разделенный запятыми список значений, заключенный в скобки в C? а = (1, 2, 3); [дубликат]

этот вопрос уже есть ответ здесь:

Я просто наткнитесь на код, который по существу делает следующее:

int a = (1, 2, 3);

Я никогда не видел эту запись раньше. Что это значит?

6 ответов


это оператор запятая оценка a, b первые причины a для оценки, затем b, и результатом является то, что b.

int a = (1, 2, 3); сначала оценивает 1, потом 2, наконец,3, и использует, что последний 3 для начала a. Здесь это бесполезно, но может быть полезно, когда левый операнд , имеет побочные эффекты (Обычно: когда это вызов функции).


использует оператор запятая, который просто оценивает каждое выражение операнда последовательно (вводя правильные точки последовательности между ними) и возвращает последний. Таким образом, ваш пример фактически эквивалентен int a = 3;.

но это действительно один из наименее используемых операторов C и C++ и не путать с запятыми, используемыми в выражениях вызова функций, списках инициализаторов и во всех других местах. Не так редкий случай использования будет кратным шагом для циклов (for(...; ...; ++i,++j)), хотя вы, вероятно, никогда не думали об этом на самом деле, используя так называемый оператор запятой.

еще один интересный случай использования-это попытка поместить несколько концептуально связанных выражений в одно утверждение (например, возврат) ради ясности и краткости, как в реализации старого доброго frexp С его странным аргументом возврата указателя (игнорируйте тот факт ,что правильный C++ просто вернет пара):

double frexp(double arg, int *exp)
{
    if(...)
        return *exp=..., result;
    ...
}

который намного более обтекаемый, чем эквивалентный

double frexp(double arg, int *exp)
{
    if(...)
    {
        *exp = ...;
        return result;
    }
    ...
}

Wiki:оператор запятая

i = (a, b, c);          // stores c into i

Это оператор "запятая". Стандарт C11 рассказывает об одном случае использования такого оператора.

C11 стандартный 6:5:17

оператор запятая

левый операнд оператора запятой оценивается как void выражение; существует точка последовательности между его оценкой и тем, что правого операнда. Затем правый операнд вычисляется, результат имеет свой тип и значение.114)

запятая оператор (как описано в этом подразделе) не может отображаться в контекстах, где запятая используется для отдельные элементы в списке (например, аргументы функций или списки инициализаторы.) С другой стороны,--8-->его можно использовать в пределах выражение в скобках или во втором выражении a условный оператор в таких условиях. В вызове функции f (a, (t=3, t+2), c) функция имеет три аргумента, второй из которых имеет значение 5.


это оператор запятая. Он "заворачивает" несколько выражений, оценивает их слева направо, а значение всего выражения определяется последнего подвыражения. В вашем примере он оценивается как 3.

ситуация, когда оператор запятой особенно удобен, если вы хотите сделать несколько вещей в выражении "increment" для цикла, например, увеличить два переменные.

пример: повторите изображение по диагонали, используя x и y как отдельные переменные. Я использую две отдельные переменные для x и y потому что я могу захотеть изменить один из них в цикле независимо от другого (помните, это просто глупый пример). Поэтому я хочу увеличить оба x и y в операторе "increment" оператора for-loop:

for(int x = 0, y = 0; x < width && y < height; ++x, ++y) {
    // ...                                     ^^^^^^^^
}

обратите внимание, что выражение "инициализация" цикла for делает не используйте оператор запятой; он как раз объявляет два переменные.


Он просто оценивает 1, 2 и 3 (поскольку они являются только значениями, но также могут быть вызовами функций) и устанавливает значение (или возвращаемое значение) последнего слева операнда (в вашем примере, a).

возможно, это поможет вам понять, как это работает:

#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'S C code, работает одинаково в C++