編集:マイクロテリオンはここで私のポイントのいくつか、特にメモリ使用量を修正する優れた答えを与えます。
確認した#define
ように、コンパイラーはconst
変数を許可しないため、の使用を強制される特定の状況があります。同様に、状況によっては、値の配列が必要な場合(つまり、配列を持つことができない場合など)に変数の使用を余儀なくされます#define
。
ただし、単一の「正しい」答えが必ずしもあるとは限らない他の多くの状況があります。ここに私が従ういくつかのガイドラインがあります:
型の安全性
一般的なプログラミングの観点から、const
変数は通常望ましい(可能な場合)。その主な理由は型安全です。
#define
(プリプロセッサマクロ)に直接コピーリテラルコードの各位置への値、すべての利用独立を行います。これは、タイプが使用方法/場所に応じて異なる方法で解決される可能性があるため、仮説的に曖昧になる可能性があります。
const
変数はその宣言によって決定され、初期化時に解決されるしか一種です。異なる振る舞いをする前に、明示的なキャストが必要になることがよくあります(暗黙的にタイププロモーションを安全に行えるさまざまな状況がありますが)。少なくとも、型の問題が発生した場合、コンパイラーは(正しく構成されていれば)より信頼性の高い警告を出すことができます。
これの可能な回避策は、内に明示的なキャストまたはタイプサフィックスを含めること#define
です。例えば:
#define THE_ANSWER (int8_t)42
#define NOT_QUITE_PI 3.14f
ただし、その方法は、使用方法によっては、場合によっては構文の問題を引き起こす可能性があります。
メモリ使用量
汎用コンピューティングとは異なり、Arduinoのようなものを扱う場合、メモリは明らかに貴重です。const
変数とa を使用すると#define
、データがメモリのどこに保存されるかに影響を与える可能性があり、どちらか一方を使用せざるを得ない場合があります。
const
変数は(通常)他のすべての変数とともにSRAMに保存されます。
- で使用されるリテラル値は、
#define
多くの場合、スケッチ自体とともにプログラム空間(フラッシュメモリ)に保存されます。
(コンパイラの構成や最適化など、何かが正確に保存される方法と場所に影響を与える可能性のあるさまざまなものがあることに注意してください。)
SRAMとフラッシュには異なる制限があります(たとえば、Unoの場合はそれぞれ2 KBと32 KB)。一部のアプリケーションでは、SRAMを使い果たすのが非常に簡単なので、いくつかのことをフラッシュに移行すると役立つ場合があります。おそらく一般的ではありませんが、逆も可能です。
PROGMEM
データをプログラム空間(フラッシュ)に保存しながら、タイプセーフの利点を得ることができます。これは、PROGMEM
キーワードを使用して行われます。すべての型で機能するわけではありませんが、一般的に整数または文字列の配列に使用されます。
ドキュメントに記載されている一般的な形式は次のとおりです。
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};
文字列テーブルはもう少し複雑ですが、ドキュメントには詳細があります。