1. 程式人生 > >const,全域性變數

const,全域性變數

const定義的變數是可以被修改的,只不過不能被顯式修改,報錯是編譯器給出的,在編譯的時候,如果編譯器發現const被
修改了則會報錯,但是在執行的時候,卻是可以修改的,因此const具有變數的屬性。並不是常量。
 下面這一段程式碼可以證明上面的判斷
int main
{
char buf[4];
const int a = 0;
buf[4] = 97;
printf(“the a is %d\n”,a);
}
其中最後一句printf的目的是看下變數a的值是否改變,根據const的理解,
如果const修飾的是變數是不能被修改的話,那麼a的值一定不會改變,肯定還是0。
但是在實際執行的結果中,我們發現a的值已經變為97了。
這說明const修飾的變數a,已經被我們程式修改了。

上面這個例子也很好的說明了const所修飾變數仍然是個變數,如果在函式中定義const的變數,
則const修飾的變數就會被放到棧上,如果在函式外面定義const的變數,則會被放到data區。
在一個函式中const所修飾的變數是不能被顯示修改的(這個變數的作用域仍然是區域性變數)。

下面的一段話是我的關於執行時全域性變數和區域性變數是如何在記憶體中分配的推測(有些內容可能不準確,僅作為自己學習時的為了後續方便理解的推測,有的部分還需要進一步驗證):
首先,我們已經對程式下載到ROM的程式碼分佈達成了共識,即分為程式碼區,BSS(ZI),data。(常量區
作為記憶體池放在了程式碼區,這個可以通過閱讀反彙編程式碼看出來)。但是這只是在rom中的分佈,以stm32為例,如果程式執行起來
程式碼是在norflash中原地執行的。而靜態分配的全域性變數肯定不會在norflash中賦值和讀取(如果這樣讀寫速度將很慢),一定是
要在sram中分配的,因此我推測,當程式中應用到全域性變數的時候,會在記憶體中開闢空間,這個空間地址是編譯器
在編譯的時候分配的(連結地址),在rom的data或者bss段中儲存的只是記憶體池,然後程式程式碼會讀取記憶體池相應的資料複製
給sram中的記憶體空間,換句話說,如果在程式中沒有用到某個在rom中定義的全域性變數,則這個全域性變數
根本就不會佔用記憶體(但是卻會佔用rom空間)。