1579|0

3836

帖子

19

TA的资源

纯净的硅(中级)

楼主
 

单片机沉思录——static [复制链接]

在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。


(1)先来介绍它的第一条也是最重要的一条:隐藏。




当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。


char a = 'A';  
void msg()
{
    printf("Hello\n");
}




下面是main.c的内容


int main(void)
{   
    extern char a;    // extern variable must be declared before use
    printf("%c ", a);
    (void)msg();
    return 0;
}

程序的运行结果是:


A Hello


你可能会问:为什么在a.c中定义的全局变量a和函数msg能在main.c中使用?前面说过,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。此例中,a是全局变量,msg是函数,并且都没有加static前缀,因此对于另外的源文件main.c是可见的。


如果加了static,就会对其它源文件隐藏。例如在a和msg的定义前加上static,main.c就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。Static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用。


(2)static的第二个作用是保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。虽然这种用法不常见,但我还是举一个例子。
#include


int fun(void){
    static int count = 10;    // 事实上此赋值语句从来没有执行过
    return count--;
}


int count = 1;


int main(void)
{   
    printf("global\t\tlocal static\n");
    for(; count <= 10; ++count)
        printf("%d\t\t%d\n", count, fun());   
   
    return 0;
}

程序的运行结果是:


global          local static


1               10


2               9


3               8


4               7


5               6


6               5


7               4


8               3


9               2


10              1



(3)static的第三个作用是默认初始化为0。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵,我们可以一个一个地把所有元素都置0,然后把不是0的几个元素赋值。如果定义成静态的,就省去了一开始置0的操作。再比如要把一个字符数组当字符串来用,但又觉得每次在字符数组末尾加’\0’太麻烦。如果把字符串定义成静态的,就省去了这个麻烦,因为那里本来就是’\0’。不妨做个小实验验证一下。


#include


int a;


int main(void)
{
    int i;
    static char str[10];


    printf("integer: %d;  string: (begin)%s(end)", a, str);


    return 0;
}
程序的运行结果如下
integer: 0; string: (begin)(end)


最后对static的三条作用做一句话总结。首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0。






例如:


/*-----------------------------------------------


  名称:99秒倒计时器


  日期:2009.5


  修改:无


  内容:通过定时器倒计时


------------------------------------------------*/


#include     //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义


code unsigned char tab[]=


{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};


          //共阴数码管 0-9


unsigned char Dis_qainwei;


unsigned char Dis_baiwei;


unsigned char Dis_Shiwei;//定义十位


unsigned char Dis_Gewei; //定义个位


/******************************************************************/


/*                    延时函数                                    */


/******************************************************************/


void delay(unsigned int cnt)


{


while(--cnt);


}


/******************************************************************/


/*                    主函数                                      */


/******************************************************************/


main()


{


TMOD |=0x01;//定时器设置 10ms in 12M crystal,工作在模式1,16位定时


  TH0=(65536-50000)/256;


  TL0=(65536-50000)%256;


IE= 0x82;  //打开中断


TR0=1;     //打开定时开关


while(1)


  {


  P0=Dis_qainwei;


  P2=0;


  delay(300);   


  P0=Dis_baiwei;


  P2=1;


  delay(300);   


  P0=Dis_Shiwei;


  P2=2;   


  delay(300);   


  P0=Dis_Gewei;  


  P2=3;


  delay(300);








  }


}


/******************************************************************/


/*                    定时器中断函数                              */


/******************************************************************/


void tim(void) interrupt 1 using 1


{


static unsigned long second=9999,count; //初值99  static相当重要,否则不能减数


  TH0=(65536-50000)/256;


  TL0=(65536-50000)%256;


count++;


if (count==10)


    {


    count=0;


    second--;//秒减1


if(second==0)


  


   second=9999;  


   


Dis_qainwei=tab[second/1000] ;


Dis_baiwei=tab[second%1000/100] ;


Dis_Shiwei=tab[second%1000%100/10];//十位显示值处理


     Dis_Gewei=tab[second%10]; //个位显示处理



 
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表