Forum: Mikrocontroller und Digitale Elektronik Berechnung innerhalb atof() bzw. atoi()


von Daniel W. (angemon84)


Lesenswert?

ich verstehe nicht, warum sich bei (atof(cmdResponse+i)) das Komma so 
komisch nach rechts verschiebt. Also bei i =1 bis 3 kommt 11001.000000 
raus, aber bei i=4 oder 5 etwas anderes.
Ich habe dieses Konstrukt in einem Code gefunden, kann mir aber keinen 
Anwendungsfall denken.

Auch diese atoi() Variante verstehe ich nicht:
char cCheckBuf[50];
unsigned int uiSTAB_Status = atoi(cCheckBuf + 5);

Kennt ihr einen Anwendungsfall hierfür, oder was hat sich der 
Programmierer hierbei gedacht?
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main()
5
{
6
    
7
    char cmdResponse[50]= {'1','0','0','1','1','0','0','1'};
8
    printf("\n %f",atof(cmdResponse));
9
    for (int i = 0; i<=5; i++)
10
    {
11
        double dPsPress_1 = (atof(cmdResponse+i));
12
        printf("\n (atof(cmdResponse+%d)) %f",i,dPsPress_1);
13
        double dPsPress_2 = (atof(cmdResponse)+5);
14
        printf("\n (atof(cmdResponse)+5) %f",dPsPress_2);
15
        if (dPsPress_2 == dPsPress_1)
16
            printf("\n dPsPress_1 == dPsPress_2");
17
        else
18
            printf("\n dPsPress_1 != dPsPress_2");
19
    }
20
    return 0;
21
}
Ausgabe:
 10011001.000000
 (atof(cmdResponse+0)) 10011001.000000
 (atof(cmdResponse)+5) 10011006.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+1)) 11001.000000
 (atof(cmdResponse)+5) 10011006.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+2)) 11001.000000
 (atof(cmdResponse)+5) 10011006.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+3)) 11001.000000
 (atof(cmdResponse)+5) 10011006.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+4)) 1001.000000
 (atof(cmdResponse)+5) 10011006.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+5)) 1.000000
 (atof(cmdResponse)+5) 10011006.000000
 dPsPress_1 != dPsPress_2

von MaWin (Gast)


Lesenswert?

Troll ?

Troll !

von Dr. Sommer (Gast)


Lesenswert?

Daniel W. schrieb:
> atof(cmdResponse+i)

Dir ist klar, dass das den Strings von cmdResponse ab der Stelle i 
übergibt? Also mit jedem Schleifendurchlauf eine Ziffer weniger.

von Daniel W. (angemon84)


Lesenswert?

Arrrr. ICh habe den zulässigen wertebereich der Datentypen missachtet. 
An diesen Beispiel wird es deutlicher:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main()
5
{
6
    char cmdResponse[20]= {'5','4','3','2'};
7
    printf("\n %f",atof(cmdResponse));
8
    for (int i = 0; i<=5; i++)
9
    {
10
        double dPsPress_1 = (atof(cmdResponse+i));
11
        printf("\n (atof(cmdResponse+%d)) %f",i,dPsPress_1);
12
        double dPsPress_2 = (atof(cmdResponse)+5);
13
        printf("\n (atoi(cmdResponse)+5) %f",dPsPress_2);
14
        if (dPsPress_2 == dPsPress_1)
15
            printf("\n dPsPress_1 == dPsPress_2");
16
        else
17
            printf("\n dPsPress_1 != dPsPress_2");
18
    }
19
    return 0;
20
}

Ausgabe:
 (atof(cmdResponse+0)) 5432.000000
 (atoi(cmdResponse)+5) 5437.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+1)) 432.000000
 (atoi(cmdResponse)+5) 5437.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+2)) 32.000000
 (atoi(cmdResponse)+5) 5437.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+3)) 2.000000
 (atoi(cmdResponse)+5) 5437.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+4)) 0.000000
 (atoi(cmdResponse)+5) 5437.000000
 dPsPress_1 != dPsPress_2
 (atof(cmdResponse+5)) 0.000000
 (atoi(cmdResponse)+5) 5437.000000
 dPsPress_1 != dPsPress_2

Das Komma wandert um den Wert "i" nach links, aber die Absichet des 
Programmiers erschließt sich mir trotzdem nicht ganz

@Dr_Sommer
der Schleifendurchlauf ist auf meinen Mist gewachsen, damit ich erkenne, 
welche Auswirkungen die Variabele i hat. Im Ursprungscode ist keine 
Schleife drin.

: Bearbeitet durch User
von Irgendwer (Gast)


Lesenswert?

Sorry, die Frage was sich der Programmierer (in diesem Fall du) sich bei 
dem Unsinn gedacht hat kannst nur du selber beantworten.


"char cmdResponse[20]= {'5','4','3','2'};"
Ist kein gültiger C-String, da fehlt die abschließende Null.

"cmdResponse+i"
"cmdResponse" ist am ende nur ein Pointer den du um "i" erhöhst und 
verändert in keinster Weise den Speicher worauf diese Zeigt.

Das ganze hat aber rein garnichts mit atof oder atoi oder irgendwelchen
"zulässigen wertebereich der Datentypen".
Das sind grundlegendste Basics in C an denen es dir hier anscheinend 
mangelt.

von Kaj (Gast)


Lesenswert?

Daniel W. schrieb:
> Das Komma wandert um den Wert "i" nach links
Nein, tut es nicht, was durch die Ausgabe offensichtlich wird.
1
(atof(cmdResponse+0)) 5432.000000
2
(atof(cmdResponse+1)) 432.000000
Wo ist da jetzt das Komma nach links gewandert? Wenn das der Fall 
waere, dann wuerde da stehen:
1
(atof(cmdResponse+0)) 5432.000000
2
(atof(cmdResponse+1)) 543.2000000

Was passiert ist:
1
(atof(cmdResponse+0)) 5432.000000
2
(atof(cmdResponse+1))  432.000000
Das Komma hat sich kein bisschen bewegt.

von Daniel W. (angemon84)


Lesenswert?

Irgendwer schrieb:
> "char cmdResponse[20]= {'5','4','3','2'};"
> Ist kein gültiger C-String, da fehlt die abschließende Null.

Auch die abschließende Null ändert an der Ausgabe nix. Das sollte nur 
mal eine willkürliche Zahlenfolge sein, da ich nicht weiss was in einem 
20 bzw 50 char-Array drinsteht.




Irgendwer schrieb:
> "cmdResponse+i"
> "cmdResponse" ist am ende nur ein Pointer den du um "i" erhöhst und
> verändert in keinster Weise den Speicher worauf diese Zeigt.

ich dividiere doch cdmRespone durch 10^i. Kannst du das mit dem Pointer 
näher spezifizieren? Gewöhnlich verwende ich Pointer mittels * oder 
Elementzugriff ->

@Kaj
ja du hast recht. Das habe ich so nicht gleich erkannt.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Daniel W. schrieb:
> Auch die abschließende Null ändert an der Ausgabe nix.

Die Null ist aber trotzdem nötig, denn sonst liest Dein atoi/atof 
solange im Speicher weiter, bis es auf eine Null (nicht das Zeichen 
'0'!) trifft.

> Kannst du das mit dem Pointer näher spezifizieren? Gewöhnlich verwende
> ich Pointer mittels * oder Elementzugriff ->

Du hast jetzt den Pointer-/Array-Dualismus kennengelernt.

C kann Funktionen keine Arrays übergeben.

Wenn Du eine Funktion mit einem Array als Parameter aufrufst, wird der 
Funktion ein Pointer auf das erste Arrayelement übergeben.

Das hat einerseits die Konsequenz, daß die Funktion nichts weiter über 
das Array weiß (und damit sizeof nicht die Größe des Arrays bestimmen 
kann), und andererseits, daß sich dieser Parameter eben /genauso wie ein 
Pointer/ verhält.

Wenn Du zu einem char-Array (das Du übrigens auch gleich mit einem 
String in "" statt einer Liste einzelner char-Konstanten in '' 
initialisieren kannst) einen Wert addierst, erhältst Du als Resultat 
einen Pointer, der auf das "erste + Wert" - Element des Arrays zeigt.

Beispiel:
1
char bla[] = "abcdefghijklmn";
2
3
char *p;
4
5
p = bla;      // p zeigt auf 'a'
6
p = bla + 2;  // p zeigt auf 'c'
7
p++;          // p zeigt auf 'd'

Wirds's klarer?

von Daniel W (Gast)


Lesenswert?

@ Rufus, danke für die Erklärung.
Rufus Τ. F. schrieb:
> einen Wert addierst, erhältst Du als Resultat
> einen Pointer, der auf das "erste + Wert" - Element des Arrays zeigt.

hier mal ein Ausschnitt aus dem Ursprungscode:
1
   char cCmdBuf[20];
2
   unsigned int uiSTAB_Status;
3
   unsigned int uiSTAT_Status;
4
5
6
   strcpy(cCmdBuf, "STAB?");
7
   iStrLen = sizeof(cCheckBuf);
8
9
   if ((iRtn = TatsBUS_QueryDevice(iDevID, cCmdBuf, cCheckBuf,
10
     /* NR-Chars*/ &iStrLen, /* RepeatCnt */ 1, /* Delay */ 0)) == NOT_OK)
11
   {
12
     PCM_Error(iDevID, __FILE__, __FUNCTION__, E_DEV_DRV_ERRMSG, EC_ERROR, "Fehler von TatsBUS_QueryDevice()");
13
   }
14
   else
15
   {   // response format: STAB<\09><dddddd>
16
     //                  01234    5
17
     uiSTAB_Status = atoi(cCheckBuf + 5);
18
     // Device Table
19
     SetPCMSendBufTxt(cCmdBuf);
20
     SetPCMReadBufTxt(cCheckBuf);
21
   }

dem Programmierer ging es also weniger darum eine Zeichenkette in ein 
Integer bzw. Float zu convertieren, sondern mehr darum einen Pointer zu 
erzeugen, der auf das "erste + Wert" - Element des Arrays zeigt?
wie darf ich das
// response format: STAB<\09><dddddd>
     //                  01234    5
verstehen?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Daniel W schrieb:
> wie darf ich das // response format: STAB<\09><dddddd>
>      //                  01234    5
> verstehen?

Das interpretiere ich so, daß auf die vier Zeichen "STAB" ein Tab (9 
oder auch '\t') und dann eine dezimale Zahl folgt.

Die dezimale Zahl fängt also im 6. Element des Zeichenarrays an.

Da das erste Element den Index 0 hat, muss man also 5 (statt 6) 
addieren.

Hier mal ein Beispiel dafür :
1
//                    0    1    2    3   4   5    6    7   8
2
char cCheckBuf[] = { 'S', 'T', 'A', 'B', 9, '1', '2', '3', 0 };

(die 9 steht nicht in Anführungszeichen, wie auch die abschließende 0 
nicht!)

cCheckBuf + 5 zeigt also auf '1', wie gewünscht.

: Bearbeitet durch User
von Daniel W (Gast)


Lesenswert?

@Rufus

vielen Dank. Ich habe auch gerade mit dem Programmierer gesprochen. Ihr 
beide sein d'Acord.
Also mit einfachen Worten erklärt sollte erst ab dem 6. Element an auf 
Integer bzw Float konvertiert werden.

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.