www.mikrocontroller.net

Forum: Compiler & IDEs Funktion gibt Parameter falsch zurück


Autor: Tobias Mueller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo allerseits!

Ich habe folgende Funktion die 2 Werte etwas manipulieren soll:

void calc_sth11(float *p_humidity, float *p_temperature) {
        const float C1=-4.0;
        const float C2=0.0405;
        const float C3=0.0000028;
        const float T1=0.01;
        const float T2=0.00008;

        float rh=*p_humidity;
        float t=*p_temperature;
        float rh_lin;
        float rh_true;
        float t_C;

        t_C=t*0.01 - 40;

        // DEBUG Ausgabe
        char* buf;
        buf = (char*)malloc(21);
        sprintf(buf,"-%5.1f-",t_C);
        lcd_puts(buf);
        free(buf);
        // DEBUG ende

        rh_lin = C3*rh*rh + C2*rh +C1;
        rh_true = (t_C-25)*(T1+T2*rh)+rh_lin;
        if (rh_true>100) rh_true = 100;
        if (rh_true<0.1) rh_true = 0.1,

        *p_temperature = t_C;
        *p_humidity = rh_true;

        }

Wenn ich die Funktion wie folgt aufrufe:

    float humi;
    float temp;
    uint16_t humi_vali, temp_vali;
    ...
    lcd_clrscr();
    humi=0.0;
    temp=0.0;
    calc_sth11(&humi,&temp,humi_vali,temp_vali);
    sprintf(buf,"t:%5.1fC h:%5.1f%%",temp,humi);
    lcd_puts(buf);


steht auf dem Display "t: 0.0C h: 52.6%", wobei er bei t immer den
Wert von temp aus gibt der gesetzt wird. Die calc_sth11-Funktion ändern
ihn also nicht :/
Allerdings gibt der Debug in der Mitte die richtigen 26.5C aus.

Ich kann mir dieses Verhalten nicht erklären und hoffe ihr habt ein
paar Ideen/Tipps.

Grüße
  Tobias

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum übergibst du an deine Funktion vier Argumente, obwohl sie nur zwei
Parameter hat?

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ist die Funktion definiert:
  void calc_sth11(float *p_humidity, float *p_temperature)

Und so wird sie aufgerufen:
  calc_sth11(&humi,&temp,humi_vali,temp_vali);

Und der Compiler jammert nicht wegen unterschiedlicher
Parameteranzahl?

Gruß, Stefan

Autor: Tobias Mueller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aaarg, das war die alte Version... Habs zu Testzwecken auf 4 Parameter
erweitert:

void calc_sth11(float *p_humidity, float *p_temperature, int humi_org,
int temp_org) {
    const float C1=-4.0;
    const float C2=0.0405;
    const float C3=0.0000028;
    const float T1=0.01;
    const float T2=0.00008;

    float rh=humi_org;
    float t=temp_org;
    float rh_lin;
    float rh_true;
    float t_C;

    t_C=t*0.01 - 40;

    char* buf;
    buf = (char*)malloc(21);
    sprintf(buf,"-%5.1f-",t_C);
    lcd_puts(buf);
    free(buf);

    rh_lin = C3*rh*rh + C2*rh +C1;
    rh_true = (t_C-25)*(T1+T2*rh)+rh_lin;
    if (rh_true>100) rh_true = 100;
    if (rh_true<0.1) rh_true = 0.1,

    *p_temperature = t_C;
    *p_humidity = rh_true;

    }

Grüße
  Tobias

Autor: Roland Schmidt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rh_lin = C3*rh*rh + C2*rh +C1;
    rh_true = (t_C-25)*(T1+T2*rh)+rh_lin;
    if (rh_true>100) rh_true = 100;
    if (rh_true<0.1) rh_true = 0.1,  <-- Komma durch Semikolon
ersetzen

    *p_temperature = t_C;
    *p_humidity = rh_true;

Autor: Tobias Mueller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daaaaaanke! Es funktioniert!

Ich hab 3 Stunden gesucht und nix gefunden und der Compiler hat auch
nicht gemeckert... :/

Grüße

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"und der Compiler hat auch nicht gemeckert"

Darf er auch gar nicht, das ist gültige Syntax.

Ist ein schönes Beispiel, warum man bei if-Anweisungen besser
geschweifte Klammern verwenden sollte, dann hätte er nämlich
gemeckert.


Peter

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ist ein schönes Beispiel, warum man bei if-Anweisungen besser
> geschweifte Klammern verwenden sollte, dann hätte er nämlich
> gemeckert.

Nicht wirklich. Das hätte genausogut auch irgendwo anders passieren
können, wo kein if davorsteht.

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Das hätte genausogut auch irgendwo anders passieren
können, wo kein if davorsteht."


Dann hätte es aber nicht geschadet, auch Anweisungen, die durch Komma
getrennt sind, werden nacheinander ausgeführt.

Der Fehler trat ja erst dadurch auf, daß if und Konsorten alles bis zum
nächsten ";" bedingt ausführen oder bis zur "}".

Es wurde also auch die dem "," folgende Anweisung im False-Fall nicht
ausgeführt.


Beliebte Fehlerfalle ist auch, nach dem if ein Macro auszuführen,
welches ein ";" enthält und nicht geklammert ist.
Das ergibt dann den umgekehrten Effekt, es wird im False-Fall zuviel
ausgeführt, statt zuwenig.


Peter

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Beliebte Fehlerfalle ist auch, nach dem if ein Macro auszuführen,
> welches ein ";" enthält und nicht geklammert ist.
> Das ergibt dann den umgekehrten Effekt, es wird im False-Fall zuviel
> ausgeführt, statt zuwenig.

Prust ... dagegen ist der Komma-statt-Semikolon-Fehler richtig einfach
zu finden ...

Ich habe mir auch angewöhnt, grundsätzlich  JEDE Schleife/Verzweigung
zu klammern. Spart mir unterm Strich wesentlich mehr Zeit als das
Weglassen.

Gruß, Stefan

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Beliebte Fehlerfalle ist auch, nach dem if ein Macro auszuführen,
>> welches ein ";" enthält und nicht geklammert ist.
>> Das ergibt dann den umgekehrten Effekt, es wird im False-Fall
>> zuviel ausgeführt, statt zuwenig.
>
> Prust ... dagegen ist der Komma-statt-Semikolon-Fehler richtig
> einfach zu finden ...

Deshalb umschließt man zweckmäßigerweise den Code im Makro mit einem

    do {...} while(0)

oder verzichtet (nicht nur aus diesem Grund) wenn möglich zugunsten von
Inline-Funktionen gleich auf Makros, was allerdings in C++ leichter ist
als in C.

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.