Ответ 1
Он будет равен b
.
Оператор запятой имеет более низкий приоритет, чем назначение.
Как работает оператор запятой на С++?
Например, если:
a = b, c;
Получается ли в итоге значение 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
.
Оператор запятой имеет более низкий приоритет, чем назначение.
Позаботьтесь о том, что оператор запятой может быть перегружен в С++. Фактическое поведение может, таким образом, сильно отличаться от ожидаемого.
В качестве примера Boost.Spirit использует оператор запятой довольно умно, чтобы реализовать инициализаторы списка для таблиц символов. Таким образом, он делает возможным следующий синтаксис:
keywords = "and", "or", "not", "xor";
Обратите внимание, что из-за приоритета оператора код (намеренно!) идентичен
(((keywords = "and"), "or"), "not"), "xor";
То есть первый оператор называется keywords.operator =("and")
, который возвращает прокси-объект, на который вызывается оставшийся operator,
:
keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");
Оператор запятой имеет приоритет самый низкий всех операторов C/С++. Поэтому всегда он привязывается к выражению, что означает следующее:
a = b, c;
эквивалентно:
(a = b), c;
Еще один интересный факт заключается в том, что оператор запятой вводит точку . Это означает, что выражение:
a+b, c(), d
гарантировано, что его три подвыражения (a + b, c() и d) оцениваются по порядку. Это важно, если у них есть побочные эффекты. Обычно компиляторам разрешено оценивать подвыражения в любом порядке, который они считают нужным; например, при вызове функции:
someFunc(arg1, arg2, arg3)
аргументы могут быть оценены в произвольном порядке. Обратите внимание, что запятые в вызове функции не являются операторами; они являются разделителями.
Оператор запятой:
Стандартная версия оператора запятой определяется для всех типов (встроенных и настраиваемых), и она работает следующим образом: exprA , exprB
:
exprA
оцениваетсяexprA
игнорируетсяexprB
оцениваетсяexprB
возвращается как результат всего выраженияДля большинства операторов компилятору разрешено выбирать порядок выполнения, и даже требуется пропустить выполнение вообще, если оно не влияет на конечный результат (например, false && foo()
пропустит вызов до foo
). Однако это не относится к оператору запятой, и указанные шаги всегда будут выполняться *.
На практике оператор запятой по умолчанию работает почти так же, как точка с запятой. Разница заключается в том, что два выражения, разделенные точкой с запятой, образуют два отдельных оператора, а разделение запятой сохраняет все как одно выражение. Вот почему оператор запятой иногда используется в следующих сценариях:
if( HERE )
Для синтаксиса for
for ( HERE ; ; )
if (foo) HERE ;
(пожалуйста, не делайте этого, это действительно уродливо!)Если оператор не является выражением, точка с запятой не может быть заменена запятой. Например, они запрещены:
(foo, if (foo) bar)
(if
не является выражением)В вашем случае мы имеем:
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);
a будет равно b
, а d
будет равно c
.
b будет присвоено значению a. Ничего не произойдет с c
Значение a будет равно b, поскольку оператор запятой имеет более низкий приоритет, чем оператор присваивания.
Да Оператор Comma имеет низкий приоритет, чем оператор присваивания
#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;
}
Обычно начинающий С++ думал, что это выражение могло бы/могло бы сравнивать вещи, но оно абсолютно неверно, смысл токенов <
, >
и ,
зависит от контекста использования.
Правильная интерпретация приведенного выше примера, конечно же, является установлением шаблона.
Пример 2:
Когда мы пишем типичный цикл цикла с более чем одной переменной инициализации и/или более чем одним выражением, которое должно быть сделано после каждой итерации цикла, мы также используем запятую:
for(a=5,b=0;a<42;a++,b--)
...
Значение запятой зависит от контекста использования, здесь это контекст конструкции for
.
Чтобы усложнить его еще больше (как всегда в С++), оператор запятой может быть перегружен (благодаря Konrad Rudolph, указав это).
Чтобы вернуться к вопросу, Код
a = b, c;
означает для компилятора что-то вроде
(a = b), c;
поскольку приоритет токена/оператора =
выше приоритета маркера ,
.
и это интерпретируется в контексте типа
a = b;
c;
(обратите внимание, что интерпретация зависит от контекста, здесь она не является вызовом функции/метода или статированием шаблона.)