# C/C++ zwei Werte zurückliefern



## PCIT (26. April 2015)

*C/C++ zwei Werte zurückliefern*

Hallo, ich soll eine Funktion schreiben, welche ein Argument übergeben bekommt (int M, so dass eine Schleife von 1 bis M durchlaufen wird) und dann sollen in dieser Funktion Berechnung durchgeführt werden und schließlich sollen zwei int Werte A und B von der Funktion zurückgegeben werden. Wie macht man sowas?


----------



## Malkolm (26. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Am einfachsten, indem du dir eine entsprechende Datenstruktur definierst und der Rückgabetyp der Funktion ebenfalls dieser Datentyp ist. Beispiel:

struct my_struct {
int A;
int B;
}

my_struct my_function(int M) {
my_struct daten;
daten.A = 0; daten.B = 0;
for(int i=0;i<M;i++) { daten.A += i; daten.B += i*i; }
return daten;
}

int main() {
int M = 10;
my_struct daten = my_function(M);
printf("Summe: %d, Quadratsumme: %d",daten.A,daten.B);
return 0;
}


----------



## Cinnayum (26. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Oder du übergibst den Zeiger auf die Variablen und schreibst direkt drin rum.
Dann kannst du return ohne Wert benutzen.

Aber vermutlich wird euch der Lehrer / Ausbilder dafür ohrfeigen, das ist fehleranfällig, wenn man nicht weiß, was man treibt.
Außerdem erfüllt es nicht ganz die Vorgabe, dass das Ergebnis zurückgegeben werden soll.


----------



## Bierseppi (26. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Ich wäre zu faul für die Stuct nur Pointer


----------



## Penman (26. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

In guter, alter C Manier, würde ich auch einfach 2 Referenzen übergeben. 
Wobei eine vernünftige Funktion nur einen Wert zurückgibt, da man designtechnisch sonst der Gefahr läuft, riesige Funktionen zu bauen und die Wiederverwertbarkeit  zu reduzieren. Auch wenn GO und Python zulassen, dass man mehrere Variablen zurückgibt, würde ich es in C nicht machen.


----------



## Crysis nerd (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Die idiomatische Variante für modernes C++ (11/14)  und für moderne Sprachen im Allgemeinen ist: std::pair


```
#include <utility>

use namespace std;

pair<int, int> func(int M) {
    // ...
    return make_pair(3, 27);
}

int main() {
    auto r = func(3);
    cout << r.first << endl;      // 3
    cout << r.second << endl;     // 27
}
```

Klingt doch auch logischer als alle anderen Varianten  
Zwei Dinge sind halt ein Paar


----------



## XPrototypeX (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Naja wenn man es pragmatisch sieht, wäre eine Struct besser, wenn man weiß das es bald 3 Zahlen sein könnten. Da müsste man bei deiner Variante mehr ändern, als wenn man eine simple Struktur oder Klasse hat (Auch wenn sich die Zahlen durch ganze Programm ziehen wäre es meiner Meinung nach ziemlich naiv immer ein Pair mitzuschleppen anstatt eine Struktur mit beschreibendem Namen).

Natürlich ist deine Variante erstmal lesbarer und erfordert weniger Code. 




Just my 2 Cents


----------



## Crysis nerd (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*



XPrototypeX schrieb:


> Naja wenn man es pragmatisch sieht, wäre eine Struct besser, wenn man weiß das es bald 3 Zahlen sein könnten.


Da hast du recht, aber glücklicherweise gibt es ja auch den Typ std::tuple, in dem man beliebig viele Elemente speichern kann:


```
std::tuple<int, float, char, Banana> func(int M) { ... }
```



XPrototypeX schrieb:


> [...]Struktur mit beschreibendem Namen.


Beschreibende Namen sind tatsächlich wichtig. Es kommt wirklich auf den Anwendungsfall drauf an. Wenn man schon weiß, dass der Rückgabewert viele unterschiedliche Daten enthält, sollte man von Anfang an ein struct benutzten, ja. Aber in vielen Situationen weiß man tatsächlich auch, dass man nur exakt 2 Werte zurück geben will. Dort ist dann pair oder tuple besser.


----------



## Olstyle (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Als C Hacker eine kleine Zwischenfrage: Was macht tuple dann überhaupt anders als einen struct inline zu definieren?


----------



## bingo88 (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Die Syntax von dem Kram ist jedenfalls merkwürdig, da würde ich doch lieber bei meinem alten struct bleiben wollen.


----------



## XPrototypeX (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Naja tuples kommen aus der funktionalen Programmierung, wo es häufig vorkommt das man mapping typen braucht für nur eine Funktion. Es wäre lästig für jeden temporären typen eine eigene Klasse / Struktur zu definieren.


----------



## bingo88 (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Ich bestreite ja auch gar nicht, dass es dafür Anwendungsfälle gibt. Wäre trotzdem nicht meine erste Wahl ^^


----------



## XPrototypeX (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Ich sehe da eher das Problem in C++ das sie meinen alles von anderen Sprachen mit abzudecken und gerade der funktionale Teil ist ihnen imho nicht besonders gut gelungen bzw. hat eine sehr hässliche Syntax.


----------



## Penman (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Dafür, dass es eine hässliche Syntax ist, ist es eine geniale Lösung. Ich wundere mich immer wieder über diese Genialität, die diese Informatiker in solche Sachen stecken. Wenn man mal den ganzen Netzwerkkram im Detail betrachtet, gibt es da so viele "Hackfixes", wie man trotzdem noch mit älteren Geräten kompatibel sein kann.

Ich bleibe aber bei meinem Statement, dass es in den meisten Fällen einfach nicht sinnvoll ist, mehr als einen Wert zurückzugeben.
Die Diskussion um zusammengehörige Werte und Objekte aka Pointer erspare ich mir mal.


----------



## Crysis nerd (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*



Olstyle schrieb:


> Als C Hacker eine kleine Zwischenfrage: Was macht tuple dann überhaupt anders als einen struct inline zu definieren?


Nix. Nur Vorsicht mit dem Wort "inline"... würde lieber "implizit" sagen. Detailliert: Durch die Template-Instanziierung wird aus dem Typ-Konstruktur `tuple` wird ein realer Typ erzeugt.



bingo88 schrieb:


> Die Syntax von dem Kram ist jedenfalls merkwürdig, da würde ich doch lieber bei meinem alten struct bleiben wollen.


Tatsächlich ist das so... `get<0>(myTuple)` ist schon merkwürdig, um das erste Element zu bekommen... Aber wenn man ein Tuple aus einer Funktion bekommt, kann `tie` recht nett sein: tie - C++ Reference



XPrototypeX schrieb:


> Ich sehe da eher das Problem in C++ das sie meinen alles von anderen Sprachen mit abzudecken und gerade der funktionale Teil ist ihnen imho nicht besonders gut gelungen bzw. hat eine sehr hässliche Syntax.


Leider ja. Andererseits ...



Penman schrieb:


> Dafür, dass es eine hässliche Syntax ist, ist es eine geniale Lösung.


... stimme ich hier zu: C++ erlaubt quasi jeden Programmierstil... nicht jeden mit besonders hübscher Syntax, das ist klar. Aber allein, dass es möglich ist so etwas allein durch eine Library zu implementieren, ist beachtlich.
Aber klar, es ist kein Vergleich zu Sprachen, die tuple gleich in das Typsystem eingebaut haben, wie Rust:


```
fn func(m: i32) -> (i32, i32) {
    (3, 27)
}

fn main() {
    let (a, b) = func(3);
    println!("{}, {}", a, b);    // 3, 27
}
```

EDIT: Kurze Erklärung für Interessierte:

 `i32` ist `int` mit 32 bits
`(i32, i32)` ist direkt ein gültiger Typ, nämlich ein tuple mit zwei `i32`
Funktionen werden so definiert: `fn function_name(arg_name: arg_type) -> return_type { ... }`
Es ist kein `return` in der Funktion, weil das letzte Statement in der Funktion impliziert zurückgegeben wird. Man könnte aber auch `return (3, 27);` schreiben
"{}" ist quasi wie "%d" in printf
Bei weiteren Fragen, fragt


----------



## Ap0ll0XT (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Ich würde bei festen Bezeichnern für diesen Zweck ebenfalls Strukturen vorziehen, wobei es dadurch allerdings dazu führen kann, das die Funktionen zu spezifisch werden und die Wiederverwendbarkeit leidet. Die Frage ist nur, ob es in einer funktionalen/prozeduralen Sprache überhaupt anders geht. Bei OOP ist klar, das die Methoden mit den Eigenschaften eines Objekts arbeiten und somit ein einfacher Rückgabewert einer Methode ausreicht. Aber bei funktionaler/prozeduraler Programmierung geht das ja so nicht.

Ich finde, das die Wiederverwendbarbeit einer Funktion/Prozedur gerade heute sehr schwer zu definieren ist. Früher (anno 2000) durfte ich in alten Büchern von Anfang der 90er (z.B alte BASIC-Bücher) lesen, das Funktionen/Prozeduren immer mit einem Datentyp wiederverwendbar sein sollten. Ist meiner Meinung nach für die heutige Zeit völliger Quatsch und ich habe auch kein Buch mehr gelesen, in dem das so kommuniziert wurde. Ich sehe es eher so, das Funktionen/Prozeduren wegen der steigenden Komplexität Redundanz aus dem Quellcode nehmen sollen und dem Programmierer die Möglichkeit geben, diese Aufgaben zentraler zu verwalten. Ich habe nie ein/-e Informatikstudium/Ausbildung zum Anwendungsentwickler genossen und kenne daher den offiziellen Standpunkt der Industrie zu dem Thema nicht. Aber ich verwende Funktionen/Prozeduren so, wie ich es mir denke. Das führt natürlich dazu, das man sehr viele Funktionen/Prozeduren hat, die alle nur eine Aufgabe auf nur einen bestimmten Typ durchführen, dafür wird diese Funktionalität während der Laufzeit einer Anwednung aber unbestimmt oft verwendet. Das kann am Ende aber durchaus dazu führen, das es Funktionen/Prozeduren gibt, die alle statt nur einem Wert ganze Strukturen oder verschachtelte Listen/Maps zurückliefern können.

Ich denke genau wegen dieser Entwicklung ist die Objektorientierung heutzutage nicht mehr wegzudenken. OOP ist zwar nicht mein Fall. Aber ich betreibe programmieren sowieso nur als Hobby. Da kann ich meine Bastelprojekte auch so umsetzen, wie ich es möchte bzw. für richtig halte 

Aber als Tabuthema würde ich persönlich Funktionen mit mehreren Rückgabewerten nicht ansehen.


----------



## XPrototypeX (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*

Gerade bei OOP gibt es immer mehr recht radikale Meinungen. Z.B wird Vererbung ziemlich stark kritisiert (viele neueren Sprachen haben dieses Konzept auch gar nicht mehr, oder wenn nur sehr bedingt). 

Funktionale Sprachen sind sehr stark im kommen, da Probleme (wie es oft in OO) Sprachen üblich ist, nicht in tausend Einzelteile gesplittet werden, sondern wenn Möglich direkt in einer Funktion gelöst werden.   Entwickler können so ohne viel Code, viel Lösen was aber auch gleichzeitig ein Kritikpunkt ist, da der Code im Grunde um einiges schwerer Wartbar ist. 

In Java finde ich den funktionalen Teil seit jdk 8 recht elegant gelöst.


----------



## Ap0ll0XT (27. April 2015)

*AW: C/C++ zwei Werte zurückliefern*



XPrototypeX schrieb:


> Gerade bei OOP gibt es immer mehr recht radikale Meinungen.


Ich finde es gibt in der Programmierung allgemein sehr viele radikale Meinungen. Eine Zeit lang durfte man nirgends mit prozeduraler/funktionaler Programmierung kommen. Man ist direkt in der Luft zerrissen worden. Eine Mischform aus OOP und funktionaler/prozeduraler Programmierung ging garnicht, was gerade bei Hilfsfunktionen in PHP bei vielen für Unmut sorgen. Wenn ich Datensätze aus einer Datenbank hole, dann finde ich es nicht so prickelnd, wenn die Strukturierung der Daten in jedem Objekt im gleichen Schema implementiert wird und somit für eine unnötige Redundanz sorgt. Statische Klassen waren das Ergebnis. Dann hätte man sich das auch sparen können. 

Aber interessant zu sehen, das der Trend wieder zu den alten Tugenden geht. Und was die Wartbarkeit angeht. Wie gut der Code strukturiert und designed ist, hängt ja immernoch vom Programmierer ab


----------

