[導讀] 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(vid)
{
return sensor_value;
}
這里定義其頭文件,比如sensor.h
#ifdef __SENSOR_H__
#define __SENSOR_H__
void update_sensor_exe(void);
#endif
用一個UML圖來描述一下這個模塊:

這樣使用,是不是有點模塊封裝的意思呢,來總結一下:
對上述代碼稍作總結,對一個使用該模塊的程序員而言來看模塊,就是下面這樣一個視圖:

#include
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=1
fun1=1
fun2=1
fun2=2
對于把函數內部變量定義為static型,個人建議是如某特性只與函數內需求或特性相關,則可以這樣使用,如果不是則不建議將過多變量定義成函數內部靜態變量。當然事無絕對,這個使用起來還是很靈活的。舉個栗子:
void fun()
{
static bool called = false;
if(!called)
{
called = true;
/*應用代碼A*/
.....
}
.....
}
這樣當該函數在第一次運行時,將會調用應用代碼A塊,然后將標志設置為true,由于該變量生命周期為整個程序的生命周期,則該函數下次進入時,將不會調用應用代碼A塊。當然如果把這個標志用模塊靜態變量或者全局變量標記從功能上是一樣的,這樣放入內部的好處是這種需求的scope就是該函數內部,所以作用域與待實現的需求比較好的匹配。
由于C語言不是對象語言,如能很好利用static關鍵字的語言特性,也可以實現些封裝屬性、開放接口的對象思想。當然C語言的對象編程策略絕不僅限于這一點。如能善用一些語言特點將會使代碼變得更加緊湊、優雅。本文做了些簡單示例總結,當然對于軟件大牛而言,則顯得頗為粗淺了。
本文辛苦原創總結,如果覺得有價值也請幫忙點贊/在看/轉發支持,不勝感激!
—END—
