汗颜呀,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只是用来限制文件中函数和变量的作用域、函数体内变量的作用域,同时对变量还起到不消亡的作用。
我还真的想不到还能用在复合语句内对变量定义使之“不消亡”
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
41条回答
lmly
1楼-- · 2020-01-30 23:41
一般来说某函数内的局部变量只有在其函数内才有意义,调用此函数时会自动给局部变量分配内存,退出此函数后,局部变量的储存空间可以再次分配给其他数据,而不会保留,如果用static限制后,说明此变量时静态变量,在系统内会一直占据内存,而不会随着函数的退出而消失。
twitter
2楼-- · 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这样的编译器也会自动识别判断其实际的有效范围,而减少其生存期。
wctmdgcd
3楼-- · 2020-01-31 01:38
 精彩回答 2  元偷偷看……
sco518
4楼-- · 2020-01-31 04:27
twitter 发表于 2013-5-10 13:09
从我的理解上,按代码块限定局部变量有效范围有2个意义:

1. 从语法功能上说,能够使局部变量有效范围粒 ...

您讲的确实有道理,不过您的实验中用的并不是static, 我想如果是用static,结果就不一样了。 还有一个问题,一般我们定义一个函数,它里面的变量最好是不要有冗余,并且都是必需的,相关的,那样更有利于程序的可读性。您举的例子中,p,q两个变量本身就没有相关性,第一种做法相当于是两个函数放在一个函数里,一个函数的外壳,其实里面是两个函数,这是正常合理的做法,而第二种做法就是有冗余的函数了,也就是说,第二种做法本身就不太合理。

不过总的来说,您提醒了我们寄存器和堆栈的区别,谢谢您的讲解。
alengend
5楼-- · 2020-01-31 09:27
学习了,好多东西平时没有仔细的去思考过,其实这里面大有学问
nongxiaoming
6楼-- · 2020-01-31 14:17
好吧,你还不知道能怎么用?
你应该看看
  1. void test1(int a)
  2. {
  3.   static int sum=0;
  4.   sum+=a;
  5. printf("sum:%d ",sum);
  6. }
  7. void test2(int a)
  8. {
  9.   int sum=0;
  10.   sum+=a;
  11. printf("sum:%d ",sum);
  12. }
复制代码这两个调用几次看看结果有什么区别。

一周热门 更多>