Jak działa Operator Przecinka

Jak działa operator przecinka w C++?

Na przykład, jeśli zrobię:

a = b, c;  

Czy a kończy się równaniem b czy c?

(tak, Wiem, że jest to łatwe do przetestowania - wystarczy udokumentować tutaj, aby ktoś szybko znalazł odpowiedź.)

Update: to pytanie ujawniło niuans podczas używania operatora przecinka. Aby to udokumentować:

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

a = (b, c);  // a is set to the value of c!
To pytanie zostało zainspirowane literówką w kodzie. Co miało być
a = b;
c = d;

Odwrócony do

a = b,    //  <-  Note comma typo!
c = d;
Author: Coding Mash, 2008-09-10

9 answers

Będzie równa b.

Operator przecinka ma niższy priorytet niż przypisanie.

 73
Author: Leon Timmermans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-13 17:04:41

Zwróć uwagę, że operator przecinka może być przeciążony w C++. Rzeczywiste zachowanie może więc znacznie różnić się od oczekiwanego.

Jako przykład, zwiększ.Spirit używa operatora przecinka dość sprytnie do implementacji inicjalizatorów list dla tabel symboli. W ten sposób następująca składnia jest możliwa i ma znaczenie:

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

Zauważ, że ze względu na pierwszeństwo operatora, kod jest (celowo!) identyczne z

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

Czyli pierwszy operator wywołane jest keywords.operator =("and"), które zwraca obiekt proxy, na którym wywołane są pozostałe operator,s:

keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");
 121
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-09 11:10:22

Operator przecinka ma najniższy pierwszeństwo ze wszystkich operatorów C / C++. Dlatego zawsze jest ostatnim, który wiąże się z wyrażeniem, co oznacza:

a = b, c;

Jest równoważne:

(a = b), c;

Innym interesującym faktem jest to, że operator przecinka wprowadza punkt sekwencji . Oznacza to, że wyrażenie:

a+b, c(), d

Ma zagwarantowane trzy podwyrażenia (a + b, C () i d) oceniane w kolejności. Jest to istotne, jeśli mają skutki uboczne. Zwykle Kompilatory mogą oceniać podwyrażenia w dowolnej kolejności, jaką uznają za odpowiednią; na przykład w wywołaniu funkcji:

someFunc(arg1, arg2, arg3)

Argumenty mogą być oceniane W dowolnej kolejności. Zauważ, że przecinki w wywołaniu funkcji są operatorami , a nie; są to separatory.

 115
Author: efotinis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 11:49:36

Operator przecinka:

  • ma najniższy priorytet
  • jest lewy-asocjacyjny

Domyślna wersja operatora przecinka jest zdefiniowana dla wszystkich typów (wbudowanych i niestandardowych) i działa w następujący sposób-podano exprA , exprB:

  • exprA jest oceniany
  • wynik {[1] } jest ignorowany
  • exprB jest oceniany
  • wynik exprB jest zwracany jako wynik całego wyrażenia

Z większością operatorów, kompilator może wybrać kolejność wykonania i jest nawet wymagane, aby pominąć wykonanie w ogóle, jeśli nie ma to wpływu na wynik końcowy(np. {[5] } pominie wywołanie do foo). Tak jednak nie jest w przypadku operatora przecinka i powyższe kroki zawsze się zdarzają*.

W praktyce domyślny operator przecinka działa prawie tak samo jak średnik. Różnica polega na tym, że dwa wyrażenia oddzielone średnikiem tworzą dwa oddzielne wyrażenia, natomiast rozdzielenie przecinkami zachowuje wszystko jako jedno wyrażenie. Z tego powodu operator przecinka jest czasami używany w następujących scenariuszach:

    Składnia C wymaga pojedynczego wyrażenia, a nie instrukcji. np. w if( HERE )
  • składnia C wymaga pojedynczej instrukcji, nie więcej, np. w inicjalizacji pętli for for ( HERE ; ; )
  • kiedy chcesz pominąć kręcone szelki i zachować jedno stwierdzenie: if (foo) HERE ; (proszę nie rób tego, to naprawdę brzydkie!)

Gdy oświadczenie nie jest wyrażenie, średnik nie może być zastąpiony przecinkiem. Na przykład są one niedozwolone:

  • (foo, if (foo) bar) (if nie jest wyrażeniem)
  • int x, int y (deklaracja zmiennej nie jest wyrażeniem)

W Twoim przypadku mamy:

  • a=b, c;, odpowiednik a=b; c;, przy założeniu, że a jest typu, który nie przeciąża operatora przecinka.
  • a = b, c = d; odpowiednik a=b; c=d;, przy założeniu, że a jest typu, który nie przeciąża przecinka centrala.

Zauważ, że nie każdy przecinek jest operatorem przecinka. Niektóre przecinki, które mają zupełnie inne znaczenie:

  • int a, b; - - - lista deklaracji zmiennych jest rozdzielana przecinkami, ale nie są to operatory przecinkowe
  • int a=5, b=3; - - - jest to również lista deklaracji zmiennych rozdzielonych przecinkami
  • foo(x,y)- - - oddzielona przecinkami lista argumentów. W rzeczywistości, x i y mogą być oceniane w dowolnej kolejności!
  • FOO(x,y) --- lista argumentów makro rozdzielonych przecinkami
  • foo<a,b>- - - oddzielona przecinkami lista argumentów szablonu
  • int foo(int a, int b)- - - oddzielona przecinkami lista parametrów
  • Foo::Foo() : a(5), b(3) {}- - - oddzielona przecinkami lista inicjalizacyjna w konstruktorze klasy

* nie jest to do końca prawdą, jeśli zastosujesz optymalizacje. Jeśli kompilator uzna, że pewien fragment kodu nie ma absolutnie żadnego wpływu na resztę, usunie niepotrzebne instrukcje.

Czytaj dalej: http://en.wikipedia.org/wiki/Comma_operator

 57
Author: CygnusX1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-05 14:49:58

Wartość {[1] } będzie b, ale wartość wyrażenie będzie c. Czyli w

d = (a = b, c);

A będzie równe b, a d będzie równe c.

 37
Author: MobyDX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-08 23:36:27

Wartość B zostanie przypisana do a. Nic się nie stanie c

 8
Author: prakash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-10 14:16:54

Wartość a będzie równa b, ponieważ operator przecinka ma niższy priorytet niż operator przypisania.

 2
Author: Jason Carreiro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-07 02:09:31

Tak operator Przecinka ma niski priorytet niż operator przypisania

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

Wyjście: i=3
Ponieważ operator przecinka zawsze zwraca wartość po prawej stronie.
W przypadku operatora przecinka z operatorem przypisania:

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

Ouput: i=1
Jak wiemy operator przecinka ma niższy priorytet niż przypisanie.....

 2
Author: Roopam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-04 13:31:23

Po pierwsze: przecinek w rzeczywistości nie jest operatorem, dla kompilatora jest to tylko token, który otrzymuje znaczenie w kontekście z innymi tokenami.

Co to oznacza i po co się przejmować?

Przykład 1:

Aby zrozumieć różnicę między znaczeniem tego samego symbolu w innym kontekście, przyjrzyjmy się temu przykładowi:

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

Zwykle początkujący C++ pomyślałby, że to wyrażenie może / porównuje rzeczy ale jest całkowicie błędne, znaczenie <, > i , żetony zależą od kontekstu użycia.

Poprawna interpretacja powyższego przykładu jest oczywiście taka, że jest to instancja szablonu.

Przykład 2:

Gdy piszemy typowo dla pętli z więcej niż jedną zmienną inicjalizacyjną i / lub więcej niż jednym wyrażeniem, które należy wykonać po każdej iteracji pętli, używamy również przecinka:

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

Znaczenie przecinka zależy od kontekstu użycia, tutaj jest to kontekst konstrukcji for.

Co właściwie oznacza przecinek w kontekście?

Aby jeszcze bardziej skomplikować (jak zawsze w C++) operator przecinka może być przeciążony (dzięki Konradowi Rudolphowi za wskazanie tego).

Wracając do pytania, kod

a = b, c;

Oznacza dla kompilatora coś w rodzaju

(a = b), c;

Ponieważ priorytet tokena/operatora = jest wyższy niż priorytet tokena ,.

I jest to interpretowane w kontekście jak

a = b;
c;

(zauważ, że interpretacja zależy od kontekstu, tutaj nie jest to ani wywołanie funkcji / metody, ani instancja szablonu.)

 -2
Author: Quonux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:10