46 votes

C++ -- return x,y ; Quel est le point ?

Je programme en C et C++ depuis quelques années et je suis maintenant un cours universitaire dans ce domaine. Notre livre contenait une fonction comme celle-ci comme exemple :

int foo(){
  int x=0;
  int y=20;
  return x,y; //y is always returned
}

Je n'ai jamais vu une telle syntaxe. En fait, je n'ai jamais vu le , utilisé en dehors des listes de paramètres. Si y est toujours retournée, alors quel est l'intérêt ? Existe-t-il un cas où une instruction de retour devrait être créée de cette manière ?

(J'ai aussi marqué C car cela s'applique aux deux, bien que mon livre porte spécifiquement sur le C++).

51voto

Justin Ethier Points 57486

Según la C FAQ :

Précisément, la signification de l'opérateur virgule dans l'expression générale

e1 , e2

est "évaluer la sous-expression e1, puis évaluer e2 ; la valeur de l'expression est la valeur de e2". Par conséquent, e1 a intérêt à impliquer une affectation ou un incrément ++ ou un décrément -- ou un appel de fonction ou un autre type d'effet secondaire, car sinon il calculerait une valeur qui serait rejetée.

Je suis donc d'accord avec vous, il n'y a aucun intérêt si ce n'est pour illustrer que c'est une syntaxe valide, si ce n'est que ça.

Si vous vouliez renvoyer les deux valeurs en C ou en C++, vous pourriez créer un objet struct contenant x y y et renvoie la structure à la place :

struct point {int x; int y;};

Vous pouvez ensuite définir un type et une fonction d'aide pour vous permettre de renvoyer facilement les deux valeurs dans la fonction struct :

typedef struct point Point;

Point point(int xx, int yy){
  Point p;
  p.x = xx;
  p.y = yy;
  return p;
}

Puis modifiez votre code original pour utiliser la fonction d'aide :

Point foo(){
  int x=0;
  int y=20;
  return point(x,y); // x and y are both returned
}

Et enfin, vous pouvez l'essayer :

Point p = foo();
printf("%d, %d\n", p.x, p.y);

Cet exemple se compile à la fois en C et en C++. Bien que, comme Mark le suggère ci-dessous, en C++, vous pouvez définir un constructeur pour l'objet point qui offre une solution plus élégante.


Soit dit en passant, la possibilité de renvoyer directement plusieurs valeurs est merveilleuse dans les langages tels que Python qui la prennent en charge :

def foo():
  x = 0
  y = 20
  return x,y # Returns a tuple containing both x and y

>>> foo()
(0, 20)

23voto

La virgule dans les listes de paramètres est juste là pour séparer les paramètres, et n'est pas la même chose que l'opérateur virgule. L'opérateur virgule, comme dans votre exemple, évalue à la fois x et y, puis rejette x.

Dans ce cas, je suppose qu'il s'agit d'une erreur de quelqu'un qui a essayé de renvoyer deux valeurs, et qui ne savait pas comment faire.

20voto

Joel Points 3899

L'opérateur virgule est principalement utilisé dans for comme ça :

for( int i=0, j=10; i<10; i++, j++ )
{
    a[i] = b[j];
}

La première virgule n'est pas un opérateur de virgule, elle fait partie de la syntaxe de déclaration. La deuxième es un opérateur virgule.

9voto

jcoder Points 14982

Cela ne répond pas vraiment à la question originale mais pourrait intéresser certaines personnes, mais si vous vouliez qu'il renvoie les deux en C++, vous devriez l'écrire comme ceci (et vous auriez besoin d'un compilateur c++0x)

tuple<int, int> foo()
{
    int x = 0;
    int y = 20;
    return make_tuple(x, y);
}

L'accès se fait comme suit -

tuple<int, int> data = foo();
int a = get<0>(data);
int b = get<1>(data);

8voto

KennyTM Points 232647
 struct Point {
   int x, y;
   Point(int x_) : x(x_), y(0) {}
   Point(const Point& p) : x(p.x), y(p.y) {}
   Point operator, (int y_) const { Point p=*this; p.y = y_; return p; }
 };

 Point get_the_point () {
    int x = 0;
    int y = 20;
    return (Point)x, y;
 }

:p

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X