https://blog.csdn.net/guotianqing/article/details/79828100概述
static關(guān)鍵字在c語(yǔ)言中比較常用,使用恰當(dāng)能夠大大提高程序的模塊化特性,有利于擴(kuò)展和維護(hù)。
但是對(duì)于c語(yǔ)言初學(xué)者,static由于使用靈活,并不容易掌握。本文就static在c語(yǔ)言中的應(yīng)用進(jìn)行總結(jié),供參考使用。錯(cuò)漏之處,請(qǐng)不吝指正。
在程序中使用static
變量
1. 局部變量
普通局部變量是再熟悉不過的變量了,在任何一個(gè)函數(shù)內(nèi)部定義的變量(不加static修飾符)都屬于這個(gè)范疇。編譯器一般不對(duì)普通局部變量進(jìn)行初始化,也就是說它的值在初始時(shí)是不確定的,除非對(duì)其顯式賦值。
普通局部變量存儲(chǔ)于進(jìn)程棧空間,使用完畢會(huì)立即釋放。
靜態(tài)局部變量使用static修飾符定義,即使在聲明時(shí)未賦初值,編譯器也會(huì)把它初始化為0。且靜態(tài)局部變量存儲(chǔ)于進(jìn)程的全局?jǐn)?shù)據(jù)區(qū),即使函數(shù)返回,它的值也會(huì)保持不變。
變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存空間;編譯器自動(dòng)對(duì)其初始化
其作用域?yàn)榫植孔饔糜颍?dāng)定義它的函數(shù)結(jié)束時(shí),其作用域隨之結(jié)束
小程序體會(huì)一下靜態(tài)局部變量的威力:
#include <stdio.h>
void fn(void)
{
int n = 10;
printf("n=%d\n", n);
n++;
printf("n++=%d\n", n);
}
void fn_static(void)
{
static int n = 10;
printf("static n=%d\n", n);
n++;
printf("n++=%d\n", n);
}
int main(void)
{
fn();
printf("--------------------\n");
fn_static();
printf("--------------------\n");
fn();
printf("--------------------\n");
fn_static();
return 0;
}
運(yùn)行結(jié)果如下:
-> % ./a.out
n=10
n++=11
--------------------
static n=10
n++=11
--------------------
n=10
n++=11
--------------------
static n=11
n++=12
可見,靜態(tài)局部變量的效果跟全局變量有一拼,但是位于函數(shù)體內(nèi)部,就極有利于程序的模塊化了。
2. 全局變量
全局變量定義在函數(shù)體外部,在全局?jǐn)?shù)據(jù)區(qū)分配存儲(chǔ)空間,且編譯器會(huì)自動(dòng)對(duì)其初始化。
普通全局變量對(duì)整個(gè)工程可見,其他文件可以使用extern外部聲明后直接使用。也就是說其他文件不能再定義一個(gè)與其相同名字的變量了(否則編譯器會(huì)認(rèn)為它們是同一個(gè)變量)。
靜態(tài)全局變量?jī)H對(duì)當(dāng)前文件可見,其他文件不可訪問,其他文件可以定義與其同名的變量,兩者互不影響。
在定義不需要與其他文件共享的全局變量時(shí),加上static關(guān)鍵字能夠有效地降低程序模塊之間的耦合,避免不同文件同名變量的沖突,且不會(huì)誤使用。
函數(shù)
函數(shù)的使用方式與全局變量類似,在函數(shù)的返回類型前加上static,就是靜態(tài)函數(shù)。其特性如下:
- 靜態(tài)函數(shù)只能在聲明它的文件中可見,其他文件不能引用該函數(shù)
- 不同的文件可以使用相同名字的靜態(tài)函數(shù),互不影響
非靜態(tài)函數(shù)可以在另一個(gè)文件中直接引用,甚至不必使用extern聲明
下面兩個(gè)文件的例子說明使用static聲明的函數(shù)不能被另一個(gè)文件引用:
/* file1.c */
#include <stdio.h>
static void fun(void)
{
printf("hello from fun.\n");
}
int main(void)
{
fun();
fun1();
return 0;
}
/* file2.c */
#include <stdio.h>
static void fun1(void)
{
printf("hello from static fun1.\n");
}
使用 gcc file1.c file2.c 編譯時(shí),錯(cuò)誤報(bào)告如下:
/tmp/cc2VMzGR.o:在函數(shù)‘main’中:
static_fun.c:(.text+0x20):對(duì)‘fun1’未定義的引用
collect2: error: ld returned 1 exit status
修改文件,不使用static修飾符,可在另一文件中引用該函數(shù):
/* file1.c */
#include <stdio.h>
void fun(void)
{
printf("hello from fun.\n");
}
/* file2.c */
int main(void)
{
fun();
return 0;
}
同樣使用 gcc file1.c file2.c 編譯,編譯通過,運(yùn)行結(jié)果如下:
-> % ./a.out
hello from fun.
面向?qū)ο?/h4>
靜態(tài)數(shù)據(jù)成員
在類內(nèi)數(shù)據(jù)成員的聲明前加上static關(guān)鍵字,該數(shù)據(jù)成員就是類內(nèi)的靜態(tài)數(shù)據(jù)成員。其特點(diǎn)如下:
- 靜態(tài)數(shù)據(jù)成員存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū),靜態(tài)數(shù)據(jù)成員在定義時(shí)分配存儲(chǔ)空間,所以不能在類聲明中定義
- 靜態(tài)數(shù)據(jù)成員是類的成員,無論定義了多少個(gè)類的對(duì)象,靜態(tài)數(shù)據(jù)成員的拷貝只有一個(gè),且對(duì)該類的所有對(duì)象可見。也就是說任一對(duì)象都可以對(duì)靜態(tài)數(shù)據(jù)成員進(jìn)行操作。而對(duì)于非靜態(tài)數(shù)據(jù)成員,每個(gè)對(duì)象都有自己的一份拷貝。
- 由于上面的原因,靜態(tài)數(shù)據(jù)成員不屬于任何對(duì)象,在沒有類的實(shí)例時(shí)其作用域就可見,在沒有任何對(duì)象時(shí),就可以進(jìn)行操作
- 和普通數(shù)據(jù)成員一樣,靜態(tài)數(shù)據(jù)成員也遵從
public, protected, private 訪問規(guī)則
- 靜態(tài)數(shù)據(jù)成員的初始化格式:
<數(shù)據(jù)類型><類名>::<靜態(tài)數(shù)據(jù)成員名>=<值>
- 類的靜態(tài)數(shù)據(jù)成員有兩種訪問方式:
<類對(duì)象名>.<靜態(tài)數(shù)據(jù)成員名> 或 <類類型名>::<靜態(tài)數(shù)據(jù)成員名>
同全局變量相比,使用靜態(tài)數(shù)據(jù)成員有兩個(gè)優(yōu)勢(shì):
- 靜態(tài)數(shù)據(jù)成員沒有進(jìn)入程序的全局名字空間,因此不存在與程序中其它全局名字沖突的可能性
- 可以實(shí)現(xiàn)信息隱藏。靜態(tài)數(shù)據(jù)成員可以是private成員,而全局變量不能
靜態(tài)成員函數(shù)
與靜態(tài)數(shù)據(jù)成員類似,靜態(tài)成員函數(shù)屬于整個(gè)類,而不是某一個(gè)對(duì)象,其特性如下:
- 靜態(tài)成員函數(shù)沒有this指針,它無法訪問屬于類對(duì)象的非靜態(tài)數(shù)據(jù)成員,也無法訪問非靜態(tài)成員函數(shù),它只能調(diào)用其余的靜態(tài)成員函數(shù)
- 出現(xiàn)在類體外的函數(shù)定義不能指定關(guān)鍵字static
- 非靜態(tài)成員函數(shù)可以任意地訪問靜態(tài)成員函數(shù)和靜態(tài)數(shù)據(jù)成員
總結(jié)
static是一個(gè)很有用的關(guān)鍵字,使用得當(dāng)可以使程序錦上添花。當(dāng)然,有的公司編碼規(guī)范明確規(guī)定只用于本文件的函數(shù)要全部使用static關(guān)鍵字聲明,這是一個(gè)良好的編碼風(fēng)格。
無論如何,要在實(shí)際編碼時(shí)注意自己的編碼習(xí)慣,盡量體現(xiàn)出語(yǔ)言本身的優(yōu)雅和編碼者的編碼素質(zhì)。
|