c語言static關鍵字的理解

Devil-wei發表於2019-01-22

static

一、概述

在c語言中static恰當的使用能讓程式更加完美,細節上的嚴謹,程式碼會更好,也更利於程式的維護與擴充套件。

而static使用靈活,且又有兩種完全無關的用法,所以整理總結一下。

二、static的兩種用法:

1、static修飾區域性變數,成為一個區域性靜態變數。

2、static修飾全域性變數與函式,成為靜態全域性變數與靜態函式。

 

三、相關涉及概念

  可能會疑惑,修飾全域性變數與修飾函式怎麼會是一個用法?

  static涉及的東西也比較多,以下有幾個概念需要明白。

 

 1、什麼是儲存類

  簡單的說也就是儲存型別,c中變數是在哪裡存放的?記憶體是怎麼管理的?

  所以記憶體的管理:

①棧:區域性變數,函式呼叫傳參的過程

②堆:動態儲存區,需要程式設計師去申請釋放

③資料段(data段):顯式初始化非零的全域性變數(static修飾顯式初始化非0的區域性變數)

④bss段:顯式初始化為0與未初始化的全域性變數(static修飾顯式初始化為0與未初始化的區域性變數)

⑤text段:程式碼(函式)、只讀資料

 

2、什麼是生命週期

描述變數什麼時候誕生,什麼時候消亡,從誕生到消亡就是這個變數的生命週期。

①區域性變數(棧),生命週期即是進入函式,從變數建立到函式返回時變數死亡。

②全域性變數(data/bss),生命週期是程式執行到程式結束

③堆變數,生命週期是從我們malloc到free

 

3、什麼是作用域

描述變數的作用的程式碼範圍。c的作用域規則是程式碼塊作用域,即是一對花括號{}。

一般的從變數定義到{}結束,即是這個變數的作用域

全域性變數與函式一般是檔案作用域,即作用域是整個.c

 

4、什麼是連結屬性

編譯器將很多原始檔編譯成很多.o檔案後,每個.o檔案裡有符號、程式碼段、data/bss等等的分段,連結器需要通過符號將這些記憶體連結起來。而這些符號就是連結屬性。

c中有三種連結屬性:外連結、內連結、無連結屬性

外連結:外部連結,可以在整個程式(跨檔案)連結。

    普通的函式與全域性變數。

內連結:內部連線,只能在當前.c檔案進行連結。

    static修飾的全域性變數與函式

無連結:沒有連結。

      普通區域性變數 

 

四、具體分析static的兩種用法

1、static修飾區域性變數(靜態區域性變數)與普通區域性變數相比

①靜態區域性變數作用域與連線屬性與普通區域性變數一樣

②儲存類:靜態區域性變數分配在data/bss段,普通區域性變數在棧上。

③生命週期:因為儲存類的不同,靜態區域性變數的生命週期得到延長了,直到程式結束。

所以當區域性靜態變數離開作用域後,並沒有銷燬,而是仍然駐留在記憶體當中,只不過我們不能再對它進行訪問,直到該函式再次被呼叫,並且值不變。

2、static修飾全域性變數函式 與 普通全域性變數普通函式相比

儲存類、生命週期、作用域都一樣

差別在於static修飾全域性變數函式連線屬性是內連線,普通全域性變數普通函式是外連結

就是說static修飾全域性變數函式不能跨檔案訪問呼叫

 

五、補充:為什麼需要這樣?

原因是命名的衝突、一個大工程不是常常不是一個人完成的,難免會遇到全域性變數、函式命名一樣。為了減少這類衝突static是很有用的工具。但是很可惜並不能完全解決,所以我們應該有效的去避免減少此類情況的發生。

如果函式僅僅被同一個原始檔呼叫時,我們就應該宣告該函式為static。

  ……

 


 

 作者:Devil-wei

出處:https://www.cnblogs.com/Devil-wei/

版權宣告:本文版權歸作者,轉載請標註文章作者與出處

相關文章