繁体   English   中英

Arduino / C ++ GlobalVars与局部变量

[英]Arduino/C++ GlobalVars vs Local variables

我现在正在研究Arduino项目。 它的作用基本上是这样的:

  1. 从PC读取串行数据
  2. 解析收到的数据
  3. 使用此数据在TFT屏幕上绘制。

我当前的方法大量使用全局变量。 没有它们,我将不得不使用一些嵌套函数,这些函数将变量传递给3级深度。 这让我开始思考哪种方法在性能上更好。 这是两个例子。

首先本地:

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;
}

全球:

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++;
}

在PC方面,通常不赞成使用全局变量。 但是我的理解是,这主要是出于样式和可伸缩性的原因。

你们怎么想?

在我看来,最好采用样式化以采用本地方法,在通常较小的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
}

根据项目的复杂程度,这两种方法都是可行的。

一个反对通过一堆函数调用将变量作为参数传递的考虑因素是,微芯片上的内存非常有限。 每个局部变量和每个函数参数都放在堆栈中,在这种情况下,堆栈上多次具有基本上相同的变量,这浪费了内存。 根据µC上的RAM数量,一旦开始使用字符串和要在运行时操作的其他较大结构,这可能会变得很麻烦。

如果您发现您的µC突然开始行为异常-崩溃,挂起,产生垃圾输出等-可能是您正在将堆栈下溢到堆中,或者反过来。 如果首先尝试避免不必要的变量副本,则这不太可能成为问题。

当然,根据程序的工作方式,情况可能相反:如果您必须具有某种状态,则只需要跟踪程序的某个部分,而无需在其中调用许多嵌套函数,最好将其保留在传递的局部变量中,因为从外部函数返回后,变量将再次消失。

从根本上说,根本的区别是全局变量始终存在并在程序运行的整个过程中都占据空间,而局部变量仅在创建它们的函数返回时才这样做-但是函数参数就像函数的局部变量一样,因此将变量传递给另一个函数会创建第二个副本。 因此,它总是有两个方面。

但是,随着复杂性的增加,我肯定会使用类(按其职责划分)以及成员或静态变量以及相应的方法,而不仅仅是一堆全局变量。

这样一来,您仍然可以将所有事物紧密地联系在一起,而不仅仅是在全球空间中松散地徘徊,而且您不会浪费内存。

我认为添加引用不会增加任何开销; 请记住,编译器并不局限于将其实现为指针。 如果所有内容都在同一编译单元中,则可能可以对其进行优化。 几乎可以肯定的是,如果函数很小,则可以内联。

如果设计允许,则使这些函数和变量属于同一类的另一种可能性。

但归根结底,封装主要存在,因此,通过转移程序员团队,可以在一个月或几十年的时间内维护复杂的项目。 如果只有一个小代码,您将永远看不到,那么就不必过多地与良好实践联系在一起。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM