編譯器在編譯時會對變數
對於變數名,會根據變數類型
開辟不同大小的內存空間
然後指定一個相對地址記錄下來。
對於編譯後, 不存在變數名,只有對應的相對地址。
❷ c++編譯系統在編譯時對靜態存儲變數分配存儲單元嗎
是啊,就是在編譯的時候分配的么,不過你也可以動態分配,比如malloc函數,這樣的內存是在堆中申請的,所以程序執行的時候才會申請,一般的變數什麼的,包括數組都是在棧中存放,堆就是要靠用戶管理的數據區域,棧則是有系統自動管理的。
❸ 編程中的變數與常量
看完要加分啊.
其實常量有幾種, 因為他們的值不能被改變而都叫常量, 但他們是有很大區別的, 因為他們的作用完全不一樣.
至於他們的本質區別分幾情況.平常定義的變數一般是放在棧或靜態區上, 也就是你說的內存中的一個特定的存儲區域.
1.宏定義的"常量".就是你的程序里的
#define P 3.14
這個不是跟平常的變數一起存放在棧上, 這個是一個宏, 編譯器編譯前會將你的代碼中所有的P替換為3.14, 所以你的程序在運行時是沒有地方存放P這個常量的, 而3.14會跟你的其他可執行代碼一起放在內存當中.所以宏定義的"常量"可以說不算一個量了.
2.C++的const定義的"常量", 例如
const int a = 2;
這個a是跟平常的變數一樣放在棧上, 只不過編譯器在編譯時會加一個安全檢查, 如果你的代碼有顯式修改a的地方, 就會報一個編譯錯誤. 但是你還是可以在運行時通過其他方式修改a的值.所以const定義的量跟平常的變數沒有什麼區別.
3.字元串常量
char* p = "text";
p確實是一個變數, 但其指向的"text"即不放在棧上也不放在代碼里,它放在一個專門的靜態區域, 如果你修改它的值(不是修改p的值), 會造成內存錯誤. 所以字元串常量又跟上面兩種不一樣.
比如下面的程序:
#define P 3.14
main()
{
char* s = "text";
const double a = P;
}
它的內存分布如下:
*******************************
| 靜態存儲區 |
| "text" |
*******************************
| 棧 |
| s a |
*******************************
| 代碼域 |
| char* s = ...|
| const double a = 3.14; |
*******************************
============================================================
這正好就是你說的時間的區別, 但注意不是"運行的時間", 而是他作為"常量"的時間. 從源代碼到可執行程序的過程中, #define的常量是在編譯前所進行的處理中作為常量(也就是預處理), const是在編譯當中作為常量, 而字元串常量則是在運行時無法修改了.
------------------------------------------------------------
至於你說的常量沒用是不正確的.我只說上面前兩種"常量".
1.#define宏定義的"常量".在多文件的情況下, 普通的變數在第一個文件中定義後又要在其他文件中重新聲明, 顯然沒有宏方便.而且如果用變數的話在它的所有有效區都可以被修改, 肯定是不安全的.另外宏也更直觀, 比變數更容易維護.
2.const定義的常量.這種常量一般是為了防止程序員誤修改不能被修改的值.特別是一個人寫的程序給另外一個人用時, 比如一個字元串, 或一個類的成員.
❹ 編譯器在編譯的時候做了什麼給申明的變數分配內存
編譯器在編譯的時候是不會聲明變數和分配內存的。 分配內存之類的是在運行時執行的。
一般編譯器在編譯的時候,只是做代碼的格式檢查, 然後將代碼轉換成機器碼或中間代碼。
❺ 我們經常看到書上面說的 某某變數的內存單元是編譯器在編譯時候分配的 是什麼意思
所謂在編譯期間分配空間指的是靜態分配空間(相對於用new動態申請空間),如全局變數或靜態變數(包括一些復雜類型的常量),它們所需要的空間大小可以
明確計算出來,並且不會再改變,因此它們可以直接存放在可執行文件的特定的節里(而且包含初始化的值),程序運行時也是直接將這個節載入到特定的段中,不
必在程序運行期間用額外的代碼來產生這些變數。
其實在運行期間再看「變數」這個概念就不再具備編譯期間那麼多的屬性了(諸如名稱,類型,作用
域,生存期等等),對應的只是一塊內存(只有首址和大小),
所以在運行期間動態申請的空間,是需要額外的代碼維護,以確保不同變數不會混用內存。比如寫new表示有一塊內存已經被佔用了,其它變數就不能再用它了;
寫delete表示這塊內存自由了,可以被其它變數使用了。(通常我們都是通過變數來使用內存的,就編碼而言變數是給內存塊起了個名字,用以區分彼此)
內存申請和釋放時機很重要,過早會丟失數據,過遲會耗費內存。特定情況下編譯器可以幫我們完成這項復雜的工作(增加額外的代碼維護內存空間,實
現申請和釋 放)。從這個意義上講,局部自動變數也是由編譯器負責分配空間的。進一步講,內存管理用到了我們常常掛在嘴邊的堆和棧這兩種數據結構。
最後對於「編譯器分配空間」這種不嚴謹的說法,你可以理解成編譯期間它為你規劃好了這些變數的內存使用方案,這個方案寫到可執行文件裡面了(該文件中包含若干並非出自你大腦衍生的代碼),直到程序運行時才真正拿出來執行。
❻ 編譯器編譯高級語言為低級語言的時候,給全局變數或靜態變數是如何分配內存的
對於C和C++的編譯器,全局變數和靜態變數都是在專門的數據區保存的,更具體一點,一般是在.data和.bss段保存的,具體在哪個段,編譯器會根據代碼中是否對這些變數進行了初始化來決定,如果初始化過,並且初始化的值不為0,那麼這個這個變數一般就會被放在編譯結果的.data段中,否則就是放在.bss段中。
.data段中就保存變數的符號,還保存變數的初始化值,而在.bss段中,只保存變數的符號,而不保存值,這是因為這部分的變數都將被初始化為0,這也是為什麼static聲明的變數即使沒有初始化也會是0的原因。
這些段都會在程序被執行的時候由操作系統(或鏈接器)載入到指定的內存中,便完成相應的初始化。
❼ 編譯系統(如:VC++6.0)編譯時對變數和變數地址如何處理
int a =5;//定義一個變數,並初始化
int *p //定義一指針變數
p = &a; //把a的地址賦給指針變數p
int &a = b;//a是b的引用。也就是b的一個別名。只要改變a的值,b的值也就改變了
❽ 編譯器是否對變數名,函數及源代碼文件的長度有限制,如果有,為什麼會有這些限制
如果沒有函數調用的話,編譯器恐怕不會產生任何代碼……如果有調用的話,會產生調用函數的代碼,至於函數的實現在哪裡,那不是編譯器要考慮的事,鏈接器才需要查找函數的實現代碼並與函數調用代碼對上……
❾ C語言中已經聲明或定義的變數如果在代碼中沒有使用到,編譯器會怎樣處理
就一直在那裡放著。如果是全局變數,編譯器連提示都沒有;若是局部變數編譯器在編譯時會提醒說某某局部變數沒有使用;若你不理會,在代碼修改前就不會再提醒了。這些變數未使用,卻一直佔用著內存空間,但不影響代碼的正確性……
❿ 問一下各位,c語言編譯器是如何處理變數名的呢
編譯器編譯到int a;時就在內存中開辟一個兩位元組的內存空間,並且命名為a