2

私はグローバル変数構造体を持っています:

typedef struct {
    int myvar1;
    int myvar2;
    int myvar3;
    ...
    int myvar10;
} t_myStruct myGlobalData;

このグローバルな構造は避けられないので、使わなければなりません。私はそれを使用するための3つのオプションがあります:

  • グローバル変数を「そのまま」任意の関数に使用します。すなわち:

    int myFunc(void) {
        myGlobalData.myvar1 = ...
        myGlobalData.myvar10 = myGlobalData.myvar5 + ...
    }
    
  • ローカルポインタを宣言して使用します。

    int myFunc(void) {
        t_myStruct * p;
    
        p = &myGlobalData;
        p->myvar1 = ...
        ...
        p->myvar10 = p->myvar5 + ...
    }
    
  • ローカル変数を使用してから、グローバル構造体にコピーします。

    int myFunc(void) {
        t_myStruct localStruct;
    
        localStruct.myvar1 = ...
        localStruct.myvar10 = localStruct.myvar5 + ...
        myGlobalData = localStruct ;
    }
    

一般的に最善の方法とその理由を教えてください。

4

3 に答える 3

10

より多くの抽象化を選択してください。引数をに変更できる場合はmyFunc、その署名を作成します。

int myFunc(t_myStruct *arg)
{
    arg->myvar1 = ...

これで、関数自体はグローバル変数の存在にまったく依存しなくなります。structそして、このタイプので動作する必要がある他の機能についても同じです。グローバル変数を使用する必要がある場合は、その使用を可能な限り分離しますつまり、グローバル変数を可能な限り少ない場所で使用します。

関数のシグネチャを変更できない場合は、質問から最も直接的なオプションを選択します。最初のオプションです。グローバル変数を直接操作するだけです。

于 2012-09-18T16:16:18.943 に答える
2

リストした3つのオプション、IMOのうち、最初のオプションが最適です。グローバル構造を慎重に使用してください。

最初のオプションと2番目のオプションはほとんど同じですが、ポインターを不必要に使い始めると、物事が難読化され、人々はより多くの間違いを犯す傾向があります。

3番目のオプションは悪い考えです。今、あなたはすべての関数がそれらが完了したときにデータを確実に書き戻すことを期待していますか?関数A()と関数B()の両方がグローバル構造を編集している場合はどうなりますか?A()完了したらデータを元に戻し、B()2番目に終了して、のデータを上書きしA()ますか?今、あなたは適切な追加の保護メカニズムを必要としています...ただ悪い考えです。

于 2012-09-18T17:10:13.867 に答える
2

まず第一に、なぜそれはそれほど避けられないのですか?第二に、なぜそれらがあなたの唯一の3つの選択肢なのですか?

グローバルにアクセスする必要がある場合、最初のオプションは不合理ではありません-すでにグローバルですが、どれだけ悪化する可能性がありますか?

2番目のオプションはまったく無意味です。

3番目のオプションにもメリットはほとんどなく、memcpyは不要です。構造体を直接割り当てることができます。

myGlobalData = localStruct ;

マルチスレッドアプリケーションでは、どのソリューションもお勧めできません。

したがって、答えは上記のどちらでもありません。代わりに、そうしない本当の理由がない場合は、グローバルをstatic定義されているモジュールの外部で非表示になるようにグローバルを修飾してから、同じモジュールで適切なアクセス関数を定義します。

静的宣言がなくても、アクセス関数は、引数の検証、データの一貫性の確保、必要に応じて相互排除の適用が可能であり、デバッグ中に、あらゆる場所ではなくアクセス関数にのみブレークポイントを設定することですべてのアクセスをトラップできるため、優れたアプローチです。そうしないと、アクセスが発生する可能性があります。

おそらくAPoxon Globalsを読む必要があります。これは組み込みシステムを指しますが、デスクトップアプリケーションにも同様に適用できます。

于 2012-09-18T18:15:35.430 に答える