Forum: Compiler & IDEs Funktion - Rückgabewert


von Verständnis (Gast)


Lesenswert?

Hallo, ich habe eine Verständinsfrage zu den allgemeinen Funktionen.
Wenn ich eine Funktion generiere, die keinen Rückgabewert hat also z.B.
1
void Zahl(uint8_t nummer)
2
{
3
hallo=nummer;
4
}
5
6
int main(void)
7
{
8
uint8_t hallo=0;
9
uint8_t nummer=5;
10
while(1)
11
{
12
Zahl(nummer);
13
if(hallo==5)
14
{
15
//leuchten...
16
}
17
}
Dann habe ich doch eigentlich einen Wert zurückgegeben? Der Wert von 
"nummer" wird doch in die variable "hallo" übertragen und dann in der 
while Schleife verwendet?

Oder meint man mit Rückgabewert: wenn man die Funktion z.B. :
1
uint8_t Zahl(uint8_t nummer)
2
{
3
return(nummer);
4
}
 so schreibt, dass dies gleichbedeutend ist wie:

hallo=Zahl(nummer);

Also die ganze Schreibweise der Funktion durch den RETURN wert ersetzt 
wird?

Hoffentlich versteht man was ich meine :/ und sry falls das eine dumme 
frage ist

: Verschoben durch User
von step by step (Gast)


Lesenswert?

Lass das mal von einem Compiler über setzen. Wenn es fehlerfrei ist, 
poster du es wieder hier und wir sprechen über Rückgabewerte. Jetzt gibt 
es noch ganz andere Baustellen.

von Verständnis (Gast)


Lesenswert?

ok hab es mal versucht und wenn es so aussieht:
1
#include <avr/io.h>
2
3
uint8_t hallo=0;
4
uint8_t nummer=5;
5
6
void Zahl(uint8_t nummer)
7
{
8
  hallo=nummer;
9
}
10
11
int main(void)
12
{
13
  while(1)
14
  {
15
    Zahl(nummer);
16
    if(hallo==5)
17
    {
18
    //leuchten...
19
    }
20
  }
21
}
bringt er keine Fehlermeldung mehr

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Jetzt ist hallo auch eine globale Variable. Du kannst von jeder Funktion 
darauf zugreifen.

nummer ist auch global. In der Funktion Zahl wird sie jedoch von der 
lokalen Variable nummer verdeckt.

Du hast keinen Wert zurückgegeben sondern die Variable direkt verändert.

Du hast Glück, dass du hier im Mikrocontroller und Digitale Elektronik 
Forum bist, sonst müsste ich fürchterlich über globale Variablen 
schimpfen :-)

von Verständnis (Gast)


Lesenswert?

puh dann bin ich froh :D :).

noch zu dem was ich anfangs gefragt hab mit dem:
1
uint8_t Zahl(uint8_t nummer)
2
{
3
    return(nummer);
4
}
ist dies gleichbedeutend wie:
1
hallo=Zahl(nummer);
Also die ganze Schreibweise der Funktion durch den RETURN wert ersetzt
wird?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Verständnis schrieb:
> puh dann bin ich froh :D :).
>
> noch zu dem was ich anfangs gefragt hab mit dem:
>
> uint8_t Zahl(uint8_t nummer)
> {
>     return(nummer);
> }

jetzt hast du einen Rückgabewert. Genau so ist die Sache mit 
'Rückgabewert' gemeint.

Die Funktion errechnet einen Wert und 'schleust' den mittels 'return' 
aus der Funktion heraus.

Der AUfruf kann mit diesem Wert machen was er will. Er kann ihn zb. 
einer Variablen zuweisen, oder er kann ihn in einem Ausdruck für eine 
Berechnung einsetzen, er kann ihn ....
Er kann damit alles tun, was er auch mit irgendeinem anderen WErt tun 
kann.

PS:
'return' ist KEIN Funktionsaufruf. EBensowenig fordert die Syntax, dass 
der AUsdruck beim return in Klammern eingeschlossen wird. Ein
1
  return nummer;
ist völlig in Ordnung. Das muss nicht geklammert werden.
Oder schreibst du auch
1
   i = (j);
klammerst also den rechten Teil einer Zuweisung ein, nur weil da ein 
beliebiger arithmetischer Ausdruck stehen kann?

: Bearbeitet durch User
von Verständnis (Gast)


Lesenswert?

ok vielen Dank!! :) fand die Ausdrucksweise nur verwirrend, weil ich das 
Ding theoretisch nicht brauche wenn ich immer variabeln verwende. Aber 
ist sehr geschickt :).

von Verständnis (Gast)


Lesenswert?

das mit den Klammern hab ich auf einer Seite gesehen:


float zylinder_oberflaeche(float h, float r)

{

  float o;

  o=2*3.141*r*(r+h);

  return(o);

}

deswegen dachte ich :/

von Karl H. (kbuchegg)


Lesenswert?

Verständnis schrieb:

> ist dies gleichbedeutend wie:
>
1
> hallo=Zahl(nummer);
2
>
> Also die ganze Schreibweise der Funktion durch den RETURN wert ersetzt
> wird?

Ich bin mit deiner Formulierung nicht glücklich.
Da wird nichts ersetzt.

In
1
  hallo = 3 * Zahl( 5 );

ist die Reihnfolge der Eregnisse:
die rechte Seite der Zuweisung wird ausgewertet
Teil dieser Auswertung besteht darin, dass da ein Funktionsaufruf 
vorkommt.

-> daher: die Funktion wir daufgerufen.
  Während des Funktionsaufrufs, wird der Parameter 5 an die 
Argumentvariable nummer innerhalb der Funktion gebunden
1
uint8_t Zahl(uint8_t nummer)
2
{
3
  return 2*nummer;
4
}
während die Funktion also läuft, existiert innerhalb der Funktion eine 
Variable namens 'nummer', die durch den Aufruf den Wert 5 erhalten hat.
Die Funktion macht nicht viel: sie liefert einfach nur den doppelten 
Wert von nummer zurück. nummer, das war der WErt 5, die Funktion liefert 
daher den Wert 10 zurück.
Damit ist die Funktion beendet und es geht wieder zurück zum Aufrufer
1
  hallo = 3 * Zahl( 5 );
die Funktionsabarbeitung ist abgeschlossen, die Funktion hat den Wert 10 
geliefert. Dieser Wert wird noch mit 3 multipliziert, ergibt somit 30 
und damit steht das Endergebnis der rechten Seite der Zuweisung fest und 
kann an die Variable hallo zugewiesen werden.
'hallo' hat also nach Abarbeitung dieser Anweisung den WErt 30.

von San L. (zwillingsfreunde)


Lesenswert?

Also, das ganze hier scheint zwar geklärt zu sein, trotzdem:
Entweder verstehe ich dein Problem nicht, dann sorry für die 
Nachfolgende Bemerkung, oder du verstehst den Untershcied zwischen 
Globalen und lokalen Variablen nicht.

http://home.htw-berlin.de/~junghans/cref/SYNTAX/glo_int_vars.html

Kann da helfen. Falls du diese verstehst, ists mein Fehler, dann kapier 
ich nicht was deine Frage war, spielt ja aber auch keine Rolle mehr, 
scheint ja beantwortet zu sein. Ging mir nur drum, dir eventuell noch 
weiterzuhelfen.

Gruss

von Karl H. (kbuchegg)


Lesenswert?

Verständnis schrieb:
> das mit den Klammern hab ich auf einer Seite gesehen:

Ja ich weiss.
Viele Leute schreiben das so. Wohl weil Kernighan&Ritchie ihre eigene 
erfundene Syntax nicht kannten und in ihrem Lehrbuch es so gemacht 
haben.

Das Argument bleibt aber.
Wer bei
1
   i = (j);
die Klammern weglässt, hat keinen guten Grund, warum er sie bei
1
  return (j);
schreiben sollte. Zumal sie auch keinerlei Klarheit bringen.
Klammern an dieser Stelle: genau gleich wie bei der rechten Seite einer 
Zuweisung - wenn sie den Ausdruck klarer machen, gerne. Ansonsten 
weglassen.

von Karl H. (kbuchegg)


Lesenswert?

Verständnis schrieb:
> ok vielen Dank!! :) fand die Ausdrucksweise nur verwirrend, weil ich das
> Ding theoretisch nicht brauche

Da wir hier im µC Forum sind, sei dir das verziehen.
In einem realen Programm, mit 200tausend Lines of Code und 600 
Funktionen ist das nicht nur theoretisch sondern auch ganz praktisch 
eine Frage der Codewartung. Denn mit 4000 globalen Variablen verlierst 
du den Überblick, welche Variable wann von welcher Funktion verändert 
wird. Überhaupt dann, wenn Funktionen wiederrum Funktionen aufrufen, die 
Funktionen aufrufen, welche wieder Funktionen aufrufen.

Wie froh bin ich da dann über eine Funktion
1
uint16_t interpolate( uint16_t minimum, uint16_t maximum, uint8_t percent )
2
{
3
  return minimum + percent * (maximum - minimum ) / 100;
4
}

die ich an 2 verschiedenen STellen einsetzen kann
1
int main()
2
{
3
....
4
5
  helligkeit = interpolate( 10,  80, adc_read(0) );
6
  kontrast   = interpolate(  0, 189, adc_read(1) );
ohne mich darum kümmern zu müssen, welche globalen Variablen die 
Funktion 'interpolate' möglicherweise verändert.

: Bearbeitet durch User
von Verständnis (Gast)


Lesenswert?

genau so hab ich es verstanden Karl Heinz. Hab mich echt schlecht 
ausgedrückt :/ aber du hast es so geschrieben wie ich es meinte =).
San Lue: mein Problem war zu trivial um es nachvollziehen zu können :D
danke für die investierte Zeit

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.