Вопрос

Как работает оператор запятая в C++?

Например, если я это сделаю:

a = b, c;  

Будет ли a в конечном итоге равным b или c?

(Да, я знаю, что это легко проверить — просто задокументируйте здесь, чтобы кто-то мог быстро найти ответ.)

Обновлять: Этот вопрос выявил нюанс при использовании оператора запятой.Просто чтобы задокументировать это:

a = b, c;    // a is set to the value of b!

a = (b, c);  // a is set to the value of c!

На самом деле этот вопрос был вызван опечаткой в ​​​​коде.Что должно было быть

a = b;
c = d;

Превратился в

a = b,    //  <-  Note comma typo!
c = d;
Это было полезно?

Решение

Это было бы равно b.

Оператор запятая имеет более низкий приоритет, чем оператор присваивания.

Другие советы

Обратите внимание, что оператор запятая может быть перегружен в C++.Таким образом, фактическое поведение может сильно отличаться от ожидаемого.

В качестве примера, Повышение.Дух весьма умело использует оператор запятой для реализации инициализаторов списков для таблиц символов.Таким образом, это делает возможным и осмысленным следующий синтаксис:

keywords = "and", "or", "not", "xor";

Обратите внимание, что из-за приоритета операторов код (намеренно!) идентичен коду

(((keywords = "and"), "or"), "not"), "xor";

То есть первый вызванный оператор keywords.operator =("and") который возвращает прокси-объект, на котором оставшиеся operator,s вызываются:

keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");

Оператор запятая имеет самый низкий приоритет всех операторов C/C++.Поэтому он всегда последним привязывается к выражению, что означает следующее:

a = b, c;

эквивалентно:

(a = b), c;

Еще один интересный факт заключается в том, что оператор запятая вводит точка последовательности.Это означает, что выражение:

a+b, c(), d

гарантированно будет иметь три подвыражения (а+б, с() и д) оцениваются по порядку.Это важно, если у них есть побочные эффекты.Обычно компиляторам разрешается вычислять подвыражения в любом порядке, который они считают подходящим;например, при вызове функции:

someFunc(arg1, arg2, arg3)

аргументы могут оцениваться в произвольном порядке.Обратите внимание, что запятые в вызове функции нет операторы;они являются сепараторами.

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

  • имеет самый низкий приоритет
  • является левоассоциативным

Версия оператора запятой по умолчанию определена для всех типов (встроенных и пользовательских) и работает следующим образом: exprA , exprB:

  • exprA оценивается
  • результат exprA игнорируется
  • exprB оценивается
  • результат exprB возвращается как результат всего выражения

Для большинства операторов компилятору разрешено выбирать порядок выполнения и даже необходимо вообще пропустить выполнение, если это не влияет на конечный результат (например, false && foo() пропустит звонок на foo).Однако это не относится к оператору запятой, и описанные выше шаги всегда будут выполняться.*.

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

  • Синтаксис C требует одного выражение, не утверждение.напримерв if( HERE )
  • Синтаксис C требует одного оператора, не более, например.при инициализации for петля for ( HERE ; ; )
  • Если вы хотите пропустить фигурные скобки и сохранить один оператор: if (foo) HERE ; (пожалуйста, не делайте этого, это действительно некрасиво!)

Если утверждение не является выражением, точку с запятой нельзя заменить запятой.Например, запрещены:

  • (foo, if (foo) bar) (if это не выражение)
  • int x, int y (объявление переменной не является выражением)

В вашем случае у нас есть:

  • a=b, c;, эквивалентный a=b; c;, при условии, что a имеет тип, который не перегружает оператор запятой.
  • a = b, c = d; эквивалентно a=b; c=d;, при условии, что a имеет тип, который не перегружает оператор запятой.

Обратите внимание, что не каждая запятая на самом деле является оператором-запятой.Некоторые запятые, имеющие совершенно другое значение:

  • int a, b; --- список объявлений переменных разделен запятыми, но это не операторы-запятые
  • int a=5, b=3; --- это также список объявлений переменных, разделенных запятыми
  • foo(x,y) --- список аргументов, разделенных запятыми.Фактически, x и y можно оценить в любой заказ!
  • FOO(x,y) --- список аргументов макроса, разделенных запятыми
  • foo<a,b> --- список аргументов шаблона, разделенных запятыми
  • int foo(int a, int b) --- список параметров, разделенных запятыми
  • Foo::Foo() : a(5), b(3) {} --- список инициализаторов, разделенных запятыми, в конструкторе класса

* Это не совсем так, если применить оптимизацию.Если компилятор признает, что определенный фрагмент кода абсолютно не влияет на остальной код, он удалит ненужные операторы.

Дальнейшее чтение: http://en.wikipedia.org/wiki/Comma_operator

Значение a будет b, но значение выражение будет c.То есть в

d = (a = b, c);

а будет равно b, и d было бы равно c.

Значение b будет присвоено a.С c ничего не случится

Значение a будет равно b, поскольку оператор запятой имеет более низкий приоритет, чем оператор присваивания.

Да. Оператор запятой имеет более низкий приоритет, чем оператор присваивания.

#include<stdio.h>
int main()
{
          int i;
          i = (1,2,3);
          printf("i:%d\n",i);
          return 0;
}

Выход :я = 3
Потому что оператор запятая всегда возвращает крайнее правое значение.
В случае оператора запятой с оператором присваивания:

 int main()
{
      int i;
      i = 1,2,3;
      printf("i:%d\n",i);
      return 0;
}

Выход:я = 1
Как мы знаем, оператор запятой имеет более низкий приоритет, чем оператор присваивания.....

Перво-наперво: Запятая на самом деле не является оператором, для компилятора это просто токен, который приобретает смысл. в контексте с другими токенами.

Что это значит и зачем беспокоиться?

Пример 1:

Чтобы понять разницу между значением одного и того же токена в другом контексте, мы рассмотрим этот пример:

class Example {
   Foo<int, char*> ContentA;
}

Обычно новичок в C++ думает, что это выражение может/будет сравнивать вещи, но это абсолютно неверно. <, > и , токены зависят от контекста использования.

Правильная интерпретация приведенного выше примера, конечно же, заключается в том, что это создание шаблона.

Пример 2:

Когда мы обычно пишем цикл for с более чем одной переменной инициализации и/или более чем одним выражением, которые должны выполняться после каждой итерации цикла, мы также используем запятую:

for(a=5,b=0;a<42;a++,b--)
   ...

Значение запятой зависит от контекста употребления, здесь это контекст употребления. for строительство.

Что на самом деле означает запятая в контексте?

Чтобы еще больше усложнить ситуацию (как всегда в C++), оператор запятой может быть перегружен (благодаря Конрад Рудольф за указание на это).

Возвращаясь к вопросу, Кодекс

a = b, c;

означает для компилятора что-то вроде

(a = b), c;

поскольку приоритет принадлежащий = токен/оператор выше приоритета , жетон.

и это интерпретируется в контексте вроде

a = b;
c;

(обратите внимание, что интерпретация зависит от контекста, здесь это не вызов функции/метода или создание шаблона.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top