C/C++的static關(guān)鍵字作用

一、限制符號(hào)的作用域只在本程序文件

  • 若變量或函數(shù)(統(tǒng)稱符號(hào))使用static修飾,則只能在本程序文件內(nèi)使用,其他程序文件不能調(diào)用(非static的可以通過(guò)extern 關(guān)鍵字聲明該變量是在其他文件內(nèi)定義的,此文件可調(diào)用)。不加static修飾的,則默認(rèn)是可以被其他程序文件調(diào)用的。
  • 本程序文件內(nèi)的非static函數(shù)也可以隨意調(diào)用static的變量和函數(shù)。只是限制了外部程序文件的函數(shù)不能調(diào)用。

原理:默認(rèn)的變量和函數(shù)名(統(tǒng)一稱為符號(hào))在編譯成匯編代碼.s文件時(shí),會(huì)有.globl func_name,.globl指示告訴匯編器,func_name這個(gè)符號(hào)要被鏈接器用到(匯編文件在經(jīng)過(guò)匯編器處理成二進(jìn)制的.o文件時(shí),符號(hào)會(huì)被變量或函數(shù)實(shí)際的地址值代替),所以要在目標(biāo)文件的符號(hào)表中標(biāo)記它是一個(gè)全局符號(hào)。如果一個(gè)符號(hào)沒(méi)有用.globl聲明,就表示這個(gè)符號(hào)不會(huì)被鏈接器用到。而static關(guān)鍵字修飾的符號(hào)在編譯成匯編代碼.s文件時(shí),就不會(huì)被.globl聲明,因此不會(huì)參與后序鏈接就不會(huì)被其他程序文件調(diào)用到。
(不同程序文件的函數(shù)變量互相調(diào)用是在鏈接各個(gè).o文件步驟后進(jìn)行的,前面預(yù)編譯、編譯、匯編步驟都是對(duì)單個(gè)程序文件進(jìn)行操作)

二、指定變量的存儲(chǔ)位置

  • 對(duì)于函數(shù)內(nèi)的變量。auto變量(函數(shù)局部變量)都是在棧內(nèi)存區(qū)存放,函數(shù)結(jié)束后就自動(dòng)釋放。但是全局的和函數(shù)內(nèi)定義的static變量都是存放在數(shù)據(jù)區(qū)的,且只存一份,只在整個(gè)程序結(jié)束后才自動(dòng)釋放。
  • 由于static變量只存一份即同一地址,所以不管函數(shù)調(diào)用多少次,函數(shù)內(nèi)定義static變量的語(yǔ)句只會(huì)在第一次調(diào)用時(shí)執(zhí)行,后面調(diào)用都不執(zhí)行也不再初始化,而是對(duì)該地址內(nèi)的數(shù)據(jù)進(jìn)行操作。
#include<iostream>
using namespace std;
void test()
{
    static int a = 1;
    a++;
    cout << a << endl;
    cout << &a << endl;
}
int main
{
    test();
    test();
    test();
    test();
}

輸出:
2
00C90008
3
00C90008
4
00C90008
5
00C90008
//可見地址只有一個(gè)

三、C++類的靜態(tài)成員變量

  • 是屬于類,而不屬于某個(gè)實(shí)例對(duì)象,因此也只有一個(gè)地址保存一份數(shù)據(jù)存放于數(shù)據(jù)區(qū)。在類中只是聲明,并不是定義,因此不分配內(nèi)存,對(duì)類用sizeof求大小也不會(huì)將static變量得大小加入。
  • 必須在類聲明的外部,以及main()函數(shù)的外部,也就是全部變量區(qū)域?qū)︻惖膕tatic成員變量再次定義(定以后才分配唯一內(nèi)存,此時(shí)該類靜態(tài)成員變量相當(dāng)于是全局的靜態(tài)變量了,只是調(diào)用的時(shí)候要使用類名加::)。若只定義不賦值初始化,則默認(rèn)初始化為0。
  • public的靜態(tài)數(shù)據(jù)成員既可以通過(guò)類名引用,也可以通過(guò)對(duì)象名引用(會(huì)自動(dòng)轉(zhuǎn)換成類名引用)。

四、C++類的靜態(tài)成員函數(shù)

  • 只能調(diào)用本類的靜態(tài)成員變量或函數(shù),不能調(diào)用本類的非靜態(tài)成員函數(shù)和變量。因?yàn)榉庆o態(tài)成員函數(shù)和變量在類成員函數(shù)中調(diào)用時(shí),都是由形參中隱含一個(gè)指向當(dāng)前實(shí)例對(duì)象的this指針來(lái)調(diào)用。然而靜態(tài)成員函數(shù)沒(méi)有這個(gè)this形參。
#include<iostream>
using namespace std;

class A
{
private:
    int a;
    static int sa;
public:
    void show()
    {
        cout << sa++ << endl;
    }
    static void s_show()
    {
        //cout << a << endl; //報(bào)錯(cuò),靜態(tài)成員函數(shù)不能調(diào)用非靜態(tài)成員變量。無(wú)法使用this.a
        cout << sa << endl;
        //show();  //報(bào)錯(cuò),靜態(tài)成員函數(shù)不能調(diào)用非靜態(tài)成員函數(shù)。無(wú)法使用this.show()
    }
};
int A::sa = 1;  //只在定義時(shí)可以不受private的限制,可以用類名調(diào)用私有成員。其他時(shí)候不行
                //若不賦初值,則默認(rèn)初始化賦值0

int main()
{
    cout << sizeof(A) << endl;      //輸出結(jié)果為4,并不是8,因?yàn)閟tatic成員變量不占用類的大小,
                                    //在類中只是聲明,而在類外定義并分配內(nèi)存
    //cout << A::sa << endl;    //sa是private私有成員,不能用類名來(lái)訪問(wèn)
    A ca;
    ca.show();
    A::s_show();
}
輸出:
4
1
2
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容