Forum: Mikrocontroller und Digitale Elektronik Variable i oft aufgerufener Funktion nur ein mal initialisieren


von Andi (Gast)


Lesenswert?

Ich stehe gerade mit einem einfachen Problem auf dem Schlauch, selbst du 
Suche spuckt keine Infos aus

void check_switch(void)
{
  uint8_t und

  uint8_t state_old;
  uint8_t state_new=0;

  state_old = state_new;
  state_new = PINC;

  und = state_old & state_new;

/* und so weiter */
}

Wenn ich die Funktion jetzt aufrufe, wird doch jedes mal state_old neu 
deklariert bzw. noch viel schlimmer state_new mit 0 initialisiert.

Gibt es da ein passendes Schlüsselwort oder kümmert sich der Compiler 
darum. Hätte jetzt auf static getippt aber die Beschreibung, was static 
macht, klingt irgendwie nach was Anderem (oder falsche Beschreibung 
gelesen) ...

Danke

von rotzfrech (Gast)


Lesenswert?

static war schon richtig

von ozo (Gast)


Lesenswert?

static ist dein freund!

von Andi (Gast)


Lesenswert?

Danke schön, eine Frage hätte ich noch:

Macht es denn Sinn, jede lokale deklarierte Variable mit static zu 
versehen, d.h. bringt das Geschwindigkeitsvorteile ? Oder optimiert der 
Compiler eine reine Deklaration ohnehin dahingehend ?

von Alex B. (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite


Lesenswert?

Ich würde eher sagen es bringt Geschwindigkeits-Nachteile, da der 
(Arbeitsspeicher-) Bereich der bei der Deklaration reserviert wurde nach 
Beendigung der Funktion nicht wieder freigegeben wird (ist ja eine 
static-Variable, könnte also nochmal jemand drauf zugreifen wollen). => 
Der Arbeitsspeicher wird voller...

Aber ich bin nicht so der Experte auf dem Gebiet.

Schöne Grüße,
Alex

von Hmm... (Gast)


Lesenswert?

'static' sorgt dafür,dass die lokale Variable nicht wie sonst üblich auf 
dem Stack (bzw. Allzweck-Register bei vielen µC's) abgelegt wird, 
sondern 'normal' im SRAM-Bereich wo auch alle globalen Variablen 
abgelegt werden. Dadurch bleibt der Inhalt auch nach Verlassen der 
Funktion (wobei deren Parameter ja vom Stack entfernt werden) erhalten. 
Nachteil ist dann, dass man die Funktion nichtmehr so einfach rekursiv 
aufrufen kann, da der Überblick über den Inhalt der Variablen nicht mehr 
ganz so leicht zu behalten ist.

Die Gültigkeit der Variablen im Programm bleibt jedoch wie gewohnt auf 
die Funktion beschränkt, in welcher Sie deklariert wurde.

von Karl H. (kbuchegg)


Lesenswert?

Andi wrote:
> Danke schön, eine Frage hätte ich noch:
>
> Macht es denn Sinn, jede lokale deklarierte Variable mit static zu
> versehen,

Nein.
static bei lokalen Funtkionen ist eher die Ausnahme.

static bei funktionslokalen Variablen benutzt man, wenn man
im Grunde aus Lebensdauergründen eine globale Variable haben möchte,
diese aber nicht öffentlich zugänglich machen will.
Eine funktionslokale static Variable wird beim ersten Aufruf der
Funtion erzeugt und initialisiert und lebt dann weiter bis zum
Ende des Programms.

von Hmm... (Gast)


Lesenswert?

Ein Beispiel ist z.B. wenn man eine State-Machine in einer Funktion 
implementieren möchte. Dann merkt sich die Funktion den aktuellen 
Zustand bis zum nächsten Aufruf in einer 'static'-Variablen.

Beispielhaft für eine UART-Empfänger Statemachine:

void uart_receiver(char c)
{
  static char ucState = 0;   /* Status des Empfängers */

  switch (ucState)
  {
     case 1:
       if (c == STX)
         ucState = 2;
       break;

    case 2:
       if ((c&0x80))
         PORTB |= (1<<(c&0xf));
       else
         PORTB &= ~(1<<(c&0xf));
       ucState = 3;
       break;

     case 3:
       if (c == ETX)
         ucState = 0;
       break;

     default:
       ucState = 0;
  }
}

von Jörg (Gast)


Lesenswert?

Static-Variablen behalten ihren Wert zwischen mehrfachen Aufrufen einer
Funktion, müssen daher ständig im Speicher gehalten werden, genau wie
globale Variablen.
NonStatic Variablen dagegen werden nach Verlassen der Funktion aus den
Speicher (genauer: Stack) entfernt, so dass der selbe Speicherplatz
Variablen anderer Funktionen dienen kann, ist also 
speicherplatzsparender.

Ausserdem ist bei vielen Prozessoren der lokale Speicherzugriff
(Zugriff auf Stack) schneller. Bei Prozessoren mit Cache wird idR der
Zugriff auf globale Daten nochmals langsamer.

Definiere also deine Zustandsvariable als static inkl. Wertezuweisung.

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.