1. 程式人生 > >static修飾的變數及函式

static修飾的變數及函式

轉自http://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html

在C語言中,static的字面意思很容易把我們匯入歧途,其實它的作用有三條。

(1)先來介紹它的第一條也是最重要的一條:隱藏。

當我們同時編譯多個檔案時,所有未加static字首的全域性變數和函式都具有全域性可見性。為理解這句話,我舉例來說明。我們要同時編譯兩個原始檔,一個是a.c,另一個是main.c。

//下面是a.c的內容
char a = 'A'; // global variable
void msg() 
{
    printf("Hello\n"); 
}
 
//下面是main.c的內容
int main(void)
{    
    extern char a;    // extern variable must be declared before use
    printf("%c ", a);
    (void)msg();
    return 0;
}

程式的執行結果是:

A Hello

你可能會問:為什麼在a.c中定義的全域性變數a和函式msg能在main.c中使用?前面說過,所有未加static字首的全域性變數和函式都具有全域性可見性,其它的原始檔也能訪問。此例中,a是全域性變數,msg是函式,並且都沒有加static字首,因此對於另外的原始檔main.c是可見的。

如果加了static,就會對其它原始檔隱藏。例如在a和msg的定義前加上static,main.c就看不到它們了。利用這一特性可以在不同的檔案中定義同名函式和同名變數,而不必擔心命名衝突。Static可以用作函式和變數的字首,對於函式來講,static的作用僅限於隱藏,而對於變數,static還有下面兩個作用。

2static的第二個作用是保持變數內容的持久。儲存在靜態資料區的變數會在程式剛開始執行時就完成初始化,也是唯一的一次初始化。共有兩種變數儲存在靜態儲存區:全域性變數和static變數,只不過和全域性變數比起來,static可以控制變數的可見範圍,說到底static還是用來隱藏的。雖然這種用法不常見,但我還是舉一個例子。
#include <stdio.h>

int fun(void){
    static int count = 10;    // 事實上此賦值語句從來沒有執行過
    return count--;
}

int count = 1;

int main(void)
{    
    printf("global\t\tlocal static\n");
    for(; count <= 10; ++count)
        printf("%d\t\t%d\n", count, fun());    
    
    return 0;
}


程式的執行結果是:

global          local static

1               10

2               9

3               8

4               7

5               6

6               5

7               4

8               3

9               2

10              1

(3)static的第三個作用是預設初始化為0。其實全域性變數也具備這一屬性,因為全域性變數也儲存在靜態資料區。在靜態資料區,記憶體中所有的位元組預設值都是0x00,某些時候這一特點可以減少程式設計師的工作量。比如初始化一個稀疏矩陣,我們可以一個一個地把所有元素都置0,然後把不是0的幾個元素賦值。如果定義成靜態的,就省去了一開始置0的操作。再比如要把一個字元陣列當字串來用,但又覺得每次在字元陣列末尾加’\0’太麻煩。如果把字串定義成靜態的,就省去了這個麻煩,因為那裡本來就是’\0’。不妨做個小實驗驗證一下。

#include <stdio.h>

int a;

int main(void)
{
    int i;
    static char str[10];

    printf("integer: %d;  string: (begin)%s(end)", a, str);

    return 0;
}


程式的執行結果如下

integer: 0; string: (begin)(end)

最後對static的三條作用做一句話總結。首先static的最主要功能是隱藏,其次因為static變數存放在靜態儲存區,所以它具備永續性和預設值0。

轉自http://bbs.csdn.net/topics/350238100

C程式一直由下列部分組成:
  1)正文段——CPU執行的機器指令部分;一個程式只有一個副本;只讀,防止程式由於意外事故而修改自身指令;    
  2)初始化資料段(資料段)——在程式中所有賦了初值的全域性變數,存放在這裡。    
  3)非初始化資料段(bss段)——在程式中沒有初始化的全域性變數;核心將此段初始化為0。     
  4)棧——增長方向:自頂向下增長;自動變數以及每次函式呼叫時所需要儲存的資訊(返回地址;環境資訊)。      
  5)堆——動態儲存分。

全域性變數之前加上關鍵字static,全域性變數就被定義成為一個全域性靜態變數。
   1)記憶體中的位置:靜態儲存區(靜態儲存區在整個程式執行期間都存在)
  2)初始化:未經初始化的全域性靜態變數會被程式自動初始化為0(自動物件的值是任意的,除非他被顯示初始化)
   3)作用域:全域性靜態變數在宣告他的檔案之外是不可見的。準確地講從定義之處開始到檔案結尾。

好處:
定義全域性靜態變數的好處:
<1>不會被其他檔案所訪問,修改
<2>其他檔案中可以使用相同名字的變數,不會發生衝突。

區域性靜態變數
在區域性變數之前加上關鍵字static,區域性變數就被定義成為一個區域性靜態變數。
  1)記憶體中的位置:靜態儲存區
  2)初始化:未經初始化的全域性靜態變數會被程式自動初始化為0(自動物件的值是任意的,除非他被顯示初始化)
  3)作用域:作用域仍為區域性作用域,當定義它的函式或者語句塊結束的時候,作用域隨之結束。

注:當static用來修飾區域性變數的時候,它就改變了區域性變數的儲存位置,從原來的棧中存放改為靜態儲存區。但是區域性靜態變數在離開作用域之後,並沒有被銷燬,而是仍然駐留在記憶體當中,直到程式結束,只不過我們不能再對他進行訪問。
當static用來修飾全域性變數的時候,它就改變了全域性變數的作用域(在宣告他的檔案之外是不可見的),但是沒有改變它的存放位置,還是在靜態儲存區中。

3. 靜態函式
在函式的返回型別前加上關鍵字static,函式就被定義成為靜態函式。
  函式的定義和宣告預設情況下是extern的,但靜態函式只是在宣告他的檔案當中可見,不能被其他檔案所用。
定義靜態函式的好處:
<1> 其他檔案中可以定義相同名字的函式,不會發生衝突
<2> 靜態函式不能被其他檔案所用。 儲存說明符auto,register,extern,static,對應兩種儲存期:自動儲存期和靜態儲存期。 auto和register對應自動儲存期。具有自動儲存期的變數在進入宣告該變數的程式塊時被建立,它在該程式塊活動時存在,退出該程式塊時撤銷。
關鍵字extern和static用來說明具有靜態儲存期的變數和函式。用static宣告的區域性變數具有靜態儲存持續期(static storage duration),或靜態範圍(static extent)。雖然他的值在函式呼叫之間保持有效,但是其名字的可視性仍限制在其區域性域內。靜態區域性物件在程式執行到該物件的宣告處時被首次初始化。
C語言中使用靜態函式的好處:
      靜態函式會被自動分配在一個一直使用的儲存區,直到退出應用程式例項,避免了呼叫函式時壓棧出棧,速度快很多。 
      關鍵字“static”,譯成中文就是“靜態的”,所以內部函式又稱靜態函式。但此處“static”的含義不是指儲存方式,而是指對函式的作用域僅侷限於本檔案。 使用內部函式的好處是:不同的人編寫不同的函式時,不用擔心自己定義的函式,是否會與其它檔案中的函式同名,因為同名也沒有關係。 
c語言中static的語義1.static變數:1).區域性a.靜態區域性變數在函式內定義,生存期為整個源程式,但作用域與自動變數相同,只能在定義該變數的函式內使用。退出該函式後, 儘管該變數還繼續存在,但不能使用它。b.對基本型別的靜態區域性變數若在說明時未賦以初值,則系統自動賦予0值。而對自動變數不賦初值,則其值是不定的。2).全域性全域性變數本身就是靜態儲存方式, 靜態全域性變數當然也是靜態儲存方式。但是他們的作用域,非靜態全域性 變數的作用域是整個源程式(多個原始檔可以共同使用); 而靜態全域性變數則限制了其作用域, 即只在定義該變數的原始檔內有效, 在同一源程式的其它原始檔中不能使用它。2.static函式(也叫內部函式)只能被本檔案中的函式呼叫,而不能被同一程式其它檔案中的函式呼叫。區別於一般的非靜態函式(外部函式)     static在c裡面可以用來修飾變數,也可以用來修飾函式。         先看用來修飾變數的時候。變數在c裡面可分為存在全域性資料區、棧和堆裡。其實我們平時所說的堆疊是棧而不包含對,不要弄混。

相關推薦

詳解 static 修飾變數函式的作用

我們知道,static 關鍵字的作用是宣告靜態變數,但是變數有全域性的,還有區域性的,難道作用都是一樣的嗎? 答案當然是不一樣,究竟有何不同,我們一起來探究一下。 static修飾區域性變數 區域性變數是出現在區域性範圍(程式碼塊內部)的變數,它的生命

static修飾變數函式

轉自http://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html 在C語言中,static的字面意思很容易把我們匯入歧途,其實它的作用有三條。 (1)先來介紹它的第一條也是最重要的一條:隱藏。 當我們同時編譯多

JAVA基礎(49)---staticstatic修飾變數

static 所解決的問題 這裡摘錄一下《Java程式設計思想(第四版)》(《Java核心技術Ⅰ卷/Ⅱ卷》)裡關於static關鍵字的一段原話:(P29)通常來說,當建立類時,就是在描述那個類的物件的外觀與行為 。除非用new建立那個物件,否則,實際上並未獲得任何物件。執行new來建立物

【c語言】static修飾變數

static 1.修飾區域性變數 改變了 生命週期,作用域不發生改變 eg: void test() { int i = 0; i++; printf("%d\n", i); } int main() { int i = 0; for (i =

全域性變數、類靜態變數函式區域性靜態變數的初始化順序

What is the lifetime of class static variables in C++? First the list of possibilities. Namespace Static Class Static Local Static

shell中的變數函式

############################1.變數###################################################簡介:   (1)什麼是變數?        變數即在程式執行過程中它的值是允許改變的量,變數是用一串固定的字

Python Flask,Jinja2模板,模板中使用特殊變數函式,閃現資訊,get_flashed_messages()

  在渲染模板時,不需要手動分配,可以直接在模板中使用的模板變數及函式:config、request、url_for()、get_flashed_messages() 在Flask中,有一些特殊的變數和方法是可以在模板檔案中直接訪問的。 config 物件: config

C語言extern與static修飾變數

extern和static在C語言裡面的作用這裡就不做過多的闡述了,下面直接通過一個小程式來看一看他們修飾的變數的特性。 #include <stdio.h> int count = 3; int main() { int i = 0,

linux——shell變數函式

shell變數 1.變數定義:     變數即在程式執行過程中它的值是允許改變的量,變數是用一串固定的字元來標誌不固定的值的一種方法,變數是一種使用方便的佔位符,用於引用計算機記憶體地址,該地址可以儲存scripts執行時可更改的程式資訊。在she

axure中的變數函式

          axure的變數設定是為了完成一些邏輯上處理,例如從26個字母中隨機取出四個字母作為驗證碼: a.用隨機數定位數字,0-26中隨機找到一個數字 b.根據0-26個位置找出相應的字母 c..4個一組合就可以了。 這個是驗證碼的主頁面:     涉及到區

C/C++變數函式的命名規則

一、C語言變數名的命名規則:(可以字母,數字,下劃線混合使用) 1. 只能以字母或下劃線開始; 2. 不能以數字開始; 3. 一般小寫; 4. 關鍵字不允許用(eg:int float=2//error  float 為保留字不允許用); 二、函式名的命名規則 1.見名知意; 2.自定義函式函式名首字母大寫(

static修飾變數的通過類名呼叫的測驗

package myHomework; public class D21_static { static int s=1512340101; public static void main(S

C語言中被static修飾函式變數

被static修飾的函式可認為是“區域性函式”,只能被本原始碼檔案訪問。而沒有static關鍵字的函式可認為是全域性函式(可在函式前寫上extern,此關鍵字是預設的,所以可不寫),可跨檔案被訪問。st

Static和Final修飾類屬性變數初始化

  1.static修飾一個屬性欄位,那麼這個屬性欄位將成為類本身的資源,public修飾為共有的,可以在類的外部通過test.a來訪問此屬性;在類內部任何地方可以使用.如果被修飾為private私有,那麼只能在類內部使用.

JAVA關鍵字Static作用 特點 利弊建立時機 成員變數和靜態變數 Static修飾成員 修飾方法 修飾塊(靜態快)

(1)Static關鍵字修飾符 可以修飾成員(成員屬性 成員方法)(2)Static修飾成員的特點a 生命週期長 跟類相同b 用Static修飾的變數 所有物件共享c Static修飾變數 可以通過物件(.)點的形式呼叫 還可以通過類名(.)點方法呼叫(3)Static建立時

簡述static關鍵字的作用?(備註:在什麼條件下使用static修飾區域性變數、全域性變數函式)

static關鍵字至少有下列n個作用: (1)設定變數的儲存域,函式體內static變數的作用範圍為該函式體,不同於auto變數,該變數的記憶體只被分配一次,因此其值在下次呼叫時仍維持上次的值; (

對C語言 static作用——修飾 變數(全域性變數/區域性變數)、函式

*******************************概念*********************************************************************************************************

php函式static,global關鍵字三種變數作用域

函式 和js函式類似,關注php與其他語言不用的地方 函式的形參預設值 形式: function f($a,$b=3,$vc = "abc"){ } 注意:沒有給預設值的形參必須傳遞值, 形參的傳值問題 一句話:形參的傳值問題,其實就是“變數

C語言中static修飾函式和普通函式的區別

用static修飾的函式,本限定在本原始碼檔案中,不能被本原始碼檔案以外的程式碼檔案呼叫。而普通的函式,預設是extern的,也就是說,可以被其它程式碼檔案呼叫該函式。 在函式的返回型別前加上關鍵字static,函式就被定義成為靜態函式。普通 函式的定義和宣告預設情況下是extern的,但靜

C語言中變數函式名的命名規則與駝峰命名法

一、C語言變數名的命名規則:(可以字母,數字,下劃線混合使用) 1. 只能以字母或下劃線開始;2. 不能以數字開始;3. 一般小寫;4. 關鍵字不允許用(eg:int float=2//error  float 為保留字不允許用); 二、函式名的命名規則 1.見名知意;2.自定義函式函式名首字