Hallo,
ich habe hier ein Problem, wo ich einfach nicht weiterkomme. Im Netz konnte ich bislang keine Lösung finden.
Ich habe eine Arduino-Library (LedControl) für die Ansteuerung des MAX7219-ICs für die Verwendung in C mit Microchip Studio (µC: ATmega88PA) umgeschrieben. Jetzt habe ich eine Funktion geschrieben, die Daten aus einem 2D-Array auf einer 8x8 LED-Matrix in einer Dauerschlaufe wiedergeben soll. Die Funktionsparameter sind das Zeit-Intervall , der Start und der Endpunkt der Durchlaufs. Allerdings bekomme ich beim kompilieren die Fehlermeldung "initializer element is not constant" in Bezug auf static uint8_t x = start;
Der selbe Code lässt sich in der Arduino-IDE (C++) allerdings anstandslos ausführen.
Wie kann ich der Variable x jetzt den Wert von start (in diesem Fall 0) zuweisen?
Ich habe ein potentielles Problem gefunden: was, wenn einer (aus welchen Gründen auch immer) end kleiner angibt als start? Oder start mit dem selben Wert wie end übergeben wird?
Ein paar Tipps zur brauchbaren Fehleranalyse:
Was funktioniert nicht?
Mit welchem Programm?
Was erwartest du und was passiert stattdessen?
Wie stellst du das fest?
also ohne static bleibt der zähler bei 0 stehen. was das keyword static genau macht, habe ich ehrlich gesagt noch nicht zu 100% begriffen, aber hauptsächlich benutzte ich es, um globale variablen zu vermeiden
Ich habe ein potentielles Problem gefunden: was, wenn einer (aus welchen
Gründen auch immer) end kleiner angibt als start? Oder start mit
dem selben Wert wie end übergeben wird?
was das keyword static
genau macht, habe ich ehrlich gesagt noch nicht zu 100% begriffen, aber
hauptsächlich benutzte ich es, um globale variablen zu vermeiden
Wenn du eine Variable in einer Funktion als "static" deklarierst, dann wird sie global angelegt und nicht nur temporär auf dem Stack.
Der eigentliche Sinn ist, dass man sich damit Dinge zwischen Funktionsaufrufen merken kann.
Da solche Variablen nur einmal initialisiert werden, meckert der Compiler auch, weil du in deinem Code versuchst sie jedes Mal mit dem übergebenen Wert zu initialisieren.
Nachtrag: bekanntes Beispiel für die Verwendung von statischen Variablen ist strtok() inclusive allen Nachteilen.
also ohne static bleibt der zähler bei 0 stehen. was das keyword static
genau macht, habe ich ehrlich gesagt noch nicht zu 100% begriffen, aber
hauptsächlich benutzte ich es, um globale variablen zu vermeiden
Leider der falsche Grund.
Punkt:
Eine Funktion hat sich bei gleichen Parametern immer gleich zu verhalten.
Das tut sie nicht, wenn sie statische oder globale Variablen nutzt.
Stichwort: Wiedereintrittsfähigkeit.
Gilt auch für Klassen und ihre Methoden. Dort macht es auch gerne die Vererbung kaputt.
Die Situation ist meist/immer vermeidbar.
Wiederverwendung statt Wegwerf Funktionen/Klassen/Methoden
...einen habe ich noch: die Geschichte, ob das nächste Intervall dran
ist, würde ich auch anders lösen, also so ungefähr insgesamt:
Eigentlich würde ich komplett darauf verzichten innere static Variablen zu benutzen.
Statt dessen würde ich eher eine Struktur mit allen notwendigen Zustandsvariablen deklarieren, die weiter außen (z.B. im main) definiert und initialisiert wird, und einen Zeiger auf die Struktur der Funktion mitgeben.
Statt dessen würde ich eher eine Struktur mit allen notwendigen
Zustandsvariablen deklarieren, die weiter außen (z.B. im main) definiert
und initialisiert wird, und einen Zeiger auf die Struktur der Funktion
mitgeben.
Im Grunde richtig!
Nur:
in Arduino gibts eher setup() und loop()
donnert dir das den Stackbereich voll. Also auf heap_end(?) achten.
Wir reden im konkreten Fall von einem uint8 und einem uint32.
Statisch verbraucht der genauso Platz im RAM.
Das einzige was man spart ist der Zeiger der auf dem Stack übergeben wird.
habe den code jetzt getestet und läuft perfekt . Besten Dank
Dass static einen Wert über das "Ableben" einer Funktion hinaus speichern kann, war mir schon bekannt, aber nicht, wie ich es sinnvoll einsetzen kann. Bin noch nicht allzu lange in der C-Programmierung unterwegs bzw. weiss noch nicht so genau, was unter der Haube vorsich geht, also was Wo , Wann, Wie, Warum gespeichtert wird. Stack,Heap,Pointer & Structs sind mir ein Begriff, allerdings habe ich mich damit noch nicht näher auseinandergesetzt.
Gibt´s da vielleicht ein halbwegs modernes Buch , was Ihr empfehlen könnt?
Das braucht man dann, wenn man einen Wert über das "Ableben" einer
Funktion hinaus speichern will ;)
Das wissen doch alle sogar der TO wie er selbst schreibt, es aber trotzdem benutzt obwohl er es nicht braucht und sich dann über die Fehlermeldung wundert.
Wenn du eine Variable in einer Funktion als "static" deklarierst, dann
wird sie global angelegt und nicht nur temporär auf dem Stack.
Solche Variablen sind nicht global, aber im Static Storage (anstatt Speicherklasse "automatic").
Dass sie nicht global sind erkennt man zum Beispiel auch daran, dass unterschiedliche Funktionen lokale (egal ob static oder nicht) Variablen gleichen Names haben können:
1
intfunc_count1(void)
2
{
3
staticintcount;
4
return++count;
5
}
6
7
intfunc_count2(void)
8
{
9
staticintcount;
10
return++count;
11
}
Die beiden "count" Variablen haben nichts miteinander zu tun, haben unterschiedliche Adressen, und sind außerhalb ihrer Funktionen nicht zugreifbar (es sei denn, ihre Adresse wird irgendwie verfügbar gemacht).