mikrocontroller.net

Forum: PC-Programmierung probleme mit Rückgabewerte in C


Autor: Dominik K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an Alle,

in Ansi C möchte ich in einer Funktion zwei oder mehrere int Wert
zurückgeben. Wie kann ich dies tun? Ich denke es ist ein sauberer
programmierstil, wenn man die Werte nicht direkt in der Funktion durch
printf ausgibt, oder?

void main (void)
{
 int array1[10];
 int array2[10];
 int ergebnisse[2];

 printf("Ergbnis1:%2d,Ergebnis2:%2d",Test......);
}

void Test(int* array1,int* array2,int iwerte,int* ergebnisse)
{
 ergebnisse[1]=array1[1] + array2[1];
 ergebnisse[2]=array1[1] + array2[2];

 return --> keine Ahnung wie!
}

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> in Ansi C

... muß main() int zurückliefern.

> möchte ich in einer Funktion zwei oder mehrere int Wert
> zurückgeben. Wie kann ich dies tun? Ich denke es ist ein sauberer
> programmierstil, wenn man die Werte nicht direkt in der Funktion
> durch printf ausgibt, oder?

Das sehe ich auch so.

> void Test(int* array1,int* array2,int iwerte,int* ergebnisse)
> {
>  ergebnisse[1]=array1[1] + array2[1];
>  ergebnisse[2]=array1[1] + array2[2];
>
>  return --> keine Ahnung wie!
> }

Wieso return? Du brauchst kein return. Der Rückgabetyp ist ja auch
void. Du mußt aber Test() vor dem printf aufrufen:

  Test(array1, array2, iwerte, ergebnisse);
  printf("Ergbnis1:%2d,Ergebnis2:%2d", ergebnisse);

Alternativ kannst du Test auch den int* zurückgeben lassen, den du als
Parameter übergeben hast, also:

int* Test(int* array1,int* array2,int iwerte,int* ergebnisse)
{
    ergebnisse[1]=array1[1] + array2[1];
    ergebnisse[2]=array1[1] + array2[2];

    return ergebnisse;
}

Dann geht's auch mit:

printf("Ergbnis1:%2d,Ergebnis2:%2d",
       Test(array1, array2, iwerte, ergebnisse));

Autor: Dominik K. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
int* Test(int* array1,int* array2,int iwerte,int* ergebnisse)
{
    ergebnisse[1]=array1[1] + array2[1];
    ergebnisse[2]=array1[1] + array2[2];

    return ergebnisse;
}

Dann geht's auch mit:

printf("Ergbnis1:%2d,Ergebnis2:%2d",
Test(array1, array2, iwerte, ergebnisse));

Wenn ich diese Variante auf meinen Code einfüge, dann erhalte ich vom
COmpiler eine Fehlermeldung-->Siehe Anhang.
Wie kann man eigentlich in C++ diese Angelegenheit dynamisch verwalten?

Autor: Wilfried Nesensohn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int ergebnisse[2];

...

    ergebnisse[1]=array1[1] + array2[1];
    ergebnisse[2]=array1[1] + array2[2];


ergebnisse[] ist 2 int lang, nicht 3!

In C wird ab 0 gezaehlt.

Du muesstest also alle indices um 1 erniedrigen, aus ergebnisse[1] wird
dann ergebnisse[0] usw.

Am besten besorgst du dir ein gutes Buch ueber C, um einmal die
Grundlagen zu lernen.

PS: Die Fehlermeldung kommt nicht vom Compiler sondern vom Debugger,
der C Code laesst sich wunderbar compilieren obwohl er offensichtlich
falsch ist.

Autor: Dominik K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ich habe meinen Code verbessert. Es kommt jetzt keine Fehlermeldung
mehr.

printf("ergebnis1:%2d ergebnis2:%2d",Test(array1, array2, iwerte,
ergebnisse),Test(array1, array2, iwerte, ergebnisse));

printf("ergebnis1:%2d ergebnis2:%2d",Test(array1, array2, iwerte,
ergebnisse));

beide Varianten habe ich getestet.
Als Rückgabewerte erhalte ich:
1244680 und 1243406. Das scheint mir so, als ob das Adressen sind.
Hm...

Ich habe zahlreiche Bücher und Unterlagen zu C. Leider habe ich da
bisher nicht gefunden zu diesem Thema!
Macht es eigentlich Sinn das ganze dynamsch zu verwalten? (mit new..)

Autor: Dominik K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das hier jetzt mal probiert:

printf("ergebnis1:%2d ergebnis2:%2d",*Test(array1, array2, iwerte,
ergebnisse),*Test(array1, array2, iwerte,
ergebnisse));

Da bekomme ich für ergebnis1 und ergebnis2 den gleichen Wert. Was
könnte da der Fehler sein?

Autor: Wilfried Nesensohn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Test(.....);
printf("ergebnis1:%2d ergebnis2:%2d",ergebnisse[0], ergebnisse[1]);

oder

printf("ergebnis1:%2d ergebnis2:%2d",*Test(array1, array2, iwerte,
ergebnisse),*(Test(array1, array2, iwerte,
ergebnisse)+1));

...ohne Anspruch auf Richtigkeit, da nicht getestet und schon lange
nichts mehr mit C gemacht.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sieht man mal wieder, daß man nicht posten sollte, wenn man in Eile
ist. Sorry, die Version meines Vorschlags, die einen Zeiger zurückgibt,
ist Blödsinn. Also, nimm einfah die erste Variante, die erst Test()
aufruft und danach printf().

Autor: Dominik K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok ich habe es jetzt hinbekommen. Danke!
Gehört diese methode eigentlich zum sauberen programmieren?
Das heisst man sollte immer der Funktion die entsprechenden Werte bzw.
Array übergeben und anschließend wieder ausgeben durch Rückgabewerte?

Kann man die von dir vorgestellt Variante auch dynamisch in C++ lösen?

Autor: Dominik K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gehört diese methode eigentlich zum sauberen programmieren?
Das heisst man sollte immer der Funktion die entsprechenden Werte bzw.
Array übergeben und anschließend wieder ausgeben durch Rückgabewerte?

Kann man die von dir vorgestellt Variante auch dynamisch in C++ lösen?

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da du ja mit C++ arbeitest, empfiehlt sich die standard template library
(Vektoren) und statt pointern entsprechende Objekt Referenzen. Dann kann
man auch sehr einfach den noetigen boundary check machen ohne einen
extra array size parameter durchzuschleifen.

Autor: Tobi H. (tobi-) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@The Daz
Jetzt verwirr den Armen doch nicht gleich und lass ihn erst einmal mit
C klarkommen!

Autor: Dominik K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also mein Programm läuft jetzt so wie ich gern möchte.
Ich hab es auch geschnallt wies funktioniert.

Hallo The Daz wie meinst du das? standard template library?
Kannst du dazu ein Beispiel machen, damit ich das verstehen kann?

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ohne Anspruch auf Fehlerfreiheit :

#include <vector>

vector<int> Test(vector<int>& array1, vector<int>& array2)
{
    vector<int> ergebnisse;

    for (int idx =0; idx < min(array1.size(),array2.size()); idx++)
       ergebnisse[idx] = array1[idx] + array2[idx];

    return ergebnisse;
}

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier eine Referenz zur standard template lib :

http://www.msoe.edu/eecs/cese/resources/stl/index.htm

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch besser sauberer waehre vermutlich :

vector<int> Test(const vector<int>& array1, const vector<int>& array2)

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Erklaerung :

Vektoren sind eine praktischer Ersatz fuer Arrays. Die Klasse vector
bringt auch einen ganzen Schwung Funktionen mit, wie z.B. size() mit
der die Anzahl der Elemente im Vektor ermittelt werden kann. Ausserdem
vergroessert sich der Vektor bei Bedarf von selbst. Das passiert unter
der Decke mit Hilfe von new() und delete() und das ohne, dass du dich
um das memory management kuemmern must. Im Gegensatz zu arrys kann man
Vektoren auch kopieren. Im Beispiel passiert dies beim zurueckgeben des
Ergebnis-Vektors. Die Eingabe-Vektoren koennen, muessen aber keine
Referenzen (&) sein. Man spart damit aber Speicher und Prozessorzyklen,
inbesondere wenn die Vektoren sehr gross werden. Das gleiche gilt fuer
den Ergebnis Vektor. Statt als return Parameter kann man, aehnlich wie
in deinem Beispiel, eine Referenz auf einen Zielvektor als Parameter
uebergeben. In diesem Fall sollte die Funktion als return Typ void
haben um unnoetiges kopieren des Ergebnis-Vektors zu vermeiden. Es
gehoert zum guten Ton, die Referenz-Parameter, die nicht von der
Funktion veraendert werden, als konstant (const) zu definieren.

Wannimmer moeglich versuche keine pointer zu verwenden. Pointer sind
eine unglaublich maechtige Waffe, in der Hand von Anfaengern aber eher
wie ne 45er Magnum in Kinderhaenden. Auch Profis schiessen sich mit den
Dingern regelmaessig ins Knie, und zwar ganz besonders gern bei C++.

Eins noch : ich bin mir nicht sicher, ob dein compiler die standard
template library ueberhaupt kennt. Wenn das include gut geht, die
Deklaration der Vektoren jedoch nicht, dann hat man meistens ein
namespace Problem. Dafuer gibt es dann zwei Loesungswege :

1. global den std namespace selektieren (direkt nach dem #include
<vector> die Zeile 'namespace std;' setzen, natuerlich ohne
Anfuehrungsstriche)
2. statt vector<int> einfach std::vector<int> schreiben

Lass mich wissen, wenn ich dich mehr verwirrt als informiert habe :)

   Daz

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

Bewertung
0 lesenswert
nicht lesenswert
vector<int> Test(vector<int>& array1, vector<int>& array2) 
{
    vector<int> ergebnisse;

    for (int idx =0; idx < min(array1.size(),array2.size()); idx++)
       ergebnisse[idx] = array1[idx] + array2[idx];

Das wird so nicht gehen. Nur weil Du einen std::vector definierst
erhältst Du nicht magisch Einträge in ihm.
Entweder den vector bei der Definition auf die richtige Grösse bringen,
oder mit resize() vordimensionieren, oder

     ergebnisse.push_back( array1[idx] + array2[idx] );

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz,

sorry, du hast natuerlich recht.

@Dominik:

also entweder Nach Karl Heinz' Methode mit push_back() Elemente
hinzufuegen, oder per

vector<int> ergebnisse(min(array1.size(),array2.size()));

Die vector Groesse vorher festlegen.

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.