Was ist der beste Weg, um einen E / A-Pin zu definieren?


9

Ich lese Definitionen wie

const int ledPin = 9;

und auch

#define ledPin 9

Ich weiß, dass eine Definition wie

int ledPin = 9;

ist eine schlechte Praxis, wenn Sie es nicht ändern werden (was Sie normalerweise nicht tun werden), obwohl ich dies mehrmals in Arduino-Programmen gesehen habe. Welches der beiden anderen wird bevorzugt?

Antworten:


6

#define ledPin 9Ist bevorzugt. Auf diese Weise weisen int ledPin = 9;Sie einen intSpeicher zu, dessen Wert bei jeder Verwendung verwendet wird ledPin. #defineist anders in dem Sinne, dass es keinen Speicher zuweist. Es wird kein Speicher aufgerufen ledPin. Vor dem Kompilieren werden alle "ledPins" im Code (außer Zeichenfolgen) durch ersetzt 9. Also im Wesentlichen

digitalWrite(ledPin);

wird

digitalWrite(9);

Vorteile von #define: Spart Speicher und da alle vor der AusführungledPin durch ersetzt werden , spart dies Prozessorzeit.9

Ist in kleinen Codes nicht wirklich wichtig ...


Sind eingebettete Compiler wirklich so schlecht, dass sie bei der Verwendung nicht ständig falten const int?
Chuu

1
@chuu soweit ich weiß Arduino verwendet gcc für avr. Es sollte also fast definitiv optimiert werden. Die Antworten hier zeigen nicht viel Verständnis für bewährte Verfahren in C ++
chbaker0

3
in C ++ const int ledPin = 9;wird gegenüber 2 anderen Optionen bevorzugt. Dies wird KEINEN Speicher für ein reservieren, intaußer wenn Sie irgendwo einen Zeiger darauf definieren, was niemand tun würde.
jfpoilpret

Const int weist Speicher @jfpoilpret zu. #define nimmt keinen Speicher ein, weil es nur ein symbolischer Name eines Ausdrucks ist und nicht der Name eines Speichers ...

Schauen Sie sich diesen Link cplusplus.com/forum/beginner/28089 an und überzeugen Sie sich selbst. Andernfalls führen Sie die Prüfung einfach mit der Arduino IDE durch: Überprüfen Sie die Datengröße mit const und mit #define.
jfpoilpret

4

Genau genommen wird der #defineAnsatz etwas weniger Speicher verbrauchen. Der Unterschied ist normalerweise jedoch winzig. Wenn Sie die Speichernutzung reduzieren müssen, sind andere Optimierungen wahrscheinlich weitaus effektiver.

Ein Argument für die Verwendung const intist die Typensicherheit . Wo immer Sie sich per Variable auf diese PIN-Nummer beziehen, wissen Sie genau, welchen Datentyp Sie erhalten. Es kann implizit oder explizit durch den Code, der es verwendet, beworben / konvertiert werden, sollte sich jedoch sehr klar verhalten.

Im Gegensatz dazu ist der Wert in a #defineinterpretationsfähig. Die überwiegende Mehrheit der Zeit wird es Ihnen wahrscheinlich überhaupt keine Probleme bereiten. Sie müssen nur ein wenig vorsichtig sein, wenn Sie Code haben, der Annahmen über den Typ oder die Größe des Werts macht.

Persönlich bevorzuge ich fast immer die Typensicherheit, es sei denn, ich muss dringend Speicherplatz sparen.


Ich war im Lager #define, bis ich Peters Antwort las. Ich schätze, ich weiß, wer dieses Wochenende den Code umgestalten wird. ;)
linhartr22

2

Wahrscheinlich wäre der beste Weg
const uint8_t LED_PIN = 9; // may require to #include <stdint.h>
oder
const byte LED_PIN = 9; // with no include necessary
const unsigned char LED_PIN = 9; // similarly
Der Name ist in Großbuchstaben gemäß der allgemeinen Praxis in C ++ (und anderen), um Konstanten zu benennen. Dies sollte keinen RAM an sich verwenden und ungefähr 1 Byte Programmspeicher pro Verwendung verwenden.
Es kann jedoch zu Problemen kommen, wenn die Zahl höher als 127 ist und das Vorzeichen erweitert wird, während auf größere vorzeichenbehaftete Ganzzahlen umgestellt wird (diesbezüglich nicht ganz sicher), obwohl dies bei PIN-Nummern unwahrscheinlich ist.


-1

Nicht nur wird

const int ledPin = 9;

Nehmen Sie RAM in Anspruch, verwenden Sie in diesem Fall jedoch mehr RAM als erforderlich, da digitalWrite(uint8_t, uint8_t)nur Ein-Byte-Argumente erforderlich sind und ein Int normalerweise zwei Bytes umfasst (compilerabhängig, aber typisch). Beachten Sie, dass Sie dem Literal in #define einen expliziten Typ geben können:

#define ledPin ((int)9) 

In einem Kontext wie einem Funktionsargument, in dem ein bestimmter Typ erforderlich ist (weil die Funktion ordnungsgemäß prototypisiert wurde!), wird sie entweder implizit umgewandelt oder es wird eine Fehlermeldung angezeigt, wenn die Typen nicht übereinstimmen.


@DrivebyDownvoter, würden Sie Ihre Gründe kommentieren?
JRobert
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.