|
[导读] static的用法对于很多刚刚开始接触开发的朋友来说,可能没理解其真正的用途,虽说这个是老生常谈的话题,但这也是高频面试要点,所以本文来聊聊。 最近有点小忙,更文慢了些,抱歉。 先谈存储类型存储类型表示变量的可见性和位置。它告诉可以从代码的哪一部分访问变量。存储类用于描述以下内容:
那么有哪些存储类型呢?下面几个词是C语言描述存储类型的关键字:
static用在文件中修饰变量,如下代码: /*这是某模块文件,比如叫senor.c*/#include "sensor.h" static float sensor_value; static float filter(float in) { float out; /*这里实现滤波计算*/ ...... return out; } void update_sensor_exe(void) { float temp = adc_read(); sensor_value = fileter(temp); } float get_sensor_value(void) { return sensor_value; } 这里定义其头文件,比如sensor.h #ifdef __SENSOR_H__#define __SENSOR_H__ void update_sensor_exe(void); #endif 用一个UML图来描述一下这个模块:
这样使用,是不是有点模块封装的意思呢,来总结一下:
对上述代码稍作总结,对一个使用该模块的程序员而言来看模块,就是下面这样一个视图:
int fun1() { int count = 0; count++; return count; } int fun2() { static int count = 0; count++; return count; } int main() { printf("fun1=%d\n", fun1()); printf("fun1=%d\n", fun1()); printf("fun2=%d\n", fun2()); printf("fun2=%d\n", fun2()); return 0; } 由于一个自动型变量,一个是静态变量,存储位置不一样,生命周期也不一样,所以运行结果也不一样。 fun1=1fun1=1 fun2=1 fun2=2 对于把函数内部变量定义为static型,个人建议是如某特性只与函数内需求或特性相关,则可以这样使用,如果不是则不建议将过多变量定义成函数内部静态变量。当然事无绝对,这个使用起来还是很灵活的。举个栗子:
{ static bool called = false; if(!called) { called = true; /*应用代码A*/ ..... } ..... } 这样当该函数在第一次运行时,将会调用应用代码A块,然后将标志设置为true,由于该变量生命周期为整个程序的生命周期,则该函数下次进入时,将不会调用应用代码A块。当然如果把这个标志用模块静态变量或者全局变量标记从功能上是一样的,这样放入内部的好处是这种需求的scope就是该函数内部,所以作用域与待实现的需求比较好的匹配。 总结一下由于C语言不是对象语言,如能很好利用static关键字的语言特性,也可以实现些封装属性、开放接口的对象思想。当然C语言的对象编程策略绝不仅限于这一点。如能善用一些语言特点将会使代码变得更加紧凑、优雅。本文做了些简单示例总结,当然对于软件大牛而言,则显得颇为粗浅了。 |
微信公众号
手机版