在这种情况下如何避免全局变量(嵌入式 C)
How to avoid globals in this case (embedded C)
我仍在学习用于微处理器的 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;
}
或者有更好的方法吗?我想一定有 :)
我最近一直在阅读结构,但老实说我并不完全理解它们,我什至不确定在这种情况下它是否对我有帮助?
在函数之间共享一个变量有几种选择:
- 在静态内存中分配您的变量 - 这几乎就是您的代码所做的。您的两个选择是函数静态、翻译单元静态和全局
- 将指针作为函数参数传递给变量 - 这个选择需要以某种形式传递指针
- 使用具有巧妙初始化的线程本地存储 - 当您使用微控制器时通常无法使用此选项;我在这里列出它是为了完整性。
对于您的情况,我认为使用翻译单元静态变量比较合适。将四个函数的实现放在一个C文件中,并在顶部声明LowVoltage
为静态变量:
static unsigned int LowVoltage;
这种简单而高效的封装机制为您提供了拥有全局变量的所有好处,而没有拥有全局变量的缺点:
- C模块里面的所有函数"see"这个变量,可以自由操作
- C 模块之外的其他函数无法访问此变量。他们可以声明自己的
LowVoltage
变量,赋予它完全不同的含义。
我能想到的两种解决方案
像这样制作函数签名
unsigned int Load_LowVoltage(unsigned int lowVoltage);
然后传递 LowVoltage
并为其分配 return 值,就像这样
LowVoltage = Load_LowVoltage(LowVoltage);
在函数内部修改LowVoltage
,像这样传递一个指向你原来的LowVoltage
的指针
void LowVoltage(unsigned int *lowVoltage)
{
*lowVoltage = modifiedValue;
}
那你就可以这样使用了
Load_LowVoltage(&LowVoltage);
我认为第二种解决方案更简洁,并且由于您处于资源有限的环境中,因此从这个意义上讲它也更好。但它们都易于实施并且效果一样好。
您可以创建一个包含所有电池参数的结构,例如:
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);
我仍在学习用于微处理器的 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;
}
或者有更好的方法吗?我想一定有 :) 我最近一直在阅读结构,但老实说我并不完全理解它们,我什至不确定在这种情况下它是否对我有帮助?
在函数之间共享一个变量有几种选择:
- 在静态内存中分配您的变量 - 这几乎就是您的代码所做的。您的两个选择是函数静态、翻译单元静态和全局
- 将指针作为函数参数传递给变量 - 这个选择需要以某种形式传递指针
- 使用具有巧妙初始化的线程本地存储 - 当您使用微控制器时通常无法使用此选项;我在这里列出它是为了完整性。
对于您的情况,我认为使用翻译单元静态变量比较合适。将四个函数的实现放在一个C文件中,并在顶部声明LowVoltage
为静态变量:
static unsigned int LowVoltage;
这种简单而高效的封装机制为您提供了拥有全局变量的所有好处,而没有拥有全局变量的缺点:
- C模块里面的所有函数"see"这个变量,可以自由操作
- C 模块之外的其他函数无法访问此变量。他们可以声明自己的
LowVoltage
变量,赋予它完全不同的含义。
我能想到的两种解决方案
像这样制作函数签名
unsigned int Load_LowVoltage(unsigned int lowVoltage);
然后传递
LowVoltage
并为其分配 return 值,就像这样LowVoltage = Load_LowVoltage(LowVoltage);
在函数内部修改
LowVoltage
,像这样传递一个指向你原来的LowVoltage
的指针void LowVoltage(unsigned int *lowVoltage) { *lowVoltage = modifiedValue; }
那你就可以这样使用了
Load_LowVoltage(&LowVoltage);
我认为第二种解决方案更简洁,并且由于您处于资源有限的环境中,因此从这个意义上讲它也更好。但它们都易于实施并且效果一样好。
您可以创建一个包含所有电池参数的结构,例如:
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);