C語言中static學習

以下大多內容均爲轉載自:https://blog.csdn.net/keyeagle/article/details/6708077  感謝網友的分享

一句話:static 修飾的全局變量或函數,不能被外部的文件所引用或訪問。

static的用途面試時會考:1限制變量的作用域,2設置變量的存儲域 ,3限制函數的外部訪問。

  C語言代碼是以文件爲單位來組織的,在一個源程序的所有源文件中,一個外部變量(注意不是局部變量)或者函數只能在一個源程序中定義一次,如果有重複定義的話編譯器就會報錯。伴隨着不同源文件變量和函數之間的相互引用以及相互獨立的關係,產生了extern和static關鍵字。

        下面,詳細分析一下static關鍵字在編寫程序時有的三大類用法:

        一,static全局變量

           我們知道,一個進程在內存中的佈局如圖1所示:

  其中.text段保存進程所執行的程序二進制文件,.data段保存進程所有的已初始化的全局變量,.bss段保存進程未初始化的全局變量(其他段中還有很多亂七八糟的段,暫且不表)。在進程的整個生命週期中,.data段和.bss段內的數據時跟整個進程同生共死的,也就是在進程結束之後這些數據纔會壽終就寢。

     當一個進程的全局變量被聲明爲static之後,它的中文名叫靜態全局變量。靜態全局變量和其他的全局變量的存儲地點並沒有區別,都是在.data段(已初始化)或者.bss段(未初始化)內,但是它只在定義它的源文件內有效,其他源文件無法訪問它。所以,普通全局變量穿上static外衣後,它就變成了新娘,已心有所屬,只能被定義它的源文件(新郎)中的變量或函數訪問。

舉例說明: file1.c中定義了兩個全局變量,一個有static 修飾,一個沒有

#include"pch.h"
#include"file1.h"
static const char* hello = "hello C/C++";
const char* G_Hello = "global hello";

void printStr() {
    printf("%s\n", hello);
}

//其它文件
#include "pch.h"
#include"file1.h"
extern  const char* hello;       //不可以引用file1.c中的此變量,編譯報錯
extern  const char* G_Hello;   //可以引用file1.c中的此變量

二,static局部變量

      普通的局部變量在棧空間上分配,這個局部變量所在的函數被多次調用時,每次調用這個局部變量在棧上的位置都不一定相同。局部變量也可以在堆上動態分配,但是記得使用完這個堆空間後要釋放之。

       static局部變量中文名叫靜態局部變量。它與普通的局部變量比起來有如下幾個區別:

           1)位置:靜態局部變量被編譯器放在全局存儲區.data(注意:不在.bss段內,原因見3)),所以它雖然是局部的,但是在程序的整個生命週期中存在。

           2)訪問權限:靜態局部變量只能被其作用域內的變量或函數訪問。也就是說雖然它會在程序的整個生命週期中存在,由於它是static的,它不能被其他的函數和源文件訪問。

           3)值:靜態局部變量如果沒有被用戶初始化,則會被編譯器自動賦值爲0,以後每次調用靜態局部變量的時候都用上次調用後的值。這個比較好理解,每次函數調用靜態局部變量的時候都修改它然後離開,下次讀的時候從全局存儲區讀出的靜態局部變量就是上次修改後的值。
以下是一些示例程序:

     file1.h的內容和上例中的相同,file1.c的內容如下:

#include"pch.h"
#include"file1.h"
static const char* hello = "hello C/C++";
const char* G_Hello = "global hello";

void printStr() {
    static int stad=0;
    int ad = 0;
    printf("stad=%d   ad=%d\n", stad,ad);
    stad++;
    ad++;
    //printf("%s\n", hello);
}

main  函數內代碼,執行結果。

int main()
{

    printStr(); // 
    printStr(); // 
    printStr(); // 

    //執行結果是
    //stad=0   ad=0
    //stad=1   ad=0
    //stad=2   ad=0
 

可以看出,函數每次被調用,普通局部變量都是重新分配,而靜態局部變量保持上次調用的值不變。

需要注意的是由於static局部變量的這種特性,使得含靜態局部變量的函數變得不可重入,即每次調用可能會產生不同的結果。這在多線程編程時可能會成爲一種隱患。需要多加註意。

 

三,static函數
              相信大家還記得C++面向對象編程中的private函數,私有函數只有該類的成員變量或成員函數可以訪問。在C語言中,也有“private函數”,它就是接下來要說的static函數,完成面向對象編程中private函數的功能。

            當你的程序中有很多個源文件的時候,你肯定會讓某個源文件只提供一些外界需要的接口,其他的函數可能是爲了實現這些接口而編寫,這些其他的函數你可能並不希望被外界(非本源文件)所看到,這時候就可以用static修飾這些“其他的函數”。

           所以static函數的作用域是本源文件,把它想象爲面向對象中的private函數就可以了。

例子就不寫了。
原文:https://blog.csdn.net/keyeagle/article/details/6708077 
 

 

 

 

 

 

 

 

 

 

--------------------- 
作者:keyeagle 
來源:CSDN 
原文:https://blog.csdn.net/keyeagle/article/details/6708077 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章