C 之static的應用

2022-08-25 20:00:20 字數 3718 閱讀 7464

static關鍵字是c, c++中都存在的關鍵字, 它主要有三種使用方式, 其中前兩種在c/c++語言中使用, 第三種只在c++中使用

(1)區域性靜態變數

(2)外部靜態變數/函式

(3)靜態資料成員/成員函式

一、區域性靜態變數

在c/c++中, 區域性變數按照儲存形式可分為三種auto, static, register

與auto型別(普通)區域性變數相比, static區域性變數有三點不同

1. 儲存空間分配不同

auto型別分配在棧上, 屬於動態儲存類別, 佔動態儲存區空間, 函式呼叫結束後自動釋放, 而static分配在靜

態儲存區

, 在程式整個執行期間都不釋放. 兩者之間的作用域相同, 但生存期不同.

2. static區域性變數在所處模組在初次執行時進行初始化工作, 且只操作一次

3. 對於區域性靜態變數, 如果不賦初值, 編譯期會自動賦初值0或空字元, 而auto型別的初值是不確定的. (對於c++中的class物件例外, class的物件例項如果不初始化, 則會自動呼叫預設建構函式, 不管是否是static型別)

特點: static區域性變數的」記憶性」與生存期的」全域性性」

所謂」記憶性」是指在兩次函式呼叫時, 在第二次呼叫進入時, 能保持第一次呼叫退出時的值.

示例程式一

#include

using namespace std;

void staticlocalvar()

int main()

注意事項:

1. 「記憶性」, 程式執行很重要的一點就是可重複性, 而static變數的」記憶性」破壞了這種可重複性, 造成不同時刻至執行的結果可能不同.

2. 「生存期」全域性性和唯一性. 普通的local變數的儲存空間分配在stack上, 因此每次呼叫函式時, 分配的空間都可能不一樣, 而static具有全域性唯一性的特點, 每次呼叫時, 都指向同一塊記憶體, 這就造成乙個很重要的問題 ---- 不可重入性!!!

二、外部靜態變數/函式

在c中static有了第二種含義:用來表示不能被其它檔案訪問的全域性變數和函式。, 但為了限制全域性變數/函式的作用域, 函式或變數前加static使得函式成為靜態函式。但此處「static」的含義不是指儲存方式,而是指對函式的作用域僅侷限於本檔案(所以又稱內部函式)。注意此時, 對於外部(全域性)變數, 不論是否有static限制, 它的儲存區域都是在靜態儲存區, 生存期都是全域性的. 此時的static只是起作用域限制作用, 限定作用域在本模組(檔案)內部.

使用內部函式的好處是:不同的人編寫不同的函式時,不用擔心自己定義的函式,是否會與其它檔案中的函式同名。

示例程式三:

static int vara;

int varb;

extern void funa()

static void funb()

extern int varb; // 使用file1.cpp中定義的全域性變數

extern int vara; // 錯誤! vara是static型別, 無法在其他檔案中使用

extern vod funa(); // 使用file1.cpp中定義的函式

extern void funb(); // 錯誤! 無法使用file1.cpp檔案中static函式

關於extern的知識

extern可以置於變數或者函式前,以表示變數或者函式的定義在別的檔案中,提示編譯器

遇到此變數和函式時在其他模組中尋找其定義

三、靜態資料成員/成員函式(c++特有)

靜態成員變數:

對於所有的物件共有乙個成員變數的就用static ,提供乙個所有物件共有的乙個成員變數比「每乙個類物件維護乙個成員變數」 要更有效。

在這種情況下類的靜態資料成員提供了乙個更好的方案靜態資料成員被當作該類型別的全域性物件,對於非靜態資料成員,每個類物件都有自己的拷貝而靜態資料成員對每個類型別只有乙個拷貝靜態資料成員,只有乙份由該類型別的所有物件共享訪問。同全域性物件相比使用靜態資料成員有兩個優勢 1 靜態資料成員沒有進入程式的全域性名字空間因此不存在與程式中其他全域性名字衝突的可能性 2 可以實現資訊隱藏靜態成員可以是private 成員而全域性物件不能 在類體中的資料成員宣告前面加上關鍵字static 就使該資料成員成為靜態的static 資料成員,遵從public/private/protected 訪問規則,例如在下面定義的account 類中_interestrate是被宣告為double 型的私有靜態成員

class account

static double getrate() private: static double _interestrate; double _amount; string  _owner; };

為什麼把_interestrate 宣告為static 而_amount 和_owner 不呢,這是因為每個account對應不同的主人有不同數目的錢而所有account 的利率卻是相同的,因為在整個程式中只有乙個_interestrate 資料成員它被所有account物件共享,所以把_interestrate宣告為靜態成員,減少每個account物件所需的儲存空間。

靜態成員函式:靜態成員函式一般只能訪問靜態成員變數,如果要訪問非靜態成員變數的話,只能訪問某乙個物件的非靜態成員變數和靜態成員函式。可以傳乙個物件的指標,引用等引數給這個靜態成員函式。

class a

int getia()     static int f(a &aa) private: int m_ia; };

void main() { a aa; cout<

靜態成員函式中是不能呼叫非靜態成員的,包括非靜態成員函式和非靜態成員變數。那麼在非靜態成員函式中是否可以呼叫靜態成員函式呢?答案是肯定的,因為靜態成員函式屬於類本身,在類的物件產生之前就已經存在了,所以在非靜態成員函式中是可以呼叫靜態成員函式的。其實,我們也可以以乙個記憶體模型這個角度來考慮,也就是說,無論採取什麼樣的操作,程式**都是在記憶體中執行的,只有在記憶體中占有了一席之地,我們才能訪問它。如果乙個成員函式或成員變數還沒有在記憶體中產生,結果是無法訪問它的。所有靜態成員函式只能訪問靜態成員變數。(講的真好!!!)

使用static關鍵字宣告的函式成員使靜態的,靜態成員函式同樣也屬於整個類,由同乙個類的所有物件共同維護,為這些物件所共享.     作為成員函式,它的訪問屬性可以受到類的嚴格控制,對於公有的靜態函式成員函式,可以通過類名或物件名來呼叫,但一般情況下建議用物件名來引用靜態函式成員.注意,一般的成員函式只能通過物件名來呼叫.       由於乙個類的靜態成員函式只有乙個拷貝,因此它訪問物件的資料和函式時受到了限制.靜態成員函式可以直接訪問該類的靜態資料成員.而訪問非靜態資料成員, 必須通過引數傳遞方式得到物件名,然後通過物件名來訪問.可以看到,通過靜態函式成員訪問非靜態成員使相當麻煩的,一般的使用中,它主要用來訪問全域性變數或同乙個類中的靜態資料成員,特別是和後者一起使用,達到對同乙個類中物件之間共享的資料進行維護的目的.       建構函式和析構函式不可以定義為static,建構函式要給每乙個物件乙個this指標如果可以是靜態的,它如何構造和訪問this指標? 明顯是不可以的!

靜態成員變數一般要在.cpp檔案裡進行定義:double account::_interestrate = 0.0589;靜態成員函式的宣告除了在類體中的函式宣告前加上關鍵字static 以及不能宣告為const 或volatile 之外與非靜態成員函式相同,出現在類體外的函式定義不能指定關鍵字static.

const string str = "liangxueliang"; account *acc = new account(222222,str); acc->getrate(); account::getrate();

c 中static的應用

不加static修飾的全域性變數,其作用域為整個工程檔案,在定義檔案外,可以通過extern宣告呼叫該變數。當全域性變數新增static修飾後,其作用域就限定在本檔案內,在工程中其他檔案中就算新增extern 宣告也不能呼叫。靜態區域性變數相當於乙個只能被定義函式使用的全域性變數,當函式結束時,其當...

static在C 中的應用

1 案例描述22 static 語法特性簡介 22.1 修飾變數 22.1.1 靜態全域性變數 22.1.2 靜態區域性變數 22.1.3 靜態資料成員 22.2 修飾函式 22.2.1 靜態函式 22.2.2 靜態成員函式33 應用場合 33.1 將變數 函式的作用域限定在本原始檔中 33.2 儲...

Static在C語言中的應用

概念 what static 作用域生命週期 函式 一直存在 定義原始檔 一直存在 內部變數 呼叫完銷毀 函式內 一直存在 外部變數 一直存在 定義原始檔內 一直存在 目的 why l對於函式來講,只有乙個目的,就是限定作用域,禁止當前檔案外的檔案呼叫 l 對於內部變數,僅僅是為了該值能夠永久留存,...