最近在各種語言之間來回編程,容易產生混亂,這裏特意整理下:
一. c語言(面向過程)
在c語言中static 可以修飾變量跟函數,並且修飾後,只在本文件中可見,別的文件中可以使用同名變量或函數。因此添加static 有利於團隊協作中出現命名相同編譯識別的情況。
1. 修飾變量
在介紹修飾變量作用之前,讀者應該要對c程序存儲結構有一定的認知。
(1) 存儲方式:
類別 | 局部變量存儲位置 | 全局變量存儲位置 |
---|---|---|
修飾 | 靜態存儲區(.data段) | 靜態存儲區(.data段) |
不修飾 | 棧(stack) | 靜態存儲區(.data段) |
(2)作用和可見性:
類別 | 局部變量 | 全局變量 |
---|---|---|
修飾 | 函數退出後數據不會清除 | 僅在同文件下全局可見 |
不修飾 | 函數退出後自動清除數據 | 程序內全局可見 |
2. 修飾函數
(1)
類別 | 有無static | 可見性 |
---|---|---|
靜態函數 | 有static | 靜態函數只是在聲明他的文件當中可見,不能被其他文件所用。 |
普通函數 | 無static | 程序內可見,默認自帶extern |
二. 面向對象類語言
在介紹語言修飾作用前,先說明一下,語言發展關係:c (面向過程)—> c++ 、c#、java、go、php、python (面向對象), 從中我們可以看出其他面向對象的語言是由c發展而來的,在存儲和作用上會有一定的相似性。由於面向對象有個共同特點就是增加了類,所以下面主要介紹 staic 對類的影響。
在使用類成員中,我們通常需要創建一個對象,通過對象來訪問類成員。而使用static修飾後會改變訪問方式。this被即爲本對象,成員函數被static修飾之後,不能使用this。
在運用多種編程語言中,可以發現帶static 的 類函數,可以方便被直接調用,而不需要使用new 創建對象。
不過由於類靜態函數不能訪問非靜態函數,因此在某些時候容易產生錯誤。
1. C++
(1)C++ 繼承c語言的面向過程,所以具備c的特性
(2)修飾類成員
語言 | 作用 | 可見性 | 調用格式 |
---|---|---|---|
變量 | 靜態成員變量是每個類有一份,普通成員變量是每個實例有一份 | 變更 | <類名>::<類變量> |
函數 | 靜態成員函數,可以用類名::函數名進行訪問,但無法使用this,僅能訪問類的靜態數據和靜態成員函數。 | 變更 | <類名>::<函數名>或<對象名>.<函數名> |
補充注意點:
- 靜態成員函數不能訪問非靜態(包括成員函數和數據成員),但是非靜態可以訪問靜態。
- 不能將靜態成員函數定義爲虛函數。
- 靜態成員變量地址是指向其數據類型的指針 ,靜態成員函數地址類型是一個“nonmember函數指針”。
- 爲了防止父類的影響,可以在子類定義一個與父類相同的靜態變量,以屏蔽父類的影響。
2. JAVA
(1)簡介
在java語言中類中的函數被稱爲方法。
在《Java編程思想》中有這樣一段話:
“static方法就是沒有this的方法。在static方法內部不能調用非靜態方法,反過來是可以的。而且可以在沒有創建任何對象的前提下,僅僅通過類本身來調用static方法。這實際上正是static方法的主要用途“。這段話雖然只是說明了static方法的特殊之處,但是可以看出static關鍵字的基本作用,簡而言之,一句話來描述就是:
方便在沒有創建對象的情況下來進行調用(方法/變量)。
(2) 其他作用
- static關鍵字還有一個比較關鍵的作用就是 用來形成靜態代碼塊以優化程序性能。static塊可以置於類中的任何地方,類中可以有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每個static塊,並且只會執行一次。
class 類名{
private String test;
static{
test = "test";
}
}
- static是不允許用來修飾局部變量。
- static關鍵字不會影響到變量或者方法的作用域。在Java中能夠影響到訪問權限的只有private、public、protected(包括包訪問權限)
3. 其他語言
基本上大同小異