最も基本的な違いはスコープです。
最初のケースでは、グローバル変数を宣言しています。定義後にすべてのスコープでアクセスできる変数です。
void setup()
{
Serial.begin(9600);
}
void inc();
int count = 0;
void loop()
{
Serial.println(count);
count++;
inc();
delay(500);
}
void inc() //Can edit the value of count
{
count=count+1;
};
2番目のケースでは、ローカルスコープで静的変数を宣言しています。変数は、グローバル変数と同様にプログラム全体で実行されますが、宣言されているコードブロックでのみアクセスできます。これは同じ例ですが、変更が1つだけあります。count
は内で静的変数として宣言されていますloop
。
void inc();
void loop()
{
static int count = 0;
Serial.println(count);
count++;
inc();
delay(500);
}
関数inc()
はにアクセスできないため、これはコンパイルされませんcount
。
グローバル変数は、一見便利なように見えますが、いくつかの落とし穴があります。これらは、物理的な環境と相互作用する可能性のあるプログラムを書くことになると、損傷を引き起こす可能性さえあります。これは、プログラムが大きくなるとすぐに発生する可能性が非常に高い基本的な例です。関数が誤ってグローバル変数の状態を変更する場合があります。
void setup()
{
Serial.begin(9600);
}
void another_function();
int state=0;
void loop()
{
//Keep toggling the state
Serial.println(state);
delay(250);
state=state?0:1;
//Some unrelated function call
another_function();
}
void another_function()
{
//Inadvertently changes state
state=1;
}
このようなケースはデバッグが非常に困難です。ただし、このタイプの問題は、静的変数を使用するだけで簡単に検出できます。
void setup()
{
Serial.begin(9600);
}
void another_function();
void loop()
{
static int state=0;
//Keep toggling the state
Serial.println(state);
delay(250);
state=state?0:1;
//Some unrelated function call
another_function();
}
void another_function()
{
//Results in a compile time error. Saves time.
state=1;
}