Question

Comment l'opérateur virgule en C++?

Par exemple, si je fais:

a = b, c;  

Un fin jusqu'à égaler b ou c?

(Oui, je sais c'est facile à tester - juste documenter sur ici pour quelqu'un de trouver rapidement la réponse.)

Mise à jour: Cette question a exposé une nuance lors de l'utilisation de l'opérateur virgule.Juste à ce document:

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

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

Cette question a été inspiré par une faute de frappe dans le code.Ce qui est censé être

a = b;
c = d;

Transformé en

a = b,    //  <-  Note comma typo!
c = d;
Était-ce utile?

La solution

Elle serait égale à b.

L'opérateur virgule a une priorité moins élevée que de l'affectation.

Autres conseils

Prenez soin de noter que l'opérateur virgule est peut-être surchargé en C++.Le comportement réel peut donc être très différente de celle attendue.

Comme un exemple, Coup de pouce.Esprit utilise l'opérateur virgule assez habilement à mettre en œuvre la liste des initialiseurs pour les tables de symboles.Ainsi, il rend la syntaxe suivante possible et significatif:

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

Notez qu'en raison de la priorité de l'opérateur, le code est (intentionnellement!) identique à

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

Le premier opérateur est appelé keywords.operator =("and") qui retourne un objet proxy sur le reste operator,s sont invoqués:

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

L'opérateur virgule a la plus bas la priorité de tous les C/C++ opérateurs.Par conséquent, il est toujours le dernier à se lier à une expression, qui signifie ceci:

a = b, c;

est équivalent à:

(a = b), c;

Un autre fait intéressant est que l'opérateur virgule introduit un point de séquence.Cela signifie que l'expression:

a+b, c(), d

est la garantie d'avoir trois de ses sous-expressions (a+b, c() et d) évaluées dans l'ordre.Ceci est important si elles ont des effets de bord.Normalement, les compilateurs sont autorisés à évaluer les sous-expressions dans quel ordre ils trouvent ajustement;par exemple, dans un appel de fonction:

someFunc(arg1, arg2, arg3)

les arguments peuvent être évalués dans un ordre arbitraire.Notez que les virgules dans l'appel de fonction sont pas les opérateurs;ils sont des séparateurs.

L'opérateur virgule:

  • a la priorité la plus basse
  • est-gauche associative

Une version par défaut de l'opérateur virgule est définie pour tous les types (intégrée et personnalisée), et il fonctionne comme suit, donnée exprA , exprB:

  • exprA est évaluée
  • le résultat de exprA est ignoré
  • exprB est évaluée
  • le résultat de exprB est retournée comme résultat de l'ensemble de l'expression

Avec la plupart des opérateurs, le compilateur est autorisé à choisir l'ordre d'exécution et il est même nécessaire de sauter de l'exécution que ce soit, si il n'a pas d'incidence sur le résultat final (par ex. false && foo() pour ignorer l'appel à foo).Ce n'est cependant pas le cas pour l'opérateur virgule et les étapes ci-dessus sera toujours le cas*.

Dans la pratique, la valeur par défaut opérateur virgule fonctionne presque de la même manière comme un point-virgule.La différence est que les deux expressions séparées par un point-virgule forme de deux états distincts, tandis que des virgules de séparation conserve tous comme une seule expression.C'est pourquoi l'opérateur virgule est parfois utilisé dans les scénarios suivants:

  • La syntaxe du C implique un seul expression, pas une déclaration.par exempledans if( HERE )
  • La syntaxe du C nécessite qu'une seule déclaration, pas plus, par exempledans l'initialisation de la for boucle for ( HERE ; ; )
  • Lorsque vous souhaitez passer des accolades et de garder une seule instruction: if (foo) HERE ; (merci de ne pas le faire, c'est vraiment moche!)

Lorsqu'une instruction est pas une expression, un point-virgule ne peut pas être remplacé par une virgule.Par exemple, ces sont interdits:

  • (foo, if (foo) bar) (if n'est pas une expression)
  • int x, int y (déclaration de variable n'est pas une expression)

Dans votre cas, nous avons:

  • a=b, c;, équivalent à a=b; c;, en supposant que a est de type qui n'a pas la surcharge de l'opérateur virgule.
  • a = b, c = d; équivalent à a=b; c=d;, en supposant que a est de type qui n'a pas la surcharge de l'opérateur virgule.

Ne noter que chaque virgule est en fait un opérateur virgule.Certains des virgules qui ont un sens complètement différent:

  • int a, b; --- la déclaration de la variable liste séparée par des virgules, mais ce ne sont pas des virgules opérateurs
  • int a=5, b=3; --- c'est également séparés par des virgules, la déclaration de la variable liste
  • foo(x,y) --- séparée par des virgules de la liste d'arguments.En fait, x et y ils peuvent être évalués à tout l'ordre!
  • FOO(x,y) --- séparées par des virgules macro liste d'arguments
  • foo<a,b> --- séparées par des virgules modèle de liste d'arguments
  • int foo(int a, int b) --- séparées par des virgules liste des paramètres
  • Foo::Foo() : a(5), b(3) {} --- séparées par des virgules initialiseur de liste à un constructeur de la classe

* Ce n'est pas tout à fait vrai si vous appliquez des optimisations.Si le compilateur reconnaît que certaines morceau de code n'a absolument aucun impact sur le reste, il va supprimer l'inutile consolidés.

Pour en savoir plus: http://en.wikipedia.org/wiki/Comma_operator

La valeur de a sera b, mais la valeur de l'expression sera c.C'est, en

d = (a = b, c);

un serait égale à b, et d serait égale à c.

b valeur sera attribuée à un.Rien ne va se passer à c

La valeur de a est égale à b, puisque l'opérateur virgule a une priorité plus basse que l'opérateur d'affectation.

Oui opérateur Virgule a une faible priorité que l'opérateur d'Affectation

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

Sortie :i=3
Parce que l'opérateur virgule toujours retourner le plus à droite de la valeur.
Dans le cas de l'opérateur virgule avec l'Opérateur d'Affectation:

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

Sortie:i=1
Comme nous le savons opérateur virgule a priorité moins élevée que de l'affectation.....

Tout d'abord: La virgule est en réalité pas un opérateur, pour le compilateur, il est juste un jeton qui reçoit un sens dans le contexte avec d'autres jetons.

Qu'est-ce que cela signifie et pourquoi s'embêter?

Exemple 1:

Pour comprendre la différence entre le sens de la même manière dans un contexte différent, nous prenons un coup d'oeil à cet exemple:

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

Habituellement, C++ débutant pourrait penser que cette expression pourrait/serait comparer des choses, mais c'est absolument faux, le sens de la <, > et , jetons depent sur le contexte d'utilisation.

L'interprétation correcte de l'exemple ci-dessus, c'est qu'il est un instatiation d'un modèle.

Exemple 2:

Lorsque nous écrire une boucle for avec plus d'une initialisation de variable et/ou plus d'une des expressions qui devrait être fait après chaque itération de la boucle, on utiliser une virgule en trop:

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

Le sens de la virgule dépend du contexte d'utilisation, ici c'est le contexte de la for la construction.

Ce n'est qu'une virgule dans le contexte signifie réellement?

Pour compliquer encore plus (comme toujours en C++) de l'opérateur virgule peut lui-même être surchargé (grâce à Konrad Rudolph pour souligné).

Pour en revenir à la question, le Code

a = b, c;

moyens pour le compilateur quelque chose comme

(a = b), c;

parce que le priorité de la = jeton/exploitant est supérieure à la priorité de l' , jeton.

et cela est interprété dans son contexte, comme

a = b;
c;

(notez que l'interprétation dépend du contexte, ici, il n'a ni une fonction/d'un appel de méthode ou d'un modèle de instatiation.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top