Ⅰ 有沒有一種編譯器在定義了一個局部變數之後,未對它初始化後,系統自動置為0
這樣做的好處是什麼呢?一般軟體工程的建議是:即使有這樣的預設選項,也要當作它沒有,因為你無法控制編譯器不改變這種預設行為。所有變數都要初始化後使用
Ⅱ 全局變數和局部變數有什麼區別是怎麼實現的
1、 全局變數的作用用這個程序塊,而局部變數作用於當前函數;
2、前者在內存中分配在全局數據區,後者分配在棧區;
3、 生命周期不同:全局變數隨主程序創建和創建,隨主程序銷毀而銷毀,局部變數在局部函數內部,甚至局部循環體等內部存在,退出就不存在;
4、 使用方式不同:通過聲明後全局變數程序的各個部分都可以用到,局部變數只能在局部使用
操作系統和編譯器通過內存分配的位置來知道的全局變數分配在全局數據段,並且在程序被運行的時候就被載入。;
編譯器通過語法詞法的分析,判斷出是全局變數還是局部變數。如果是全局變數的話,編譯器在將源代碼翻譯成二進制代碼時就為全局變數分配好一個虛擬地址 (windows下0x00400000以上的地址,也就是所說的全局區),所以程序在對全局變數的操作時是對一個硬編碼的地址操做。
局部變數的話,編譯時不分配空間,而是以相對於ebp或esp的偏移來表示局部變數的地址,所以局部變數內存是在局部變數所在的函數被調用時才真正分配。 以匯編的角度來看:函數執行時,局部變數在棧中分配,函數調用完畢釋放局部變數對應的內存,另外局部變數可以直接分配在寄存器中。
操作系統通過變數的分配地址就可以判斷出是局部變數和全局變數。
Ⅲ 操作系統和編譯器是怎麼識別全局變數和局部
操作系統,只管調度進程,線程編譯器根據編程語言的定義,確定變數的作用於,存儲類型,生命周期!
定義在函數外部的變數,只有文件靜態變數,和外部變數
外部變數,是實實在在的全局變數,不論作用域還是生命周期。
靜態變數是局部作用域的,生命周期為,程序的生命周期的變數。
自動變數和函數參數,是局部作用域的生命周期為函數結束的局部變數。
寄存器變數,用register定義,是局部變數;
函數內部的靜態變數,語句組內部的靜態變數,局部作用域的,生命周期為,程序的生命周期的變數。
靜態變數,編譯器,可以通過static關鍵字知道。
自動變數,1)函數內部定義的非靜態變數,非寄存器變數是自動變數。
2)函數參數,只能是自動變數,不過也可能定義在寄存器中。
這和調用約定有關,因此不可以用register定義。
C語言沒有全局變數這種數據類型。
只有4種存儲類型,和變數的作用域與生命周期的概念。
C++同樣沒有全局變數這種數據類型。
有另外的兩種作用域
1)namespace作用域。
2)類(類型)作用域。
C只有全局,文件,函數以及函數內部的語句組,4種逐漸縮小的作用域。
其中內層,對外部作用域,具有完全的遮蔽作用。
C++可以通過作用域限定符,區分不同作用域(類,名空間)的名字。
類作用域,可以通過訪問許可權,限制外部的訪問權。
函數作用域(語句組作用域)是封閉的作用域,外部不可以使用函數內部定義的名字。
也不會和外部有命名沖突,只會遮蔽外部的名字。
類作用於,和名空間由於訪問方式不同,命名沖突和遮蔽有些特殊。
函數和全局域,基本不會和類作用域有命名沖突,除非類方法內部。
命名空間,可以避免命名沖突。
類繼承體系中,則有遮蔽現象。
還有訪問許可權問題。
實際上,全局變數,有兩個概念可以判定
1)作用域(空間)===>由定義和聲明位置,和定義和聲明使用的關鍵字決定。
2)生命周期(時間)===>外部和靜態變數,的生命周期是全局的,從初始化到程序結束。
函數參數,和函數局部非靜態變數,是局部變數
函數參數的傳遞,是跨函數的(實參,變成形參);
函數內部定義的,局部變數,只有定義處可見,作用域是函數甚至語句組局部,
其中靜態變數,生命周期是全局的,非靜態是函數甚至語句組的。
全局變數,不是C,C++的概念。
而是,使用編程語言的程序員的概念。
所以,全局變數和C,C++的存儲類型,作用域,生命周期等,不是一一對應的概念。
所以,可以有不同的理解。
所以這個概念是很模糊的,不清晰的。
比如局部靜態變數,類的靜態變數,是否全局變數,就不是可以清晰的說明的。
Ⅳ 編譯器對作為局部變數的數組是怎麼管理的放在堆棧中
C語言的堆跟棧是有區別的,請大家不要混淆。
局部變數和函數調用時的實參是放在棧里。所以有大家常說函數調用時的入棧,出桟這個說話。
動態申請的內存放在堆里的。
全局變數和靜態變數是放在另外的全局內存區。
Ⅳ 為什麼使用gcc編譯代碼後局部數組變數的初始值消失了
局部變數在棧上 不在數據段 運行時初始化的
這個問題和編譯器無關,是 CPU 的分段配置有問題。
編譯腳本里,加上一個-g的參數,會生成調試符號,調試符號里是帶行號的
Ⅵ 編譯器怎麼知道是全局變數還是局部變數
這個要細說,能說的很詳細,我說一下,比較好理解的你就懂了!
我說之前先打個比方:小區人家,幾十戶,每家每戶都有燈光自己用就是局部的
月亮..全局的.都能用懂了?
按照目前的面向對象來說如Java,C++,C#,Ruby中,由於變數都是封裝在類裡面的,對別的類不可見,所以已經幾乎完全拋棄了全局變數的概念。然而,可以通過把一個類定義為public static,把類成員變數也定義為public static,使該變數在內存中佔用固定、唯一的一塊空間,來實現全局變數的功能。
說通俗點,你如果想理解,就假如在一個類中,看你定義的變數,位置!類中,方法外面,就屬於全局,每個方法都能拿去用..方法裡面定義的,就屬於局部的,只能他自己用.懂了?
和你一樣初學者,不足之處還請指點!
Ⅶ Dsp bin文件局部變數內存怎麼分配
編譯器自動把變數分配到可讀寫空間上的任意位置
DSP的所有變數,函數,以及程序員定義的地址都保存在這三片空間上,程序員在定義變數時,若沒有特殊規定,則編譯器自動把變數分配到可讀寫空間上的任意位置,所以當程序員使用int*p=0x00810000;
這種語法的時候,很有可能會覆蓋掉程序保存變數和函數的空間,導致程序運行異常,因此需要一個.cmd文件來約束,哪些地方用來給程序員自己定義變數地址用,哪些地方用來給程序為變數和函數申請內存來用。
嵌入式的設備如DSP上的棧空間是Kb級別,在函數內定義數組或申請空間都不能像linux下那樣直接定義和申請,要麼定義成全局的,要麼指向一塊劃分好的空間,否則就會造成覆蓋代碼段等的問題。
Ⅷ GCC編譯器局部變數地址分配為什麼總是從低
原因:GCC的堆棧保護技術—— canary的使用。
使用的原因是為了防止某些溢出的攻擊。但是只是溢出時方向發生了改變,並沒有起到太大的作用,可能對於傳統的一些攻擊方法有用。
GCC 中的堆棧保護實現
Stack Guard 是第一個使用 Canaries 探測的堆棧保護實現,它於 1997 年作為 GCC 的一個擴展發布。最初版本的 Stack Guard 使用 0x00000000 作為 canary word。盡管很多人建議把 Stack Guard 納入 GCC,作為 GCC 的一部分來提供堆棧保護。但實際上,GCC 3.x 沒有實現任何的堆棧保護。直到 GCC 4.1 堆棧保護才被加入,並且 GCC4.1 所採用的堆棧保護實現並非 Stack Guard,而是 Stack-smashing Protection(SSP,又稱 ProPolice)。
SSP 在 Stack Guard 的基礎上進行了改進和提高。它是由 IBM 的工程師 Hiroaki Rtoh 開發並維護的。與 Stack Guard 相比,SSP 保護函數返回地址的同時還保護了棧中的 EBP 等信息。此外,SSP 還有意將局部變數中的數組放在函數棧的高地址,而將其他變數放在低地址。這樣就使得通過溢出一個數組來修改其他變數(比如一個函數指針)變得更為困難。
Ⅸ C語言中的 局部變數,存儲在什麼地方
C語言中的局部變數存儲在棧里。
普通的局部變數在棧空間上分配,這個局部變數所在的函數被多次調用時,每次調用這個局部變數在棧上的位置都不一定相同。局部變數也可以在堆上動態分配(malloc),但是記得使用完這個堆空間後要釋放之。
在棧空間上分配時是要注意內存的,不能分配內存過大。如果棧內空間小於所申請的空間大小,那麼這時系統將揭示棧溢出,並給出相應的異常信息。但是堆不一樣,堆可分配空間是很大的。
(9)編譯器編譯局部變數擴展閱讀
局部變數分類
1、位置:靜態局部變數被編譯器放在全局存儲區.data,所以它雖然是局部的,但是在程序的整個生命周期中存在(定義時出生,隨著程序結束而結束)。
2、訪問許可權:靜態局部變數只能被其作用域內的變數或函數訪問。也就是說雖然它會在程序的整個生命周期中存在,由於它是static的,它不能被其他的函數和源文件訪問。
3、值:靜態局部變數如果沒有被用戶初始化,則會被編譯器自動賦值為0,以後每次調用靜態局部變數的時候都用上次調用後的值。