2016-05-20 9 views
0

私は今Arduinoプロジェクトに取り組んでいます。何それがないことは基本的にはこれです:Arduino/C++ GlobalVarsとローカル変数

  1. は、解析は、このデータを使用して
  2. ドローTFT画面上でデータを受信PC
  3. からのシリアルデータを読み込みます。

私の現在のアプローチでは、グローバル変数を頻繁に使用しています。それらがなければ、3レベルの変数を渡すネストされた関数を使用する必要があります。それは、どのアプローチがパフォーマンス面で優れているかを考えさせました。ここに2つの例があります。ローカル

まず:

void setup() { 
    Serial.begin(9600); 
    Serial.println(firstFunction(10)); 
} 

int firstFunction(int val) 
{ 
    return secondFunction(val+1); 
} 

int secondFunction(val) 
{ 
    return thirdFunction(val+1); 
} 

int thirdFunction(val) 
{ 
    return val + 1; 
} 

グローバル:物事のPC側で

int x; //global var 
void setup() { 
    Serial.begin(9600); 
    firstFunction(10); 
    Serial.println(x); 
} 
void firstFunction(int val) 
{ 
    x = val; 
    x += 1; 
    secondFunction(); 
} 
void secondFunction() 
{ 
    x++; 
    thirdFunction(); 
} 
void thirdFunction(val) 
{ 
    x++; 
} 

、使用してグローバルは、一般的に眉をひそめるされています。しかし、私の理解は、主にスタイルとスケーラビリティの理由です。

あなたの意見は?

答えて

1

、いずれかのアプローチが可能になります

私はこのような何かをするだろう。

関数呼び出しのスタックを介して変数をパラメータとして渡すことについて言及している1つの考慮点は、マイクロチップ上にあるメモリの容量が非常に限られていることです。すべてのローカル変数とすべての関数パラメータがスタックに置かれ、あなたの場合、基本的に同じ変数がスタックに複数回あり、メモリが無駄になります。 μC上のRAMの量によっては、実行時に操作したい文字列や他のより大きな構造で作業を開始すると、髪の毛がかってしまうことがあります。

あなたが突然あなたのμCが不正な動作を開始することに気付いた場合 - クラッシュ、ハングなどのゴミ出力を生成 - それはあなたがあなたのヒープまたは他の方法でのラウンドにあなたのスタックをアンダーフローしていることをすることができます。これは、最初にこのような変数の不要なコピーを避けようとすると、問題になる可能性は低くなります。

もちろん、あなたのプログラムの仕方によっては、逆のことが言えるでしょう:あなたがプログラムの特定の部分だけを追跡する必要がある状態を必要とし、関数がそこを通過すると、渡されたローカル変数にその変数を保持するほうが良いでしょう。外部関数から戻ってしまえば、変数はもう一度消えてしまいます。

基本的な違いは、グローバル変数は常にプログラムが実行されている間ずっとグローバル変数が存在することですが、ローカル変数は関数を作成した関数が返す限りローカル変数はそれを行いますが、変数を別の関数に渡すと、2番目のコピーが作成されます。だから、それは常に2つの側面を持っています。

しかし、複雑さが増すにつれて、メンバ変数や静的変数、およびグローバル変数の代わりに対応するメソッドを使用して、責任で分けたクラスを使用することは間違いありません。

それでは、あなたはまだ一緒にうまくつながっていて、まるで世界の宇宙空間にゆるやかに浮かんでいるだけではありませんが、あなたは記憶を浪費していません。

0

リファレンスを追加するとオーバーヘッドが追加されるとは思われません。コンパイラはそれをポインタとして実装することに縛られていないことに注意してください。すべてが同じコンパイルユニットにある場合は、おそらく最適化されている可能性があります。関数が非常に小さい場合は、ほぼ確実にインライン化できます。

異なる可能性は、それらの関数と変数を、同じクラスのメンバにすることです(設計上許される場合)。

しかし、今日の終わりにカプセル化が主に存在するため、プログラマーのチームをシフトさせることで複雑なプロジェクトを数十年以上にわたって維持することができます。 あなただけが見る小さなコードなら、おそらくあまりにも良い習慣に縛られる必要はありません。

1

私の意見では、一般的に小さなArduinoプログラムでも、ローカルアプローチのためにスタイルを設定する方が良いと思います。いったんたくさんのグローバルがあると、それらを構造体に入れ、構造体のアドレスを関数に渡すことができます。

セットアップ機能では特に便利です。セットアップが完了するとメモリはもう使用されません。あなたのバージョンでは、xはプログラムの存続期間中に4バイトを使います。ちょうど2kのメモリで、あなたは限界にすぐに達することができます。あなたのプロジェクトがどのように複雑に応じて

typedef struct { 
    int a, b; 
} entity_t; 

void foo(entity_t *e) { foo2(e); foo3(e); /* do stuff */ } 

void setup() 
{ 
    entity_t e = { 1, 2}; 

    foo(&e); 

    Serial.println(e.a); 
    // automatic memory of e is released 
}