1. 程式人生 > >C語言中的靜態變數和普通變數的區別

C語言中的靜態變數和普通變數的區別

下面用程式碼說明:

一個可執行程式包括BSS段、資料段、程式碼段(文字段)

bss segment ,data segment ,code/text segment

BSS(Block by Start Symbol) :通常指用來存放程式中未初化的全域性變數和靜態變數的一塊記憶體區域。BSS段屬於靜態記憶體分配

     特點是:可讀寫的,在程式執行之前BSS段為自動清零,所以未初始的全域性變數在程式執行之前已經成零了。

資料段:通常用來存放程式中已初始化的全域性變數和靜態變數的一塊記憶體區域。DATA segment 屬於靜態記憶體分配

程式碼段:通常是指用來存放程式程式碼的一塊記憶體區域,這部分割槽域的大小在程式執行前就已確定,並且記憶體區域通常屬於只讀,某些架構允許程式碼段可寫,即可以修改,在程式碼段中,也有可能包含一些只讀的常數變數,例如字串變數等。

堆(heap:用於存放程式中被動態分配的記憶體段,大小不固定,可動態擴大或縮減, malloc /free 

棧(stack:用來存放程式臨時建立的區域性變數,但不包括static宣告的變數。除此之外,在函式被呼叫時,其引數也會被壓入發起呼叫的堆疊中,並且待到呼叫結束後,函式的返回值也會被放會棧中,由於棧的先進後出的特點,所以棧特別方便用來儲存/恢復呼叫現場,從這個意義來講,我們可以把堆疊看成一個寄存、交換臨時資料的記憶體區

下面用一個程式碼來講述C語言中普通變數和靜態變數的儲存位置

#include <stdio.h>

//全域性變數

int n=3;      //已初始化的全域性變數 存放在資料段
int k ;            //未初始化的全域性變數  存放在bss段
static int j;      //靜態全域性變數 未初始化 存放在bss段
static int i=9;   //靜態全域性變數 初始化 存放在資料段
const int a=5;  //只讀變數 存放在資料段  const修飾的不是常量而是隻讀的變數,const 修飾的只讀變數不能用來作為定義陣列的維數,也不能放在case 關鍵字後面。

void fun()
{
   static int ret=2;
  /*靜態區域性變數只會初始化一次.下一次依據上一次結果值*/
  ret++;
  printf("%d\n",ret);
}

void fun1()
{
  int ret=2;  //函式呼叫完就釋放,所以每次呼叫行數ret都是從2開始
  ret++;
  printf("%d\n",ret);
}
int main(int argc, char const *argv[])
{
  printf("bss段中K,j:%d %d\n",k,j);
  int num; //區域性變數存放在棧中,棧中的變數不會自動初始化為0
  static int C; //未初始化的靜態區域性變數存放在bss段 值為0
  printf("未定義同名前的n:%d\n",n);//3
  int n=7;
  printf("定義同名的:%d\n",n);  // 7 遵循就近原則
 

 //靜態區域性

//靜態區域性變數只會初始化一次.下一次依據上一次結果值
 fun(); //3
 fun(); //4
 fun();//5
   

 //區域性
    fun1();//3
    fun1();//3
    fun1();//3
 return 0;
}

未初始化普通全域性變數系統會自動初始化為0.

未經初始化的靜態全域性變數會被程式自動初始化為0(自動變數的值是機的,除非它被顯式初始化);

靜態全域性變數在宣告它的整個檔案都是見的,而在檔案之外是不可見的;

相關推薦

C語言的++aa++的區別

自增自減1、++自增運算子:如a++,++a都等價於a = a + 1;2、--自減運算子:如a--,--a都等價於 a = a -1; 雖然++a和a++等價的結果一樣,但是運算過程確大不相同,以下舉例說明: #include <stdio.h> int

C語言靜態變數普通變數區別

下面用程式碼說明: 一個可執行程式包括BSS段、資料段、程式碼段(文字段)。 bss segment ,data segment ,code/text segment ①BSS(Block by Start Symbol) :通常指用來存放程式中未初化的全域性變數和靜態變數

CC++經const修飾的常量、常變數普通變數區別

1.在C89標準下的const const 修飾的型別是一個常變數,不能作為陣列的下標。常變數不能作為左值。 如: const int a = 10; int b = a; //其編譯的過程和一般變數編譯的過程相同 //並不會把引用符號的地方替換為對應的資

phpstatic 靜態變數普通變數區別

1、在變數的前面加上static 就構成了靜態變數(static 變數)。 2、static變數和普通變數的區別在於非靜態全域性變數的作用域是整個源程式,當一個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是有效的。 而靜態全域性變數則限制了其作用域, 即只在定義該變數的原始檔內有效, 在同一源

c語言靜態全域性變數靜態區域性變數、全域性變數、區域性變數、巨集

全域性變數: 全域性變數具有全域性作用域。,它只編譯期被始化一次,它不能用變數來初始化。全域性變數只需要在一個原始檔中定義,就可以作用於所有的原始檔。在其他不包含全域性變數定義的原始檔中需要用extern關鍵詞來再次宣告這個全域性變數 區域性變數: 區域性變數只有區域性

C語言跨檔案的全域性變數

宣告:突然看到這篇文章,發現了c語言中使用全域性變數的錯誤,特轉之。 func.c 123456 int buf = 0; void func() { buf = 2; /* Do something else */ } ma

C語言的未初始化變數的值

C語言中未初始化的變數的值是0麼 全域性變數 、靜態變數初始值為0區域性變數,自動變數初始值隨機分配 C語言中,定義區域性變數時如果未初始化,則值是隨機的,為什麼?定義區域性變數,其實就是在棧中通過移動棧指標來給程式提供一個記憶體空間和這個區域性變數名繫結。因為這段

C語言的一個*[]優先級問題

pre 執行 return ges spa 技術 分享 malloc bsp 最近寫著玩了這麽一段代碼 1 int Init(int **T, int v1, int v2, int v3) 2 { 3 4 if (!(*T=(int*) malloc(3*

c語言宏定義常量定義的區別

沒有 int 符號表 cnblogs 格式 nbsp 參數 不同之處 區別   他們有共同的好處就是“一改全改,避免輸入錯誤”哪兩者有不同之處嗎?有的。   主要區別就在於,宏定義是在編譯之前進行的,而const是在編譯階段處理的 宏定義不占用內存單元而const定義的常量

c語言指標陣列陣列指標的認識

1.陣列:一批具有同名的同屬性的資料就組成了一個數組。(“[ ]”也是陣列型別的一部分)     由此可知:(1)陣列是一組有序資料的集合;(2)陣列中的每一個元素都屬於同一個資料型別。  定義一維陣列的一般形式:型別符  陣列名【常量表達式】(陣列也

C語言巨集定義函式的取捨

原文連結:http://www.embedu.org/Column/Column177.htm 要寫好C語言,漂亮的巨集定義是非常重要的。巨集定義可以幫助我們防止出錯,提高程式碼的可移植性和可讀性等。 在軟體開發過程中,經常有一些常用或者通用的功能或者程式碼段,這些功能既可以寫成函式,也可以

c語言的 strcpystrncpy字串函式使用介紹

1.strcpy函式 函式原型:char *strcpy(char *dst,char const *src)            必須保證dst字元的空間足以儲存src字元,否則多餘的字元仍然被複制,覆蓋原先儲存在陣列後面的記憶體空間的數值,strcpy無法判斷這個問題因為他無法判斷字元陣列的長度。

詳解:C語言的指標p, p+1, *(p+1), *P+1, p[0], &p[0] 的含義

解析:C語言中的指標和p, p+1, *(p+1), *P+1, p[0], &p[0] 每一種表示式的含義  一、先解決一個問題:什麼是指標 指標就是存放地址的變數。很好,百度上就是這個答案(哈哈,感覺這句話很廢話)。 指標是一個大小固定為4個byte的變數,不管

linux shell “永久環境變數”、“臨時環境變數"普通變數"之完全解讀

        這個年代, 大家寫點書, 也無非就是為了搞點錢, 基本都是羅列一些知識點, 基本都是寫給已經會了的人看的。 真正用心寫書的人, 不多。 如果真正用心寫書, 且站在讀者的角度去寫, 那就少之又少了。         關於linux shell環境變數, 我看

詳解C語言的 %*s %.*s

%*s:取決於在scanf中使用還是在printf中使用。 1.在scanf中使用,則添加了*的部分會被忽略,不會被引數獲取。 例如: int a,b; char b[10]; scanf("%d%*s",&a,b); //輸入為:12 abc那麼12將會讀取到變數a

c語言的__FILE____LINE__的作用

這是編譯器內建巨集,這些巨集定義不僅可以幫助我們完成跨平臺的原始碼編寫,靈活使用也可以巧妙地幫我們輸出非常有用的除錯資訊。 例如:printf("FILE: %d, LINE: %d, %s/n", "__FILE__, __LINE__, "這裡寫上相關資訊"); ANS

關於C語言自增自減運算子的使用及注意事項

++是自增運算子,是單目運算子,其作用是使單個變數的值增1。它有兩種使用情況: 1)前置:++i,先執行i=i+1,再使用i值; 2)後置:i++,先使用i值,再執行i=i+1。 例如: j=3;k=++j; 執行“k=++j”語句後,k=4,j=4。上述語句等效為: j=

C語言對時間日期的處理

北京燕園智峰韓語培訓中心 韓語:依附於漢城(首爾)著名大學--漢城(首爾)大學的授課內容,短期內使學員快速掌握韓語培訓的聽、說、讀寫能力。教員由漢城(首爾)著名大學--延世大學的講師和漢城(首爾)專業培訓的歸國老師共同打造韓語課程。本班質量可靠、學費低廉,是大學生選擇學韓語的首佳之選。培訓機構自從開辦六年以

c語言形參實參的區別

形式引數和實際引數 函式的引數分為形參和實參兩種。在本小節中,進一步介紹形參、實參的特點和兩者的關係。形參出現在函式定義中,在整個函式體內都可以使用,離開該函式則不能使用。實參出現在主調函式中,進入被調函式後,實參變數也不能使用。形參和實參的功能是作資料傳送。發生函式呼叫

C語言的字串字元陣列

本文來源於網路,轉載為是了更好的複習! 原文網址 :點這裡 1、字元陣列的定義與初始化 字元陣列的初始化,最容易理解的方式就是逐個字元賦給陣列中各元素。 char str[10]={ 'I',' ','a','m',' ',‘h','a','p','p','y'}; 即把1