PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : zwei Rückgabewerte einer Funktion?!



Janiiix3
20.09.2014, 14:49
Hallo Freunde,

"Leider" warnt mich der Compiler, dass er kein "return" Statement findet. Jedoch klappt das jetzt auch so, wie es im Code steht.
Wie löst man solch ein Problem? Wie gebe ich zwei verschiedene "Rückgabewerte" zurück?

vielen dank schonmal :-)




uint16_t read_Drucksensor(uint8_t Druck_Temperatur)
{
uint16_t Druck_Byte_High = 0;
uint8_t Druck_Byte_Low = 0;
uint16_t Temperatur_Byte_High = 0;
uint8_t Temperatur_Byte_Low = 0;
int16_t Druck = 0;
int16_t Temperatur = 0;
long Druck_Byte_High_Low = 0;
long Temperatur_Byte_High_Low = 0;

sei();
i2c_rep_start(0x50+I2C_READ);
Druck_Byte_High = i2c_readAck();
Druck_Byte_Low = i2c_readAck();
Temperatur_Byte_High = i2c_readAck();
Temperatur_Byte_Low = i2c_readNak();
i2c_stop();

if (Druck_Temperatur == 0)
{
Druck_Byte_High = Druck_Byte_High & 0b00111111;
Druck_Byte_High = Druck_Byte_High << 8;
Druck_Byte_High_Low = Druck_Byte_Low | Druck_Byte_High;
Druck = ((Druck_Byte_High_Low - 1638) * 100 / (14745 - 1638) ) ;
return (Druck);
}



if (Druck_Temperatur == 1)
{
Temperatur_Byte_Low = Temperatur_Byte_Low >> 5;
Temperatur_Byte_High_Low = Temperatur_Byte_High << 3 | Temperatur_Byte_Low;
Temperatur = (((Temperatur_Byte_High_Low * 2000) / 2047) - 562 );
return (Temperatur);
}



}

askazo
20.09.2014, 15:10
Der Compiler meckert, weil er nicht für alle möglichen Fälle ein return-Statement findet.
Für Druck_Temperatur == 0 und Druck_Temperatur == 1 ist ein return-Wert definiert.
Aber was soll die Funktion zurückgeben, wenn Druck_Temperatur == 2 ist?
Auch wenn dieser Fall bei Dir nicht vorkommen wird - der Compiler weiß das nicht und sieht einen Fehler.

Beheben kannst Du das so


if (Druck_Temperatur == 0)
{

...

return Druck;
}

else if (Druck_Temperatur == 1)
{

...
return Temperatur;

}

else
{

return 0;

}


Gruß,
askazo

Janiiix3
20.09.2014, 15:48
Okay, dass scheint zu klappen. Danke !

Was mache ich denn falsch, wenn ich mein Array nicht zurück kann ?
Ich möchte gerne "Uhrzeit" an die Funktion zurück geben...



uint16_t TimeToString(uint8_t Stunden, uint8_t Minuten, uint8_t Sekunden)
{
char Uhrzeit[9];

Uhrzeit[0] = (Sekunden >> 4) + 0x30;
Uhrzeit[1] = (Sekunden & 0x0f) + 0x30;
Uhrzeit[2] = ':';
Uhrzeit[3] = (Minuten >> 4) + 0x30;
Uhrzeit[4] = (Minuten & 0x0f) + 0x30;
Uhrzeit[5] = ':';
Uhrzeit[6] = (Stunden >> 4) + 0x30;
Uhrzeit[7] = (Stunden & 0x0f) + 0x30;
Uhrzeit[8] = '\0';

return(Uhrzeit);

}// Ende TimeToString

askazo
20.09.2014, 16:38
Du kannst in C ein Array nicht direkt als Rückgabewert einer Funktion verwenden.
Die gängige Lösung ist eigentlich, einen Zeiger auf das Array zurückzugeben.
Dafür solltest Du Dich aber mit Zeigern auskennen.

Allerdings stellt Dir die C-Bibliothek schon eine Funktion zur Verfügung, die genau das kann, was Du mit dieser Funktion machen möchtest...



#include <stdio.h>

uint8_t Stunden;
uint8_t Minuten;
uint8_t Sekunden;

char Uhrzeit[9];

// Hier kommt die Berechnung der Uhrzeit hin
...

printf(Uhrzeit,"%02u:%02u:%02u",Stunden,Minuten,Sekunden);


Siehe auch http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_Nutzung_von_sprintf_und_printf
und http://home.htw-berlin.de/~junghans/cref/FUNCTIONS/format.html (http://home.htw-berlin.de/~junghans/cref/FUNCTIONS/format.html)

Gruß,
askazo

Peter(TOO)
20.09.2014, 17:27
Hallo,

Was mache ich denn falsch, wenn ich mein Array nicht zurück kann ?
Ich möchte gerne "Uhrzeit" an die Funktion zurück geben...


Wie schon gesagt, musst du einen Zeger zurück geben.

Aber du hast noch zwei ganz grobe Fehler!




uint16_t TimeToString(uint8_t Stunden, uint8_t Minuten, uint8_t Sekunden)
{
char Uhrzeit[9];

Uhrzeit[0] = (Sekunden >> 4) + 0x30;
Uhrzeit[1] = (Sekunden & 0x0f) + 0x30;
Uhrzeit[2] = ':';
Uhrzeit[3] = (Minuten >> 4) + 0x30;
Uhrzeit[4] = (Minuten & 0x0f) + 0x30;
Uhrzeit[5] = ':';
Uhrzeit[6] = (Stunden >> 4) + 0x30;
Uhrzeit[7] = (Stunden & 0x0f) + 0x30;
Uhrzeit[8] = '\0';

return(Uhrzeit);

}// Ende TimeToString


1.
char Uhrzeit[9];
Ist eine lokale Auto-Variable!

Beim Aufruf von TimeToString() wird diese auf dem Stack angelegt und nach verlassen von TimeToString() wird der Speicher wieder freigeben!
Wenn du nun eine andere Funktion aufrufst oder eine Interruptroutine ausgeführt wird, werden die Werte überschrieben und due hast nur noch Datensalat.
Also übe mal, wie man eine gute Salatsauce macht :-)

Wenn du
static char Uhrzeit[9];
verwendest, umgehst du dieses Problem, dann wird Uhrzeit im allgemeinen Speicher angelegt.
Allerdings ändert jeder Aufruf von TimeToString() den Inhalt von Uhrzeit.


2. der Rückgabewert von TimeToString() ist nicht mehr
uint16_t
sondern
char *TimeToString(uint8_t Stunden, uint8_t Minuten, uint8_t Sekunden)

MfG Peter(TOO)

schorsch_76
20.09.2014, 19:12
Du kannst das auch in ein struct packen und dann dieses strukt zurück geben.



struct Uhrzeit {
char sec;
char min;
char hour;
char day;
char month;
char year;
};

...

Uhrzeit MyFunction()
{
Uhrzeit ret;
ret.min = ...;
ret.sec = ...;

...
return ret;
}


Gruß
Georg

Peter(TOO)
20.09.2014, 19:48
Hallo Georg,

Du hast jetzt aber immer noch den Fehler mit der auto Variablem.
Nach return wird der Speicher freigegeben!!

MfG Peter(TOO)

schorsch_76
20.09.2014, 20:21
Nein, denn es wird by value übergeben und nicht by reference.

EDIT:
Link
http://courses.washington.edu/css342/zander/css332/passby.html
http://de.wikipedia.org/wiki/Wertparameter

- - - Aktualisiert - - -

Ja, der Speicher wird freigegeben, aber es wird eine tiefe Kopie gemacht für den Aufrufer. Wenn ich

return &ret;

mache, dann habe ich ein Problem mit diesem Speicher.