汗颜呀,static还能这样用。

2020-01-27 11:50发布

  1. void Init_system(void) REENTRANT
  2. {
  3.          unsigned char i;
  4.         P1=255;
  5.        if(i==0)
  6.             {
  7.                  static unsigned char b=25;
  8.                  b++;      //前后多次调用Init_system()函数,此处b的值会作累积。
  9.                  P1=b;
  10.             }
  11.        else
  12.            {
  13.                  P1=0;
  14.            }
  15.       TMOD &= 0xF0;
  16.       TMOD |= 0x01;
  17.       TH0 = TIMER_20MS_TH0;
  18.       TL0 = TIMER_20MS_TL0;
  19.       ET0 = 0;
  20.       EA=0;
  21.      TR0 = 0;
  22. }
复制代码且看上面的代码。
我一直以为static只是用来限制文件中函数和变量的作用域、函数体内变量的作用域,同时对变量还起到不消亡的作用。
我还真的想不到还能用在复合语句内对变量定义使之“不消亡”
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
42条回答
twitter
2020-01-31 01:26
本帖最后由 twitter 于 2013-5-10 13:14 编辑
sco518 发表于 2013-5-9 12:30

test2.png (28.09 KB, 下载次数: 0)

下载附件

test2

2013-5-10 12:45 上传



这两个函数的区别就在于p、q的有效范围,可以看到:

test1() 中的p、q是共用了R5,因为 p 的有效范围在块外已经结束了(或者说生存期结束了),所以下面编译器又把R5分配给了q。

test2() 中的p、q是分别使用了R5、R6,因为两者在整个函数块范围内都有效。

因为这两个函数用到的局部变量不多,所以ARM的通用寄存器是够用的。但当局部变量增多后,编译器必然得使用栈,RISC最快的指令一般都是寄存器之间的操作,而栈却需要访问内存空间,用到栈就意味着速度的下降(虽然就现在MHz级别的时钟来说是很微小,但内存的速度却不一定能那么快)。所以如果能让局部变量有效范围提前结束,那么就能更多地复用寄存器,而不是用栈。

当然,现在的编译器优化能力是非常出 {MOD}的,比如用 avr gcc 的新手经常会发现局部变量无法监视,一般就是因为优化后局部变量的生存期变短了,寄存器被反复地复用。即使局部变量有效范围是定义在函数块级别,像gcc这样的编译器也会自动识别判断其实际的有效范围,而减少其生存期。

一周热门 更多>