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?
hier der Code:
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?
Abhilfe: ich würde da einfach auf *>=* vergleichen.
> C++ ist halt nicht C.>> Lösen lässt sich das allerdings relativ einfach: static uint8_t x;> x = start;>> Warum x überhaupt static sind muß, darfst du mit dir selber diskutieren.
static , da ich die variable nur in der funktion gültig sein soll (nicht
global)
x = start funktioniert leider nicht
Hendrik schrieb:> x = start funktioniert leider nicht
Dann ist der Compiler kaputt.
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?>> Abhilfe: ich würde da einfach auf *>=* vergleichen.
danke! werde ich berücksichtigen
Hendrik schrieb:> static , da ich die variable nur in der funktion gültig sein soll (nicht> global)
Pure Bequemlichkeit!
Hendrik schrieb:> x = start funktioniert leider nicht
Da fehlt das Semikolon!
Hendrik schrieb:> 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
Es ist aber genau umgekehrt
https://stackoverflow.com/questions/5033627/static-variable-inside-of-a-function-in-c
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.
Hendrik schrieb:> 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
danke erstmal an alle für die Lösungsvorschläge.
Uwe B. schrieb:> wie wäre es mit dieser abgeänderten Funktion (ohne sie jetzt durch einen> Compiler gejagt zu haben):
ich werde den Code nacher ausprobieren . vielen dank schonmal
Uwe B. schrieb:> if ((previous_ms + interval) <= millis())
Das klassische Überlaufproblem. Es muss unbedingt so heißen:
if (millis() - previous_ms >= interval)
Nur dann rechnet sich mit der Unsigned Integer Arithmetik das
Überlaufproblem automatisch heraus.
Uwe B. schrieb:> ...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.
Udo S. schrieb:> 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:
1. in Arduino gibts eher setup() und loop()
2. donnert dir das den Stackbereich voll. Also auf heap_end(?) achten.
Arduino F. schrieb:> . in Arduino gibts eher setup() und loop()
stimmt
Arduino F. schrieb:> donnert dir das den Stackbereich voll.
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.
Udo S. schrieb:> Wir reden im konkreten Fall von einem uint8 und einem uint32.
Die Begründung des TO liest sich so, als wird static aus Prinzip
verwendet.
Dabei gilt:
> Wer mal kapiert hat, wie ein Hammer funktioniert,> für den sieht die ganze Welt plötzlich wie ein Nagel aus.
>
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?
Oliver S. schrieb:> Hier gehts tatsächlich um C.
Du hast wahr.
Hendrik schrieb:> Der selbe Code lässt sich in der Arduino-IDE (C++) allerdings> anstandslos ausführen.
Naja...
Hendrik schrieb:> Dass static einen Wert über das "Ableben" einer Funktion hinaus> speichern kann, war mir schon bekannt,
Warum verwendest du es dann?
Hendrik schrieb:> aber nicht, wie ich es sinnvoll einsetzen kann.
Wirst du merken, wenn du es brauchst.
Obelix X. schrieb:> Hendrik schrieb:>> Dass static einen Wert über das "Ableben" einer Funktion hinaus>> speichern kann, war mir schon bekannt,>> Warum verwendest du es dann?> Hendrik schrieb:>> aber nicht, wie ich es sinnvoll einsetzen kann.>> Wirst du merken, wenn du es brauchst.
Das braucht man dann, wenn man einen Wert über das "Ableben" einer
Funktion hinaus speichern will ;)
Oliver
Oliver S. schrieb:> 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.
Udo S. schrieb:> 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).
Obelix X. schrieb:> Das wissen doch alle sogar der TO wie er selbst schreibt,
Er weiss, dass er weiss, dass er es nicht Weiss...
Hendrik schrieb:> aber nicht, wie ich es sinnvoll einsetzen kann.
Oliver