Forum: Mikrocontroller und Digitale Elektronik PIC Speicherung von Variablen


von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Hi,
könnt ihr mir folgendes Phänomen erklären?
1
int main(void)
2
{
3
     while (1)
4
    {
5
        set_fixValues();
6
}
7
8
9
void set_fixValues(void)
10
{
11
    
12
    uint8_t r,g,b = 0;
13
//    uint8_t g = 0;
14
//    uint8_t b = 0;
15
r++;
16
g++;
17
b++;
18
...
19
}

Den obiigen Code debugge ich gerade und erhalte immer größer werdende 
Werte für r und g.
Dabei dachte ich es läuft ganz normal nach den "Call by Value" Prinzip 
und sobald die Funktion beendet wurde sind die Variablen futsch?
An der Stelle von "..." werden r,g und b weiter verwendet und ich hatte 
eigentlich Werte wie r=1; erwartet. Die Lösung des Problems habe ich ja 
bereits in den Kommentar geschrieben.

Doch ich würde das ganze auch gerne verstehen ;)

Grüße Oekel

von Klaus (Gast)


Lesenswert?

D a v i d K. schrieb:
> Den obiigen Code debugge ich gerade und erhalte immer größer werdende
> Werte für r und g.

Nein, zufällige Werte, da sie nicht initialisiert sind.

MfG Klaus

von Teo D. (teoderix)


Lesenswert?

D a v i d K. schrieb:
> uint8_t r,g,b = 0;

Mach da mal ein = statt der Kommas.

von Ingo (Gast)


Lesenswert?

Du initialisierst nur b! r und g bleiben uninitialisiert.

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Teo Derix schrieb:
> D a v i d K. schrieb:
>> uint8_t r,g,b = 0;
>
> Mach da mal ein = statt der Kommas.

ok Danke!
uint8_t r= g= b= 0; (Hätte ich drauf stoßen müssen)

Trotzdem wüsste ich gerne ob dann mit diesem Zufallswert gerechnet wird.
Und woher kommt dieser?

Also angenommen ich möchte einen Zufallswert dort haben, erhalte ich 
dann mit jedem Aufruf einen neuen, oder ist dieser dann sozusagen 
konstannt seit dem Zeitpunkt an dem es compiliert/geflasht wurde?

Grüße Oekel

von holger (Gast)


Lesenswert?

>Also angenommen ich möchte einen Zufallswert dort haben, erhalte ich
>dann mit jedem Aufruf einen neuen, oder ist dieser dann sozusagen
>konstannt seit dem Zeitpunkt an dem es compiliert/geflasht wurde?

Kann beides bei rauskommen. Das Verhalten ist komplett undefiniert.
Lässt sich also nicht für Vermutungen nutzen.

von Karl H. (kbuchegg)


Lesenswert?

D a v i d K. schrieb:

> Trotzdem wüsste ich gerne ob dann mit diesem Zufallswert gerechnet wird.

Es sind keine Zufallswerte in dem Sinne, dass du damit rechnen kannst, 
dass sie statistische EIgenschaften von Zufallszahlen haben.

> Und woher kommt dieser?

Der Speicher, an dem diese Variablen beim Betreten der Funktion erzeugt 
werden, existiert ja unabhängig von den Variablen auch vorher schon. Die 
Speicherzellen kristallisieren ja nicht aus der Luft heraus um dann 
Variablenwerte aufzunehmen. Was auch immer dieser Speicher für einen 
Inhalt hat, eine uninitialisierte Variable 'erbt' ihn. Die Bits sind nun 
mal entweder 0 oder 1.
Und ja. In deinem Programm ist es gar nicht so unwahrscheinlich, dass 
die Variablen r und g beim erneuten Betreten der Funktion wieder an der 
gleichen Stelle im Speicher erzeugt werden, an der sie auch lagen, als 
die Funktion das letzte mal lief. Da in deinem main() dazwischen nichts 
passiert ist, 'erben' sie damit ihre letzten Werte wieder. Aber: Das ist 
nichts womit du rechnen kannst. Machst du im main() etwas, rufst du dort 
andere Funktionen auf, dann wird genau dieser Speicher unter Umständen 
in dieser Funktion für andere Variablen verwendet und damit hat dieser 
Speicher dann andere Inhalte beim erneuten Aufruf deiner Funktion.


> Also angenommen ich möchte einen Zufallswert dort haben, erhalte ich
> dann mit jedem Aufruf einen neuen, oder ist dieser dann sozusagen
> konstannt seit dem Zeitpunkt an dem es compiliert/geflasht wurde?

Vergiss den Begriff 'Zufall' hier gleich wieder.
Das hat nichts mit Zufallszahlen zu tun.
Es ist eher so, wie wenn du in eine neue Wohnung einziehst und das 
Postkästchen erbst. Was immer der Vormieter dir da drinn hinterlassen 
hat, findet sich darin, wenn du es zum ersten mal öffnest. Aber das ist 
nichts, womit du fix rechnen kannst. Uninitialsiert ist uninitialisiert. 
Irgendein Wert, von dem nicht festgelegt ist, wie er entsteht.

von Michael (Gast)


Lesenswert?

D a v i d K. schrieb:
> uint8_t r= g= b= 0; (Hätte ich drauf stoßen müssen)

Bitte nicht :-D Das ist ultrahässlich programmiert. Du hast zwar Recht, 
es geht so. Die Auflösung erfolgt von rechts nach links. Das ist aber so 
ein NoGo wie ein Goto oder sowas. Die Programmiererehre verbietet das 
fast schon. Ein ungeschriebenes Gesetz der Programmiersprachen.
1
uint8_t r=0;
2
uint8_t g=0;
3
uint8_t v=0;
4
// oder eben auch
5
uint8_t r=0, g=0, b=0;

D a v i d K. schrieb:
> Trotzdem wüsste ich gerne ob dann mit diesem Zufallswert gerechnet wird.
> Und woher kommt dieser?

Das Verhalten ist völlig undefiniert. Es kann sein, dass sich der 
Compiler diese Speicherzelle zwischendurch mal für Bitshifting ausleiht, 
Zwischenergebnisse speichert oder du diese Zelle zufällig nutzt und 
veränderst, sie dann aber wieder freigibst bevor der nächste 
Funktionsaufruf kommt, etc. Da ist alles möglich, nichts vorherzusagen. 
Kommt darauf an wie du programmierst, wie dynamisch du programmierst, 
wie dein Compiler optimiert, ob du debuggst oder releast, und und und. 
Eine switch case Entscheidung anderst und du es ist wieder alles ganz 
anderst :-D

von Fallobst (Gast)


Lesenswert?

Michael schrieb:
> Die Programmiererehre verbietet das
> fast schon. Ein ungeschriebenes Gesetz der Programmiersprachen.

Was kurz, knapp und übersichtlich ist, verbessert die Leserlichkeit des 
Codes. Deine "Regeln" fallen da eher unter Geschmack.

von kopfkratzer (Gast)


Lesenswert?

Wie war das noch ...
"shoot yourself in the foot"
in c:
1
"shoot yourself in the foot"
in Pascal:
"The compiler wont let you shoot in your foot"
Frei nach:
http://www.toodarkpark.org/computers/humor/shoot-self-in-foot.html
Wobei bei EIFFEL noch die Variante und Invariante fehlt :-P

P.S.: Variablen in einzelnen Zeilen ist immer übersichtlicher und der 
Compiler erledigt schon eventuelle Optimierungen ;-)

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.