Kannst du bitte erklären, warum? Wie berechnet sich der benötigte Speicherplatz für eine String Variable? Ist es ein fester Wert, oder ein Byte pro Zeichenlänge?
Bei einem char[5] gehe ich von 5 Byte aus, evtl. noch eines für die Array-Verwaltung? Ist das bei einem String anders?
char ist ein sogenannter "einfacher Datentyp" und wird im Speicher als Byte (je Zeichen bei unseren Arduinos) abgelegt.
Ein char-Array (char[]) ist dann eine Kette von chars hintereinander im Speicher mit einer Startadresse.
String ist ein sogenannter "komplexer Datentyp". Er kann viel mehr mit seinem eigenen Inhalt tun (z.B. manipulieren) und bringt gleich Methoden dafür mit. Das kann hilfreich sein, wenn man es braucht. Jedoch wird für die Verwendung von String ein ganzer Satz mehr Code geladen.
Beispiel:
Code: Alles auswählen
void setup() {
// put your setup code here, to run once:
char wort[] = "Test";
Serial.println(s);
}
void loop() {
// put your main code here, to run repeatedly:
}
Ergebnis:
Binäre Sketchgröße: 10.496 Bytes (von einem Maximum von 262.144 Bytes)
Estimated memory use: 2.564 bytes (of a 65.536 byte maximum)
Code: Alles auswählen
void setup() {
// put your setup code here, to run once:
String wort = "Test";
Serial.println(s);
}
void loop() {
// put your main code here, to run repeatedly:
}
Ergebnis:
Binäre Sketchgröße: 14.452 Bytes (von einem Maximum von 262.144 Bytes)
Estimated memory use: 3.908 bytes (of a 65.536 byte maximum)
Das ganze Relativiert sich natürlich, je öfter ich String benutze, da der zusätzliche Code ja insgesamt nur ein mal dazugeladen und immer wieder verwendet wird. Zehn mal verwendet wird der Code also nicht auch zehn mal größer. Er wäre aber insgesamt dennoch größer als wenn ich zehn mal char[] verwende.
Kann man ja einfach mal ausprobieren.
Kannst du bitte mal ein Beispiel für einen "schlechten" und das gleiche Beispiel mit einem "guten" Code schreiben? Ich lerne gerne dazu.
Das ist natürlich ohne konkrete Aufgabenstellung nicht so leicht zu zeigen. (Habe schon drüber nachgedacht mir ein paar leichte aufgaben einfallen zu lassen und man schaut mal, wie jeder das löst so dass man von einander lernen kann).
Ein prominentes Beispiel wäre aber z.B. das Deklarieren einer Variable innerhalb einer Schleife (anstatt außerhalb und diese nur in der Schleife zu verwenden). In der Regel behebt ein guter Kompiler so etwas aber. Ist also eher ein "fiktives" Beispiel an dem man das aber gut erkennt.
Ein anderes Beispiel ist der Unterschied zwischen "call by value" und "call by reference" - also den Aufruf einer Methode und die Art und Weise, wie ich größere (komplexere) Variablen übergebe. Angenommen ich habe eine Variable mit 100 Byte Inhalt und ich rufe eine Funktion auf die diesen Inhalt modifiziert. Ich kann natürlich diese 100Byte übergeben, in der Funktion verändern und zurückgeben, wo der modifizierte Inhalt wieder in die originalvariable zurück geschrieben wird.
Beispiel:
In diesem Fall wird eine Kopie des Inhaltes in der Funktion macheWas() bearbeitet und zurückgegeben. Ich verschwende also mal eben noch mal 100Byte.
Ich kann aber auch der Funktion einfach nur sagen, WO die Variable im Speicher liegt.
Beispiel:
Hier übergebe ich nur die Adresse der Variable im Speicher. Das ist bei den AVR-Prozessoren gerade mal 2Byte.
Weitere Möglichkeit ist natürlich, dass die Variable a global bekannt ist und die Funktion macheWas einfach drauf zugreift (wenn das gegeben ist).
Außerdem - auch wenn das nicht direkt mit dem Code zu tun hat - ist eine gute Dokumentation etwas, das den guten Code erst richtig perfekt macht. Auch wenn es Mühe kostet.
Stimmt eigentlich meine Annahme, das die Länge der Variablennamen beim kompilieren egalisiert werden, weil es direkt in Speicheradressen umgesetzt wird?
Ja. Der Variablenname ist für dich. Intern sind das alles nur Speicheradressen (sogenannte "Pointer"). Für den Kompiler kannst du auch alles stumpf durchbuchstabieren.
Ein guter Stil ist es aber "sprechende" Variablennamen zu verwenden. Also ein Name, der schon irgendwie aussagt, wofür die Variable ist.
Schlecht: int a;
Gut: int tasterZaehler;
Du wirst dir sowas selber danken wenn du zwei Monate später deinen Code anguckst und versuchst, nach zu vollziehen was da passiert. Oder wenn du den Code jemanden zeigen willst.
Ich finde aber den Code aus deinen Beispielen wirklich vorbildlich (jetzt klinge ich ja wie so ein verkorkster Oberlehrer
).
Ich muss mich oft selber zwingen das so gut lesbar und dokumentiert zu machen. Ist also eine gute Sache die man so beibehalten sollte und zu der ich mich auch immer wieder zwingen muss.