7

私はまだマイクロプロセッサで使用される C を学んでいます。最初は、多くのグローバルを使用していました。今はできる限り回避しようとしていますが、これを行う方法が常に明確であるとは限りません。

たとえば、バッテリー モニターの場合、変数の読み取りまたは変更が必要な関数が 4 つあります。これらの関数はすべて、変数 LowVoltage を使用しています。

void Check_Voltage(){
  checks current voltage against LowVoltage
}

void Menu_Voltage(){
  a menu on the LCD screen to set the value of LowVoltage
}

void Save_LowVoltage(){
 runs after the settings menu is finished to save LowVoltage to EEPROM
}

void Load_LowVoltage(){
 reads EEPROM and sets LowVoltage at startup 
}
  • Check_Voltage() と Save_LowVoltage() は LowVoltage を読み取る必要があります。
  • Load_LowVoltage() は LowVoltage を書き込む必要があります。
  • Menu_Voltage() は LowVoltage を読み書きする必要があります。

LowVoltageをグローバルにせずにどうすればこれを機能させることができますか?? LowVoltage を読み書きするために別の関数を作成する必要がありますか? このようなもの:

unsigned int Low_Voltage(short Get, unsigned int Value){
  static unsigned int LowVoltage;

  if(Get) return LowVoltage;
  else LowVoltage= Value;
}

または、これを行うためのより良い方法はありますか? あるに違いないと思います:)最近、構造について読んでいますが、正直に言うと、それらを完全には理解しておらず、このような場合に役立つかどうかさえわかりませんか?

4

3 に答える 3

10

関数間で変数を共有するには、いくつかの選択肢があります。

  • 変数を静的メモリに割り当てます。これは、コードが行うこととほとんど同じです。function-static、translation unit-static、および global の 2 つの選択肢があります。
  • 関数パラメーターとして変数へのポインターを渡す - この選択では、何らかの形式でポインターを渡す必要があります
  • 巧妙な初期化でスレッド ローカル ストレージを使用する- この選択は通常、マイクロコントローラーを使用する場合には利用できません。完全を期すためにここにリストします。

あなたの場合、翻訳単位静的変数を使用するのが適切だと思います。4 つの関数の実装を 1 つの C ファイルに配置LowVoltageし、先頭で静的変数として宣言します。

static unsigned int LowVoltage;

このシンプルだが効率的なカプセル化メカニズムは、グローバル変数を持つことの欠点なしに、グローバル変数を持つことのすべての利点を提供します。

  • C モジュール内のすべての関数は、この変数を「参照」し、自由に操作できます。
  • C モジュール以外の関数は、この変数にアクセスできません。独自のLowVoltage変数を宣言して、まったく異なる意味を与えることができます。
于 2015-03-30T14:26:51.173 に答える
0

私が考えることができる2つの解決策

  1. このような関数シグネチャを作成します

    unsigned int Load_LowVoltage(unsigned int lowVoltage);
    

    LowVoltage次に、このように戻り値を渡して割り当てます

    LowVoltage = Load_LowVoltage(LowVoltage);
    
  2. 関数内を変更し、このようLowVoltageにオリジナルへのポインターを渡しますLowVoltage

    void LowVoltage(unsigned int *lowVoltage)
     {
        *lowVoltage = modifiedValue;
     }
    

    その後、このように使用できます

    Load_LowVoltage(&LowVoltage);
    

2番目の解決策はよりクリーンで、リソースが限られている環境にいるので、その意味でも優れていると思います。しかし、どちらも実装が簡単で、うまく機能します。

于 2015-03-30T14:27:01.443 に答える
0

たとえば、次のように、すべてのバッテリー パラメータを保持する構造体を作成できます。

typedef struct {
  int low_voltage; 
  int voltage;
  int capacity;
  int temperature;
  ...
} BatteryData

プログラムの開始時に、メモリを割り当て、メンバーをいくつかの開始値に初期化します。

BatteryData *battery = malloc(sizeof(BatteryData));
battery->low_voltage = 0;
...

次に、構造体全体へのポインターを、個々の値を設定または読み取る関数に渡します。次に例を示します。

void Load_LowVoltage(BatteryData *battery){
 //reads EEPROM and sets LowVoltage at startup 
 int eeprom_val = get_low_voltage_from_eeprom();
 battery->low_voltage = eeprom_val;
}

不要な場合は構造を解放します。

free(battery);
于 2015-03-30T15:56:24.543 に答える