Sucht sich der Compiler den Variablentyp selbst?

Es ist sehr interessant hier mitzulesen und man lernt dabei.
Mit jedem Bröckchen Wissen tuen sich neue Fragen auf.

Wenn ich mit millis() Zeiten verglichen habe, dann wurde von mir die Sollzeit mit #define Intervall 300000 definiert.

Ich ging davon aus, dass der Compiler den Wert entsprechend seiner Größe einem Variablentyp zuordnet.
Ist das nicht so? Muss ich das mit einem Kürzel wie UL selbst machen?
Macht es einen Unterschied, ob ich einen Festwert mittels cont oder define zuweise?

Gibt es ein PDF im Netz, wo so etwas in deutsch beschrieben ist. Programmieren lernen mit rudimentären Englischkenntnisse ist meist mühsam.

Grüße :slight_smile:

Hausknecht:
Macht es einen Unterschied, ob ich einen Festwert mittels cont oder define zuweise?

Ja, Konstanten haben einen Typ, weshalb eine Typüberprüfung stattfinden kann. Bei define wird nur eine Textersetzung ohne Typüberprüfung gemacht. In beiden Fällen optimiert der Compiler das weg, zumindest bei einfachen Konstanten, nicht bei Feldern.

Einige im Forum bevorzugen die Konstanten.

Und hier kannst du etwas in deutsch nachlesen.

Super! vielen Dank.

Daher bleiben die 300000 vorerst 300000 was in uint16_t passt.

Nein!
Die dreihundert Tausend passen nicht in 16 Bit.
Darum ist ein L oder UL schon angemessen.

Auf einer 32 Bit Maschine passen sie in ein int. Da ist keine Spezifizierung nötig.
Bei unseren 8 Bit AVR wird es eng

Ich ging davon aus, dass der Compiler den Wert entsprechend seiner Größe einem Variablentyp zuordnet.
Ist das nicht so? Muss ich das mit einem Kürzel wie UL selbst machen?
Macht es einen Unterschied, ob ich einen Festwert mittels cont oder define zuweise?

Der Compiler beinhaltet automatische Konvertierungen.
Diese Konvertierungen erfolgen nach Regeln.

Grundsätzlich ist der Default Datentype für ganzzahlige numerische Literale das int.
Und int ist von Compiler zu Compiler(oder besser von µC zu µC) unterschiedlich groß
So wie ein Byte auch unterschiedlich groß sein kann. Meist 8 Bit, aber längst nicht immer.

#define Intervall 300000
Kann für den einen µC in eine Falle führen, beim anderen gut gehen.

#define Intervall 300000UL
Wird auf allen Systemen brauchbare Ergebnisse liefern.

Tipp:
Je exakter du dein Programm formulierst, desto weniger Spielraum hat der Compiler für automatische, oder schlimmstenfalls unerwartete/unbeabsichtigte Konvertierungen (implizit Cast)

Also wäre (höchstvermutlich) die richtige/beste/strengste Formulierung:

const uint32_t interval {300000UL};

Das entsprechende Mantra lautet:

Sei explizit!

Merksatz:

Jedes vermiedene #define ist ein gutes #define.
Jedes vermeidbare #define ist ein böses #define

Merke: Zwischen den beiden Aussagen befindet sich eine Hysterese/Spielraum der "sinnvollen/unvermeidlichen #define"


Gibt es ein PDF im Netz, wo so etwas in deutsch beschrieben ist. Programmieren lernen mit rudimentären Englischkenntnisse ist meist mühsam.

Ich empfehle dir so ein schönes dickes C++ Buch, mit ca 1000 Seiten.
z.B. dieses

Ansonsten ist es natürlich doof, auf englische Quellen zu verzichten.
Denn nahezu alle Datenblätter und Computerliteratur gibt es nur auf englisch.
Der deutsche Anteil dümpelt unter der 10% Grenze.
Selbst chinesisch ist mittlerweile weiter verbreitet.
Manche Datenblätter gibts nur auf Chinesisch.

Du solltest also schon üben, englisch und chinesisch zu lesen.

Vielen Dank für die ausführlichen Erklärungen. Es hat mich weiter gebracht.

Die Karma-Punkte sind vermutlich mit DANKE gleichzusetzen - oder? Kann ich die beliebig oft vergeben?

Hi

Hausknecht:
Die Karma-Punkte sind vermutlich mit DANKE gleichzusetzen - oder? Kann ich die beliebig oft vergeben?

Die Karma-Punkte sollen kein Danke in dem Sinn sein, sondern eher in die Richtung 'gute Leistung'.
(Was sich ja nicht gegenseitig ausschließen muß)
Beliebig oft: Ja, aber nur mit zeitlichem Versatz - soll irrtümliches Mehrfach-Karma verhindern.
Verschiedenen Usern kannst Du aber Karma direkt hinter einander geben.

MfG

Hausknecht:
Es ist sehr interessant hier mitzulesen und man lernt dabei.
Mit jedem Bröckchen Wissen tuen sich neue Fragen auf.

....
Macht es einen Unterschied, ob ich einen Festwert mittels cont oder define zuweise?

Da Du ja offensichtlich gerne weiter lernst, noch ein paar Hintergrundinformationen zum #define

Die Übersetzung des Codes läuft grob gesagt in 2 Schritten ab:
Zuerst bearbeitet der 'C-Präprozesser' den Text. Das ist ein rel. einfacher Makroprozessor, der den Text des Programms nach bestimmten Regeln verändert. Wie schon gesagt wurde, geht es hier rein um Textersetzungen. Im Prinzip ist das ein automatisierter Texteditor. Gesteuert wird er über die Codezeilen, die mit '#' beginnen. Von der C/C++ Syntax weis der eigentlich nichts - und damit auch nichts von Variablentypen.
Wo z.B. eine #include-Zeile steht, kopiert er stur den Text der angegebenen Datei hinein. Bei einer Zeile wie in deinem Beispiel

#define Intervall 300000

wird ab dem Auftreten dieser Zeile der Variablenname (oder genauer: der Makroname, denn wir definieren hier ein ganz einfaches Makro) 'Intervall' durch die Zeichenfolge '300000' ersetzt.
Die '#' Steuerzeilen selbst und Kommentare werden in dem erzeugten Text gelöscht und tauchen dort nicht mehr auf.
Neben #define und #include gibt es noch einige ander Steuerkommandos für den Präpozessor. Auch das #define kann komplexer aufgebaut sein als in dem einfachen Beispiel.

Erst das Ergebnis dieses Präprozesserlaufes bearbeitet dann der eigentliche Compiler. D.h. der Compiler bekommt den Variablennamen 'Intervall' überhaupt nicht zu sehen - kann da also auch keinen Variablentyp mit verbinden.
Im Unterschied dazu ist

const unsigned long Intervall = 300000;

eine echte Compileranweisung, an der der Präprozessor nichts ändert ( Wenn Du nicht oben drüber zusätzlich die #define Zeile reinschreibst - aber dann würde der Compiler eine fehlerhafte Zeile sehen ). Von daher ist die Festwertzuweisung mit #define oder mit const also etwas vollkommen anderes. Das eine wird vom Präprozessor bearbeitet, das andere vom eigentlichen Compiler.

Als Anwender/Programmierer bekommst Du davon direkt nichts mit, da Präprozessor und Compiler sehr eng zusammenarbeiten damit sich Fehlermeldungen und Warnings immer auf deinen Ausgangstext beziehen können. Um die aber immer richtig interpretieren zu können, ist es von Vorteil, sich diese 2-Stufigkeit klarzumachen.