全域性變數初始化相關的乙個錯誤

2021-07-07 08:37:22 字數 1054 閱讀 1108

標籤(空格分隔):coding-nissan

// 全域性域

int i = 3;

int j = i;

因為是全域性變數,編譯時會將i放入.data段,並設定其值為3.而對於j,編譯器遇到這種非常量的全域性變數初始化語句,只知道j=i,由於i是變數,不是常量,編譯器無法在編譯時直接得到它的值,即編譯器不能夠直接用3來初始化j。編譯器無法在編譯時求得乙個非常量的值,它只能在執行時通過讀取變數位址來間接得到變數的值,而全域性變數在編譯時就必須確定其值,故c有靜態儲存區資料必須用常量初始化的規定。

由於j是全域性變數,儲存在靜態儲存區,因此也需要在編譯時確定其值。而i是變數,不是常量,i的值無法在編譯時確定,這就造成j的值也無法在編譯時確定,所以c對此就會報錯。而c++採取了另外一種做法,在編譯時簡單的把j作為未初始化的全域性變數放入.bss區,其預設值為0,然後新增一條語句在執行時通過i的位址進而讀取i的值,再賦給j。上述過程在 main函式開始之前執行。因此j 的初始化實際上實在執行時完成的。

【補充】

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

.bss段:通常是指用來存放程式中未初始化的全域性變數的一塊記憶體區域。bss段屬於靜態記憶體分配。

上述完整的過程可以概括為:

取i的位址,把3放到i的位址中,取i的位址,讀取這個位址中的內容,取j的位址,把這個內容 寫入j 的位址。

int i = 3

int main()

在編譯時不需要確定區域性變數j的值,而是在執行時讀取i的值來賦給j。編譯連線後的可執行檔案中不會存放j的值,只有相應的賦值語句的**。與此相對的,由於i是全域性變數,儲存在靜態儲存區,因此在編譯時其值就需要確定其值,在目標檔案中會分配空間來存放i的值,執行時不會有賦值語句來給i賦值,沒有對應的**。

未初始化全域性變數

未初始化全域性變數,這名字就很直白,就是 c 程式中定義成全域性作用域而又沒有初始化的變數,我們知道這種變數在程式執行後是被自動初始化為 全0 的。編譯器編譯的時候會將這類變數收集起來集中放置到 bss 段中,這個段只記錄了段長,沒有實際上的內容 全是0,沒必要儲存 在程式被裝載時作業系統會為它分配...

關於未初始化全域性變數

前幾天發現未初始化全域性變數一些特性,後來在一篇部落格上發現有人說過這個問題 這是原博文位址 blog.csdn.net liuqiaoyu080512 article details 8455652 然後結合原博文,自己又做了幾個實驗 以下算是自己實驗一遍以後的總結 首先,自己曾經以為未初化的全域...

C語言全域性變數的初始化

本意是想定義乙個全域性結構體變數,並設定其成變數的值。typedef struct a t a t a a.a 1 error expected asm or attribute before token a.b 2 error expected asm or attribute before to...