Jak najlepiej zdefiniować pin we / wy?

9

Czytam takie definicje jak

const int ledPin = 9;

i również

#define ledPin 9

Wiem, że taka definicja

int ledPin = 9;

jest złą praktyką, jeśli nie zamierzasz tego zmieniać (czego zwykle nie robisz), chociaż widziałem to kilka razy w programach Arduino. Który z pozostałych dwóch jest preferowany?

Joris Groosman
źródło

Odpowiedzi:

6

#define ledPin 9jest preferowany. Robiąc int ledPin = 9;to, będziesz przydzielać intpamięć, której wartość jest wykorzystywana za każdym razem ledPin. #defineróżni się tym, że nie przydziela pamięci. nie ma pamięci nazywanej ledPin. Przed kompilacją wszystkie „ledPiny” w kodzie (inne niż łańcuchy) są zastępowane przez 9. Zasadniczo

digitalWrite(ledPin);

staje się

digitalWrite(9);

Zalety #define: Oszczędza pamięć, a ponieważ wszystkie ledPinsą zastępowane 9 przed wykonaniem , oszczędza czas procesora.

Tak naprawdę nie ma znaczenia w małych kodach ...


źródło
Czy osadzone kompilatory są tak złe, że nie robią ciągłego składania podczas używania const int?
Chuu,
1
@chuu, o ile wiem, Arduino używa gcc dla avr. Dlatego prawie na pewno powinien zostać zoptymalizowany. Odpowiedzi tutaj nie pokazują dobrego zrozumienia dobrych praktyk w C ++
chbaker0
3
w C ++ const int ledPin = 9;jest preferowany w porównaniu z 2 innymi opcjami. To NIE przydzieli pamięci dla wyjątku, intchyba że zdefiniujesz gdzieś wskaźnik, czego nikt by nie zrobił.
jfpoilpret
Const int nie przydziela pamięci @jfpoilpret. #define nie zajmuje pamięci, ponieważ jest to tylko symboliczna nazwa wyrażenia, a nie nazwa pamięci ...
Sprawdź ten link cplusplus.com/forum/beginner/28089 i przekonaj się sam. W przeciwnym razie po prostu wykonaj sprawdzenie za pomocą Arduino IDE: sprawdź rozmiar danych za pomocą const i #define.
jfpoilpret
4

Ściśle mówiąc, #definepodejście zużyje nieco mniej pamięci. Różnica jest zwykle niewielka. Jeśli musisz zmniejszyć zużycie pamięci, inne optymalizacje byłyby prawdopodobnie znacznie bardziej skuteczne.

Argumentem przemawiającym za użyciem const intjest bezpieczeństwo typu . Ilekroć odwołujesz się do tego numeru PIN według zmiennej, wiesz dokładnie, jaki typ danych otrzymujesz. Może być promowany / konwertowany pośrednio lub jawnie przez kod, który go używa, ale powinien zachowywać się w bardzo jasny sposób.

Natomiast wartość w #definejest otwarta na interpretację. W przeważającej większości przypadków prawdopodobnie nie spowoduje to żadnych problemów. Musisz tylko zachować ostrożność, jeśli masz kod, który przyjmuje założenia dotyczące rodzaju lub wielkości wartości.

Osobiście prawie zawsze wolę bezpieczeństwo typu, chyba że mam bardzo poważną potrzebę oszczędzania pamięci.

Peter Bloomfield
źródło
Byłem w obozie #define, dopóki nie przeczytałem odpowiedzi Petera. Chyba wiem, kto będzie w ten weekend refaktoryzował kod. ;)
linhartr22
2

Prawdopodobnie najlepszym sposobem byłoby
const uint8_t LED_PIN = 9; // may require to #include <stdint.h>
lub
const byte LED_PIN = 9; // with no include necessary
const unsigned char LED_PIN = 9; // similarly
Nazwa jest pisana wielkimi literami, zgodnie z ogólną praktyką w C ++ (i innych) do nazywania stałych. Nie powinno to zużywać pamięci RAM jako takiej i zużywać około 1 bajta pamięci programu na użycie.
Jednak nie może być problemy, gdy liczba jest wyższa niż 127 i jest przedłużony podczas logowania promowane coraz większych podpisanych liczb całkowitych (nie do końca pewien na ten temat), mimo że jest mało prawdopodobne z numerami pinów.

rykien
źródło
-1

Nie tylko będzie

const int ledPin = 9;

zajmują pamięć RAM, ale w tym przypadku zużyje więcej pamięci RAM, niż jest to konieczne, ponieważ digitalWrite(uint8_t, uint8_t)wymaga tylko argumentów jednobajtowych, a int to zwykle dwa bajty (zależne od kompilatora, ale typowe). Zauważ, że możesz podać literałowi jawny typ w #define:

#define ledPin ((int)9) 

chociaż w kontekście, takim jak argument funkcji, w którym wymagany jest określony typ (ponieważ funkcja została odpowiednio prototypowana!), zostałby albo niejawnie rzutowany, albo otrzymałby komunikat o błędzie, jeśli typy nie pasują.

JRobert
źródło
@DrivebyDownvoter, czy mógłbyś skomentować swoje powody?
JRobert