在这种情况下如何避免全局变量(嵌入式C)
我还在学习C语言在微处理器中的应用。一开始我用了很多globals。现在我正在尽可能地避免它,但对我来说,这并不总是清楚如何做到这一点 例如,电池监视器,在这种情况下,有4个函数需要读取或修改变量。 我有这些功能都使用可变低电压在这种情况下如何避免全局变量(嵌入式C),c,global-variables,mikroc,C,Global Variables,Mikroc,我还在学习C语言在微处理器中的应用。一开始我用了很多globals。现在我正在尽可能地避免它,但对我来说,这并不总是清楚如何做到这一点 例如,电池监视器,在这种情况下,有4个函数需要读取或修改变量。 我有这些功能都使用可变低电压 void Check_Voltage(){ checks current voltage against LowVoltage } void Menu_Voltage(){ a menu on the LCD screen to set the value o
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
}
- 检查_Voltage()并保存_LowVoltage()需要读取低电压
- Load_LowVoltage()需要写入低电压
- 菜单_Voltage()需要读取和写入低电压
unsigned int Low_Voltage(short Get, unsigned int Value){
static unsigned int LowVoltage;
if(Get) return LowVoltage;
else LowVoltage= Value;
}
还是有更好的方法?我想一定有:)
最近我一直在阅读有关结构的文章,但说实话,我并不完全理解它们,我甚至不确定在这种情况下它是否会对我有所帮助?在函数之间共享变量有几种选择:
- 在静态内存中分配变量——这与代码所做的差不多。有两种选择:函数静态、转换单元静态和全局
- 将指向变量的指针作为函数参数传递-此选项要求以某种形式传递指针
- 通过智能初始化使用线程本地存储-使用微控制器时,此选项通常不可用;为了完整起见,我把它列在这里
LowVoltage
声明为静态变量:
static unsigned int LowVoltage;
这种简单但高效的封装机制为您提供了使用全局变量的所有好处,而没有使用全局变量的缺点:
static unsigned int LowVoltage;
- C模块中的所有函数都可以“看到”这个变量,并且可以自由地操作它
- C模块之外的任何其他函数都无法访问此变量。他们可以声明自己的
变量,赋予它完全不同的含义LowVoltage
- 让函数签名像这样
unsigned int Load_LowVoltage(unsigned int lowVoltage);
LowVoltage = Load_LowVoltage(LowVoltage);
void LowVoltage(unsigned int *lowVoltage) { *lowVoltage = modifiedValue; }
然后传递Load_LowVoltage(&LowVoltage);
并为其指定返回值,如下所示低电压
unsigned int Load_LowVoltage(unsigned int lowVoltage);
LowVoltage = Load_LowVoltage(LowVoltage);
void LowVoltage(unsigned int *lowVoltage) { *lowVoltage = modifiedValue; }
Load_LowVoltage(&LowVoltage);
- 在函数中修改
,并像这样传递指向原始LowVoltage
的指针LowVoltage
unsigned int Load_LowVoltage(unsigned int lowVoltage);
LowVoltage = Load_LowVoltage(LowVoltage);
void LowVoltage(unsigned int *lowVoltage) { *lowVoltage = modifiedValue; }
那么你可以这样使用它Load_LowVoltage(&LowVoltage);
unsigned int Load_LowVoltage(unsigned int lowVoltage);
LowVoltage = Load_LowVoltage(LowVoltage);
void LowVoltage(unsigned int *lowVoltage) { *lowVoltage = modifiedValue; }
Load_LowVoltage(&LowVoltage);
- 我能想到的两种解决方案
我认为第二个解决方案更清洁,因为你身处资源有限的联合国环境中,从这个意义上讲也更好。但是它们都很容易实现,并且工作正常。您可以创建一个包含所有电池参数的结构,例如:
typedef struct {
int low_voltage;
int voltage;
int capacity;
int temperature;
...
} BatteryData
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;
}
在程序开始时,为其分配内存,并将成员初始化为某些起始值:
BatteryData *battery = malloc(sizeof(BatteryData));
battery->low_voltage = 0;
...
然后将指向整个结构的指针传递给设置或读取单个值的函数,例如:
typedef struct {
int low_voltage;
int voltage;
int capacity;
int temperature;
...
} BatteryData
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);
这些函数是同时使用的吗?不要将“全局变量”(即暴露于整个程序的文件范围变量)与仅对放入它们的文件可见的私有文件范围变量混淆。前者是非常糟糕的实践,永远不应该使用,后者大多数时候是很好的编程实践。@moffeltje,不,它们从来没有同时使用过。但这并没有提供私有封装。很明显,他正在编写某种“电池”驱动程序,而打电话的人不应该关心该驱动程序的内部结构,这个低电压变量似乎是什么。将其设为静态文件范围变量,并将所有这些函数放在一个battery.h/battery.c代码模块中,这似乎正是OP需要做的。谢谢dasblinkenlight!这确实是我所想的,但当我在两个不同的C模块中有相同的静态变量名时,它们不知何故在同一范围内。因为直到最近我才了解静态变量及其作用域,所以我认为我误解了它。但现在我开始明白为什么我经常看到对米克罗克的抱怨。。。我已经将.c文件包含在#include中,如果我将.c文件包含在项目经理那里,它会正常工作……我认为这是个坏主意。在嵌入式系统上最好避免使用动态分配。如果您必须使用它,那么只需为它分配一次内存,而不要释放它。根据具体情况,多次释放和重新创建分配将很快导致堆损坏。