在哪里为全局变量,初始化或在函数中赋值

时间:2015-01-15 07:25:42

标签: c embedded

我有两个功能。哪一个更好,为什么?我想在嵌入式系统中运行该程序。

1

int Flag = 1;
void main(void) {
    /* main body goes here */
}

2

int Flag;
void main(void) {
    Flag = 1;
    /* main body goes here */
}

4 个答案:

答案 0 :(得分:2)

首先,你根本不应该使用全局(见A Pox on Globals)。

但是,如果你坚持,你应该首先确保变量在整个生命周期中都有一个有效值,无论代码是如何维护的,以及首次访问它的位置和时间。第二部分介绍了一个维护问题,即数据名称或类型的更改以及变量的添加或删除需要在两个地方进行必要的更改。

另一个问题是,虽然该变量的初始值为零,但语言定义的某些嵌入式运行时间可选择优化"通过不将全局和静态数据初始化为零来启动。

答案 1 :(得分:0)

第一个在运行时执行的代码较少,但成本是对一个不可测量的全局变量的一个分配。

在这种情况下,假设main()是嵌入式系统的入口点,那么Flag只需要设置一次,而且最好在初始化时完成。

但是,如果您正在处理另一个函数,请将其称为somefunc(),从main()调用(直接或间接)),您需要Flag为{{ 1}}在1的每个条目上调用查看somefunc()中的值的其他函数之前,您需要在Flag的顶部指定Flag

我假设您的嵌入式环境明确支持somefunc() - 标准需要return type of main() to be int,除非实现支持其他类型(并且嵌入式系统可能与此不同)。

答案 2 :(得分:0)

int Flag = 1;
void main(void) {
    /* main body goes here */
}

这里的内存是在数据段中分配的,并且该内存一直存在到程序结束之前,所以如果仅在Flag

中需要main(),则这是不必要的。

然后你可以做

void main(void) {
    int Flag = 1;
    /* main body goes here */
}

现在变量Flag在堆栈上分配了内存并在main()中使用,变量的范围在main()

之内

现在你的问题:

  

哪一个更好,为什么?

正如我在评论中所说,代码中显示的代码片段对内存利用率没有任何影响,并且正如已经说过的那样,第一个代码片段在执行时的指令较少,因为没有赋值语句{{1}在int Flag =1内,第二个有这个assignemnt,这个语句会有额外的执行。

答案 3 :(得分:0)

对于此特定情况,请使用int Flag = 1;

当您逐个初始化变量时,它完全没有意义,因为初始化它的代码最终会占用尽可能多的.data来完成任务。

当您从循环生成查找表并希望最小化二进制大小(如果您的闪存有限)时,

int lookup_table[8192];是有意义的,因为没有任何内容添加到您的二进制文件中。一个很好的例子是一个经常使用的8k查找表,涉及慢速函数(例如浮点三角函数),可以在启动时循环初始化一次,这样8k * sizoeof(int)表就不会存储在二进制文件。 (参见各种mp3解码器实现示例)

注意:查找表的循环初始化仍将占用尽可能多的内存,并且在第一次使用(并因此初始化)时需要额外的启动时间,但会减少二进制大小并且可以< / em>实际上减少了启动时间,如果特定的表很大并且不常用。

如果您使用的是具有大量XIP(就地执行)闪存的嵌入式系统,那么

int lookup_table[8192] = { ... };是有意义的。预生成不仅可以消除额外的启动时间,而且由于它是XIP,因此不会使用RAM,但代价是更大的二进制文件。