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


von Dominik K. (Gast)


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!
}

von Rolf Magnus (Gast)


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));

von Dominik K. (Gast)


Angehängte Dateien:

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?

von Wilfried Nesensohn (Gast)


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.

von Dominik K. (Gast)


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..)

von Dominik K. (Gast)


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?

von Wilfried Nesensohn (Gast)


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.

von Rolf Magnus (Gast)


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().

von Dominik K. (Gast)


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?

von Dominik K. (Gast)


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?

von The Daz (Gast)


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.

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

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

von Dominik K. (Gast)


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?

von The Daz (Gast)


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;
}

von The Daz (Gast)


Lesenswert?

Hier eine Referenz zur standard template lib :

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

von The Daz (Gast)


Lesenswert?

Noch besser sauberer waehre vermutlich :

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

von The Daz (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

1
vector<int> Test(vector<int>& array1, vector<int>& array2) 
2
{
3
    vector<int> ergebnisse;
4
5
    for (int idx =0; idx < min(array1.size(),array2.size()); idx++)
6
       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] );

von The Daz (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.