Dies ist weniger eine Frage, sondern mehr eine Antwort. Da ich dieses Thema in den Tutorials, die ich gerade konsultiere, nicht wirklich erklärt bekam, habe ich eben selbst rumprobiert. Und möchte hier das Ergebnis zeigen. Jeder C-Programmierer weiß das natürlich, aber Anfänger könnten da Schwierigkeiten haben. Hier wird eine Variable "x" mehrfach deklariert, und die entsprechende Reaktion des Programms gezeigt. Und hier der kurze Code:
int x=555;
void setup() {
Serial.begin(115200);
delay(2000); //if(!Serial){ ... } funktioniert eigentlich nicht, lieber einfach warten
Serial.println(x);
Funktion1();
Funktion2();
Serial.println(x);
}
void loop() { } // bleibt diesmal ganz leer
void Funktion1() {
x=666; // hier wird die globale Variable x überschrieben
Serial.print("F1 "); // soll hinweisen, dass diese Ausgabe von Funktion1 kommt
Serial.println(x);
}
void Funktion2() {
int x=777; // hier wird die globale Variable x nicht überschrieben,
// sondern eine andere, die nur scheinbar den selben Namen hat
Serial.print("F2 "); // soll hinweisen, dass diese Ausgabe von Funktion2 kommt
Serial.println(x);
}
Das ist ja gerade der Witz an der Sache, globale und lokale Variablen zu unterscheiden, obwohl sie den gleichen Namen haben. Hätten alle Variablen, sowohl lokale als auch globale, definitiv unterschiedliche Namen, dann bräucht man diese Unterscheidung eigentlich nicht. Jetzt kann man nach Herzenslust Namen vergeben, auch wenn in anderer Leut's Funktionen zufällig die gleichen Namen schon deklariert waren.
Die Unterscheidung ist ja nicht wegen der Namensgleichheit geschaffen, sie dient der Kapselung. Also dass Variablen nur dort gültig sind, wo sie auch gebraucht werden.
Normalerweise sollten globale Variablen nur eingesetzt werden, wenn es sich nicht vermeiden lässt. Schließlich sind sie auch global veränderbar.
Das kann bei größeren Programmen aber zu Problemen führen. Darum solle der Geltungsbereich möglichst klein sein, weil das hilft Fehler zu vermeiden.
Aus diesem Grund ist es sinnvoll, den Variablen einen beschreibenden Namen zu geben.
Ich persönlich mag das nicht so gerne. Ich halte es wie in der Mathematik. Der Satz von Pythagoras ist für mich: a²+b²=c². Und nicht KatheteEinsImRechtwinkligenDreieck^2 + KatheteZweiImRechtwinkligenDreieck^2 = HypertenuseImRechtwinkligenDreieck^2.
Etwas übertrieben, um den Gedanken deutlich zu machen. Aber das ist Geschmacksache, und natürlich ein ganz anderes Thema.
Deine zweite Variante sieht in der Tat besser aus. Vielleicht ein Kompromiss, nicht all zu lange Namen, aber doch beschreibend.
Außerdem hätte man ja noch die Möglichkeit, hinzuschreiben, was was ist: constexpr uint8_t x {3}; // die Nummer des Pins, mit dem die Led angesteuert wird
Jetzt natürlich nicht plump mit "x", sondern schon etwas kurz beschreibender.
Man kann das natürlich machen. Aber wenn man ein größeres Programm hat, ist es besser wenn man es (fast) sprachlich lesen kann. Außerdem neigen Kommentare dazu schnell falsch zu werden, weil sie bei Programmänderungen oft nicht angepasst werden.
Spätestens, wenn Du größere Programme hast oder längere Zeit nichts mit einem bestimmten Programm gemacht hast, wirst Du sprechende Variablennamen schätzen lernen.
Falls Du beruflich in einem Team entwickeln willst, sind sie, neben anderen Festlegungen zur Schreibweise, Pflicht.
Der Gültigkeits-Bereich ist übrigens in jedem C/C++-Buch eindeutig beschrieben. Ebenso die Lebensdauer.
Ins besondere die Verwendung von static wird hier nochmal deutlich. Und natürlich Serial.print(__func__) ist praktisch, das kannte ich noch nicht. Ich komm langsam immer weiter.
P.S. nicht so ganz wird hier der Sinn von static klar, denn "katze" wird ja nirgends woanders noch einmal definiert.
noch mal P.S. doch nicht. Denn wenn "katze" nicht als static deklariert wäre, würde es ja bei jedem Aufruf von Funktion2 wieder auf 777 zurückgesetzt werden.