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


von Tobias Mueller (Gast)


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

von Rolf Magnus (Gast)


Lesenswert?

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

von Stefan Kleinwort (Gast)


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

von Tobias Mueller (Gast)


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

von Roland Schmidt (Gast)


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;

von Tobias Mueller (Gast)


Lesenswert?

Daaaaaanke! Es funktioniert!

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

Grüße

von Peter D. (peda)


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

von Rolf Magnus (Gast)


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.

von Peter Dannegger (Gast)


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

von Stefan Kleinwort (Gast)


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

von Rolf Magnus (Gast)


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.

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.