C++ – x,y zurückgeben; Was ist der Sinn?

Lesezeit: 8 Minuten

Benutzeravatar von Earlz
Earlz

Ich programmiere seit ein paar Jahren in C und C++ und jetzt mache ich gerade einen College-Kurs darin und unser Buch hatte zum Beispiel eine Funktion wie diese:

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

Ich habe noch nie eine solche Syntax gesehen. Tatsächlich habe ich das noch nie gesehen , Operator, der außerhalb von Parameterlisten verwendet wird. Wenn y wird aber immer zurückgegeben, was ist dann der Sinn? Gibt es einen Fall, in dem eine Rückgabeerklärung so erstellt werden müsste?

(Außerdem habe ich auch C markiert, weil es für beide gilt, obwohl mein Buch speziell C++ ist.)

  • Aus welchem ​​Buch ist das? Ich kann mir keinen legitimen Grund dafür vorstellen.

    – Stefan

    29. März 2010 um 16:16 Uhr

  • “D. Malik, C++ Programming: Program Design Inclusion Data Structures, Fourth Edition. Course Technology Incorporated, 2007, ISBN 1-4188-3640-0” Ich empfehle es niemandem, da der Autor anscheinend kein sicheres Verständnis hat von C++ Dinge erwähnt wie “Variablendeklarationen gehen immer an den Anfang der Funktion, egal was passiert.”

    – Earlz

    29. März 2010 um 16:19 Uhr

  • Wirf das Buch weg.

    – Daniel Daranas

    29. März 2010 um 16:20 Uhr


  • @Daniel, ich wünschte wirklich, ich könnte es, aber es ist erforderlich, um meine College-Credits zu bekommen

    – Earlz

    29. März 2010 um 16:22 Uhr

  • @Frank V: Selbst das würde keinen Sinn machen – die Variablen gehen aus dem Geltungsbereich. @Earlz: Ist es überhaupt möglich, dass dies lediglich demonstrieren soll, dass dies der Fall ist? nicht zwei Werte zurückgeben? Geben Sie ein Beispiel dafür, was Sie nicht tun sollten?

    – Kaskabel

    29. März 2010 um 16:29 Uhr

Benutzeravatar von Justin Ethier
Justin Ether

Laut dem C-Häufig gestellte Fragen:

Genau gesagt, die Bedeutung des Komma-Operators im allgemeinen Ausdruck

e1, e2

ist “den Teilausdruck e1 auswerten, dann e2 auswerten; der Wert des Ausdrucks ist der Wert von e2.” Daher sollte e1 besser eine Zuweisung oder ein Inkrement ++ oder ein Dekrement — oder einen Funktionsaufruf oder eine andere Art von Nebeneffekt enthalten, da es sonst einen Wert berechnen würde, der verworfen würde.

Da stimme ich dir zu, es hat keinen Sinn außer um zu veranschaulichen, dass dies eine gültige Syntax ist, wenn überhaupt.

Wenn Sie beide Werte in C oder C++ zurückgeben möchten, können Sie eine erstellen struct enthält x und y Mitglieder, und geben Sie stattdessen die Struktur zurück:

struct point {int x; int y;};

Sie können dann einen Typ und eine Hilfsfunktion definieren, damit Sie beide Werte problemlos innerhalb der zurückgeben können struct:

typedef struct point Point;

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

Und ändern Sie dann Ihren ursprünglichen Code, um die Hilfsfunktion zu verwenden:

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

Und schließlich können Sie es ausprobieren:

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

Dieses Beispiel wird sowohl in C als auch in C++ kompiliert. Obwohl Sie, wie Mark weiter unten vorschlägt, in C++ einen Konstruktor für die definieren können point Struktur, die eine elegantere Lösung bietet.


Nebenbei bemerkt, die Möglichkeit, mehrere Werte direkt zurückzugeben, ist wunderbar in Sprachen wie Python, die dies unterstützen:

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

>>> foo()
(0, 20)

  • Vielen Dank für die Erklärung des Operators.

    – Jeff Davis

    24. Juni 2010 um 19:31 Uhr

  • Dein point struct braucht einen Konstruktor, der zwei nimmt int Parameter.

    – Markieren Sie Lösegeld

    24. Juni 2010 um 19:49 Uhr

  • @Markiere die struct ist nur ein Beispiel – würden Sie das bitte näher erläutern? Genau genommen gibt es in C keine Konstruktoren. Unabhängig davon lässt sich der Code in C und C++ problemlos kompilieren, und die x und y Mitglieder können direkt per Code aufgerufen werden.

    – Justin Ethier

    5. August 2011 um 1:00 Uhr

  • In C hast du Recht, kein Konstruktor ist möglich. In C++ lässt Sie das ein Konstruktor tun return point(x,y);. Entschuldigung, dass ich so kryptisch bin.

    – Markieren Sie Lösegeld

    5. August 2011 um 2:01 Uhr


  • Ich wollte darauf hinweisen, dass Ihr Punkt, einen Punkt zu machen, wenn es keinen Sinn hatte, mich amüsiert hat.

    – Jason Reis

    2. Januar 2015 um 4:08 Uhr

Das Komma in Parameterlisten dient nur dazu, die Parameter zu trennen, und ist nicht dasselbe wie der Kommaoperator. Der Kommaoperator wertet wie in Ihrem Beispiel sowohl x als auch y aus und wirft dann x weg.

In diesem Fall würde ich vermuten, dass es sich um einen Fehler von jemandem handelt, der versucht, zwei Werte zurückzugeben, und nicht wusste, wie das geht.

Benutzeravatar von Joel
Joel

Der Kommaoperator wird hauptsächlich in verwendet for Aussagen wie diese:

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

Das erste Komma ist kein Kommaoperator, sondern Teil der Deklarationssyntax. Der Zweite ist ein Kommaoperator.

  • Das macht keinen Sinn. Warum wird diese Antwort positiv bewertet und warum wird diese als die richtige ausgewählt? Es ist völlig irrelevant für die gestellte Frage.

    – vivekian2

    4. August 2011 um 22:49 Uhr

  • In diesem Fall ist die Verwendung des Kommas erforderlich, um beide zu erhöhen i und j. Es gibt andere Fälle, in denen Sie das Komma anstelle eines Semikolons verwenden können, wenn Sie betonen möchten, dass beide Anweisungen wirklich eng miteinander verbunden sind und nicht getrennt werden sollten. Zum Beispiel std::memcpy(data, moredata, moresize), datasize+=size;. Ich halte die Aussagen gerne zusammen, um zu vermeiden, dass jemand versehentlich den zweiten Teil verschiebt oder löscht.

    – Andre Caron

    5. August 2011 um 14:23 Uhr

  • @Joel: Es gibt Abzeichen zu verdienen, wenn Sie positiv bewertete/akzeptierte Antworten zurücknehmen.

    – Sebastian Mach

    6. März 2012 um 10:46 Uhr

  • Ich nahm die Frage hinter der Frage als “Warum einen Kommaoperator?” anstatt “Warum einen in einer Rückgabeerklärung haben?” Anscheinend stimmte das OP zu, dass dies seine eigentliche Frage war.

    – Joel

    6. März 2012 um 18:01 Uhr

Dies beantwortet die ursprüngliche Frage überhaupt nicht wirklich, könnte aber für einige Leute von Interesse sein, aber wenn Sie beides in C++ zurückgeben wollten, müssten Sie es so schreiben (und würden einen c++0x-Compiler benötigen )

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

Der Zugriff geht so –

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

 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

  • Das ist also nicht C++. Ich meine, es wird kompiliert, aber das ist so unlesbar. Ick.

    – Clay

    29. März 2010 um 16:42 Uhr

  • @clahey: Dann wirst du das hassen: boost.org/doc/libs/1_42_0/libs/assign/doc/index.html

    – kennytm

    29. März 2010 um 16:50 Uhr

  • Ich denke, das Boost-Zeug ist definitiv fragwürdig, aber es gibt etwas Schlimmeres an dem, was Sie da haben. Zum Beispiel: “Rückkehr (Punkt)1, 2, 3;” gibt (1,3) zurück. “return (Point)1” gibt (1,0) zurück. Beides fühlt sich nicht wie intuitives Verhalten an. Außerdem speichert Ihre Notation nichts. Wenn Sie nur einen richtigen Konstruktor deklarieren, der zwei Ints akzeptiert, können Sie einfach “return Point(x, y);” schreiben. Es spart nicht einmal ein einziges Zeichen beim Tippen und ist besser lesbar. Das Boost-Zeug spart zumindest viel Tipparbeit.

    – Clay

    29. März 2010 um 17:14 Uhr

  • @clahey: Beachten Sie, dass ich diesen Stil nicht befürworte (siehe “:p”?), Ich zeige dort nur vielleicht einen “Punkt”, dass ein Kommaoperator missbraucht wird (ich kann keinen mehrzeiligen Kommentar platzieren ).

    – kennytm

    29. März 2010 um 17:48 Uhr

  • Das ist so wunderbar teuflisch. Gibt es ein Äquivalent des IOCCC für C++?

    – Johannes Bode

    29. März 2010 um 20:25 Uhr

Benutzeravatar von Joel Rondeau
Joel Rondeau

So wie jeder, der hier kommentiert, denkt, dass es sinnlos ist, und ich bin nicht anderer Meinung, wenn ich mir nur das Beispiel anschaue, werde ich eine Vermutung anstellen, die nicht viel besser ist:

Der Schreiber erhielt eine Compiler-Warnung darüber, dass x nicht in der Funktion verwendet wird, und dies war eine einfache Möglichkeit, die Warnung verschwinden zu lassen.

  • Das ist also nicht C++. Ich meine, es wird kompiliert, aber das ist so unlesbar. Ick.

    – Clay

    29. März 2010 um 16:42 Uhr

  • @clahey: Dann wirst du das hassen: boost.org/doc/libs/1_42_0/libs/assign/doc/index.html

    – kennytm

    29. März 2010 um 16:50 Uhr

  • Ich denke, das Boost-Zeug ist definitiv fragwürdig, aber es gibt etwas Schlimmeres an dem, was Sie da haben. Zum Beispiel: “Rückkehr (Punkt)1, 2, 3;” gibt (1,3) zurück. “return (Point)1” gibt (1,0) zurück. Beides fühlt sich nicht wie intuitives Verhalten an. Außerdem speichert Ihre Notation nichts. Wenn Sie nur einen richtigen Konstruktor deklarieren, der zwei Ints akzeptiert, können Sie einfach “return Point(x, y);” schreiben. Es spart nicht einmal ein einziges Zeichen beim Tippen und ist besser lesbar. Das Boost-Zeug spart zumindest viel Tipparbeit.

    – Clay

    29. März 2010 um 17:14 Uhr

  • @clahey: Beachten Sie, dass ich diesen Stil nicht befürworte (siehe “:p”?), Ich zeige dort nur vielleicht einen “Punkt”, dass ein Kommaoperator missbraucht wird (ich kann keinen mehrzeiligen Kommentar platzieren ).

    – kennytm

    29. März 2010 um 17:48 Uhr

  • Das ist so wunderbar teuflisch. Gibt es ein Äquivalent des IOCCC für C++?

    – Johannes Bode

    29. März 2010 um 20:25 Uhr

Dies ist das Kommaoperator (,).

Beide Ausdrücke x und y werden ausgewertet. Das Ergebnis des Gesamtausdrucks ist y, dh letzterer Wert.

Es ist schwer zu sagen, warum es hier verwendet wird. Vermutlich zu Demonstrationszwecken. Natürlich könnte die Funktion umgestaltet werden zu:

int foo()
{
  return 20;
}

  • @mmyers: und die hier gegebene Antwort lautet … es scheint keinen Sinn zu geben.

    – Kaskabel

    29. März 2010 um 16:17 Uhr

  • @Jefromi: Das war nicht da, als ich kommentierte.

    – Michael myers

    29. März 2010 um 16:32 Uhr

1408690cookie-checkC++ – x,y zurückgeben; Was ist der Sinn?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy