mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Kann eine Funktion 2 Werte zurückgeben per Return?


Autor: Msp 430_crew (msp430_crew)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich dachte an soetwas:
int test(void)
{foo;
return a,b;
}

Wie kann man das machen?

Autor: Jens D. (jens) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jein
nicht direkt.
Du kannst aber einen Pointer der funktion übergeben in der du 2 werte 
aenderst.

http://www.mikrocontroller.net/articles/AT91-TWI#twi_read

Schau dir das hier mal an

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein.
Eine Funktion hat per definition nur EINEN Rückgabewert.
Du kannst aber einen struct z.B. verwenden, oder der Funktion pointer 
übergeben wo sie die Ergebnisse hinschreiben soll.

Autor: Msp 430_crew (msp430_crew)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

Autor: Mark Struberg (struberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einfach den 2. Wert per call-by-reference übergeben


int wert2;

int testfn(int* pwert2) {
  *pwert2 = A;
  return B;
}

Autor: Philipp Karbach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du kannst aber auch shiften, das machte man früher wenn man wenig 
speicher hatte gerne:

int dostuff(int r,int g,int b,int i)
{
int value = r | ( g << 8 ) | ( b << 16 ) | ( i << 24 );

return value;
}

die werte lassen sich dann wie folgt auseinander nehmen:

int color = dostuff(128,96,28,255);
int r = color & 255;
int g = ( color >> 8 ) & 255;
int b = ( color >> 16 ) & 255;
int i = ( color >> 24 ) & 255;

So habe ich früher gerne mal farben "kodiert" :). auch eine möglichkeit!

Autor: Dirk S. (tomcat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit der Struct als Returnwert hört sich unheimlich an.
Legt der Compiler die Struktur vor Funktionsaufruf bereits auf dem Stack 
an?
Wie kann man die einzelnen Elemente dann erreichen?
Wird von der Funktion ein Zeiger zurückgegeben?
Wie funktioniert das genau, weis das einer?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdio.h>

struct Pair {
  int Component1;
  int Component2;
};


struct Pair foo( void )
{
  struct Pair RetVal;

  RetVal.Component1 = 5;
  RetVal.Component2 = 7;

  return RetVal;
}

int main()
{
  struct Pair Result;

  Result = foo();

  printf( "%d %d\n", Result.Component1, Result.Component2 );
}

> Legt der Compiler die Struktur vor Funktionsaufruf bereits auf
> dem Stack an?

Könnte er. Ist aber dem Compiler überlassen.

> Wie kann man die einzelnen Elemente dann erreichen?
So wie bei jeder anderen struct auch: Indem man die Komponente
angibt, auf die man zugreifen möchte

> Wird von der Funktion ein Zeiger zurückgegeben?
Nein. Im Funktionskopf steht, dass eine Struktur zurückgegeben
wird. Und genau das passiert auch. Zumindest dann, wenn der
Compiler keine Return-Value-Optimization macht.

> Wie funktioniert das genau, weis das einer?
Ja, dein Compiler.

Autor: Dirk S. (tomcat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vom Aufbau her hätte ich mir das auch genau so vorgestellt.
Sieht allerdings nach einer ziehmlichen Kopierorgie aus.
Das lokale struct RetVal nuss ja bei return irgendwohin kopiert werden, 
wo es den Funktionsaufruf "überlebt". Und als zweites das kopieren in 
die Variable "Result" damit man auf die einzelnen Elemente Zugriff 
bekommt. Kann da der Kompiler überhaupt optimieren? Schließlich kann die 
Funktion von verschiedenen Stellen aus aufgerufen werden und die 
"Returnstruct" (woimmer sie auch liegen mag) muss damit Standardisiert 
sein.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk S. wrote:
> Kann da der Kompiler überhaupt optimieren?

Und wie er das kann!
C++ lebt davon, dass es hier eine Möglichkeit zur Optimierung
gibt.

> Schließlich kann die
> Funktion von verschiedenen Stellen aus aufgerufen werden und die
> "Returnstruct" (woimmer sie auch liegen mag) muss damit Standardisiert
> sein.

Und?
Wenn der Compiler die NRVO (named return value optimization)
immer benutzt, ist das ja kein Problem.

Was ist die NRVO?
Kurz gesagt, der Compiler stellt das hier:
struct Pair foo( void )
{
  struct Pair RetVal;

  RetVal.Component1 = 5;
  RetVal.Component2 = 7;

  return RetVal;
}

int main()
{
  struct Pair Result;
  Result = foo();

so um
void foo( struct Pair* pTmp )
{
  pTmp->Component1 = 5;
  pTmp->Component2 = 7;
}

int main()
{
  struct Pair Result;

  foo(&Result);

et voila, keine Kopierorgie mehr.

Autor: Dirk S. (tomcat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, sehr anschaulich erklärt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.