Domanda

Come fa l'operatore virgola lavoro in C++?

Per esempio, se io faccio:

a = b, c;  

Non una fine uguale a b o c?

(Sì, lo so che è facile per un test a documentare qui da qualcuno per trovare la risposta in tempi rapidi.)

Aggiornamento: A questa domanda ha esposto una nuance quando si utilizza l'operatore virgola.Solo per documentare questo:

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

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

Questa questione era in realtà ispirato da un errore di battitura nel codice.Ciò che è stato inteso per essere

a = b;
c = d;

Trasformato in

a = b,    //  <-  Note comma typo!
c = d;
È stato utile?

Soluzione

Sarebbe pari a b.

L'operatore virgola è inferiore precedenza di assegnazione.

Altri suggerimenti

Prendersi cura di notare che l'operatore virgola può essere sovraccaricato in C++.Il comportamento effettivo, quindi, può essere molto diverso da quello previsto.

Come esempio, Boost.Spirito utilizza l'operatore virgola abbastanza abilmente per implementare la lista di inizializzatori per le tabelle di simboli.Pertanto, si rende la seguente sintassi possibile e significativo:

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

Si noti che a causa della precedenza degli operatori, il codice è (volutamente!) identico a

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

Che è, il primo operatore è chiamato keywords.operator =("and") che restituisce un oggetto proxy su cui il restante operator,s vengono richiamati:

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

L'operatore virgola ha il più basso la precedenza di tutti i C/C++ operatori.Pertanto è sempre l'ultimo ad associare a un'espressione, cioè questo:

a = b, c;

è equivalente a:

(a = b), c;

Un altro fatto interessante è che l'operatore virgola introduce un sequenza di punto.Questo significa che l'espressione:

a+b, c(), d

è garantito per avere le sue tre espressioni (a+b, c() e d) valutati in ordine.Questo è importante se si hanno effetti collaterali.Normalmente i compilatori sono permesso di valutare sottoespressioni in qualunque ordine si trova in forma;per esempio, in una chiamata di funzione:

someFunc(arg1, arg2, arg3)

gli argomenti possono essere valutati in un ordine arbitrario.Si noti che le virgole nella chiamata di funzione sono non operatori;sono separatori.

L'operatore virgola:

  • ha il più basso precedenza
  • è associatività da sinistra a destra

Una versione predefinita di operatore virgola è definito per tutti i tipi built-in e personalizzata), e funziona come segue - dato exprA , exprB:

  • exprA viene valutata
  • il risultato di exprA viene ignorato
  • exprB viene valutata
  • il risultato di exprB viene restituito come risultato di tutta l'espressione

Con la maggior parte degli operatori, il compilatore è consentito di scegliere l'ordine di esecuzione è anche necessario per saltare l'esecuzione di sorta se non pregiudica il risultato finale (ad es. false && foo() salta la chiamata a foo).Questo non è comunque il caso di operatore virgola e la procedura di cui sopra sarà sempre accadere*.

In pratica, il valore di default operatore virgola funziona quasi allo stesso modo come un punto e virgola.La differenza è che le due espressioni separate da un punto e virgola forma di due prospetti separati, mentre la virgola di separazione mantiene tutti come una singola espressione.Questo è il motivo per operatore virgola è a volte utilizzato nei seguenti scenari:

  • La sintassi del C e richiede una singola espressione, non una dichiarazione.ad es.in if( HERE )
  • La sintassi del C e richiede una singola istruzione, non di più, ad es.in fase di inizializzazione del for loop for ( HERE ; ; )
  • Quando si desidera saltare parentesi graffe e mantenere una singola istruzione: if (foo) HERE ; (si prega di non farlo, è davvero brutto!)

Quando un'istruzione non è un'espressione, un punto e virgola non può essere sostituito da una virgola.Per esempio questi non sono consentiti:

  • (foo, if (foo) bar) (if non è un'espressione)
  • int x, int y (dichiarazione di variabile non è un'espressione)

Nel tuo caso abbiamo:

  • a=b, c;, equivalente a a=b; c;, supponendo che a è del tipo che non sovraccaricare l'operatore virgola.
  • a = b, c = d; equivalente per a=b; c=d;, supponendo che a è del tipo che non sovraccaricare l'operatore virgola.

Faccio notare che non ogni virgola è in realtà un operatore virgola.Alcune virgole che hanno un significato completamente diverso:

  • int a, b; --- dichiarazione di variabile lista separata da virgole, ma questi non sono virgola operatori
  • int a=5, b=3; --- anche questa è una variabile separati da virgola dichiarazione elenco
  • foo(x,y) --- virgola-separato elenco di argomenti.Infatti, x e y può essere valutato in qualsiasi un ordine!!!
  • FOO(x,y) --- virgola-separato macro elenco di argomenti
  • foo<a,b> --- virgola-separato modello di elenco di argomenti
  • int foo(int a, int b) --- virgola-separato elenco di parametri
  • Foo::Foo() : a(5), b(3) {} --- virgola-separato lista di inizializzazione nel costruttore della classe

* Questo non è del tutto vero se si applica ottimizzazioni.Se il compilatore riconosce che certo pezzo di codice non ha assolutamente alcun impatto sul resto, sarà rimuovere le inutili dichiarazioni.

Ulteriore lettura: http://en.wikipedia.org/wiki/Comma_operator

Il valore di a sarà b, ma il valore di l'espressione sarà c.Che è, in

d = (a = b, c);

una sarebbe pari a b, e d sarebbe pari a c.

b verrà assegnato un valore ad una.Non accadrà nulla a c

Il valore di a è uguale a b, in quanto l'operatore virgola è inferiore precedenza che l'operatore di assegnazione.

Sì operatore Virgola ha una bassa priorità rispetto operatore di Assegnazione

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

Output :i=3
Perché l'operatore virgola sempre tornare valore più a destra.
In caso di operatore virgola con l'Operatore di Assegnazione:

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

Uscita:i=1
Come sappiamo operatore virgola è inferiore precedenza di assegnazione.....

Prime cose prima: Virgola, in realtà non è un operatore, per il compilatore è solo un "token" che ottiene un significato in contesto con altri token.

Che cosa significa e perché preoccuparsi?

Esempio 1:

Per capire la differenza tra il significato della stessa token in un contesto diverso diamo un'occhiata a questo esempio:

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

Di solito un C++ principiante potrebbe pensare che questa espressione potrebbe/dovrebbe confrontare le cose, ma è assolutamente sbagliato, il significato del <, > e , token depent del contesto di utilizzo.

La corretta interpretazione dell'esempio di cui sopra è, naturalmente, che si tratta di un instatiation di un modello.

Esempio 2:

Quando scriviamo un tipico ciclo con più di una inizializzazione variabile e/o più espressioni che dovrebbe essere fatto dopo ogni iterazione del ciclo usiamo la virgola di troppo:

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

Il significato della virgola dipende dal contesto di utilizzo, qui è il contesto di for costruzione.

Che cosa fa una virgola in un contesto di realtà?

A complicare ancora di più (come sempre in C++) l'operatore virgola può essere sovraccaricato (grazie a Konrad Rudolph per la segnalazione).

Per tornare alla domanda, il Codice

a = b, c;

significa che per il compilatore qualcosa di simile

(a = b), c;

perché il priorità del = token/operatore è maggiore la priorità del , token.

e questo viene interpretato in un contesto come

a = b;
c;

(nota che l'interpretazione che dipendono dal contesto, qui non è né una funzione/metodo di chiamata o di un modello di instatiation.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top