const:限定一個變量不允許改變,產(chǎn)生靜態(tài)作用,const在一定程度上可以提高程序的安全性和可靠性戳晌。
const 推出的初始目的,正是為了取代預編譯指令痴柔,消除它的缺點躬厌,同時繼承它的優(yōu)點。宏定義:
#define xxxx \
{\
xxx\
}\
\后不能有任何字符竞帽,包括空格 最后的 “}\”需要最少空一行
struct xxxx xxx = {.x1 = xxxxx,.x2 = xxxxx,.x3 = xxxxx};
在C99模式下可以使用該方式對結(jié)構(gòu)體進行初始化扛施,方便觀察每一個變量的初始值。
聲明為const的變量是不能被用戶改變的屹篓,因為編譯器會將該變量放在只讀區(qū)疙渣,比如在KEIL開發(fā)平臺下,聲明為const的變量放在FLASH區(qū)堆巧,這樣即使你使用取地址符 & 獲取聲明為 const 變量地址妄荔,并通過指針進行修改,雖然編譯器不報錯谍肤,但也是無法進行修改的啦租,因為進行FLASH編程是有條件的。
你會發(fā)現(xiàn)雖然P獲取了N的地址荒揣,但因為N存放在FLAH中篷角,所以通過指針也是無法改變N的值的。
可以看到N沒有改變系任。但是編譯器確實也沒報錯恳蹲。但是如果你直接 N = 4 的話,肯定是報錯的俩滥,因為你的N被申明為const嘉蕾。
《C語言深度剖析》中關于const的介紹發(fā)現(xiàn)和KEIL情況不一樣。
在KEIL中進行相關代碼的編寫霜旧,編譯错忱,最后可以看到如下結(jié)果:
這是仿真模式下兩個地址的內(nèi)容,一個存放在FLAH挂据,一個存放在RAM中以清,并且當修改FLAH的內(nèi)容之后(因為是軟件仿真模式,可以直接修改值)棱貌,復位重新運行玖媚,你會發(fā)現(xiàn)RAM的內(nèi)容對應改變了(重新運行后,進入main函數(shù)之前婚脱,有一段拷貝代碼今魔,就是函數(shù)外申明的一些變量的初始化過程)勺像,這就說明,在STM32错森、KEIL環(huán)境下吟宦,并不是《C語言深度剖析》中說的只有一份內(nèi)存,而是每一個都有一個涩维,申明為const情況跟使用宏定義的方式是一樣的殃姓。
以下是Watch中的內(nèi)容
但其實上面的結(jié)論是在使用 & 將N的地址獲取后的結(jié)果(從上圖可以看到p的值),實際上代碼中如果沒有獲取N的地址時瓦阐,情況又不一樣了蜗侈。
內(nèi)存情況:
在刪去獲取N地址后的內(nèi)存情況,可以發(fā)現(xiàn)N的值為0x2000470睡蟋,和FLAH地址0x08000000一樣踏幻。
這像一個地址。但通過Memory查看這個地址發(fā)現(xiàn)存放的不是5戳杀。
根據(jù)ARM內(nèi)核的知識可以知道该面,0x08000000地址存放的其實是棧頂指針,也就是說N存放的是棧頂指針嗎信卡?顯然不是隔缀。
然后對.map地址映射文件進行搜索,你會發(fā)現(xiàn)傍菇,根本沒有N的地址猾瘸。這樣說來,N在內(nèi)存的位置對用戶是不可見的桥嗤,而是由編譯器自動處理了须妻。
那么有沒有辦法找到這個拷貝源頭呢仔蝌。之前我說過泛领,先前能找到拷貝的源頭純屬偶然,有沒有什么方法可以找到呢敛惊?這其中的難點就是進入main函數(shù)之前的那段拷貝代碼不是我們用戶自己寫的渊鞋,而是C編譯器自動處理的,怎么辦瞧挤?
這個時候就需要請出一個關鍵人物:數(shù)據(jù)觀察點(關于數(shù)據(jù)觀察點锡宋,將有專門的一小節(jié)詳細說明)。
我們知道特恬,不管如何执俩,因為FLASH存放著變量初始值,然后在程序運行的時候才將FLASH中的值初始化到RAM中去癌刽,也就是我們使用的RAM變量役首,那么必然存在通過總線進行數(shù)據(jù)傳輸?shù)倪^程尝丐,所以可以通過數(shù)據(jù)觀察點的功能實現(xiàn)對地址的監(jiān)控,雖然我們不知道FLAH的地址衡奥,但是我們知道RAM的地址爹袁,所以只要對變量i進行監(jiān)控,就可以通過內(nèi)核的寄存器找到FLASH地址了矮固。如下:
這里的0x20000000就是i的RAM地址失息,最終可以找到FLASH的位置:
由此可以知道,F(xiàn)LAH中也是有多個相同副本存在的档址。
因此可以得出結(jié)論盹兢,在STM32、KEIL的環(huán)境下守伸,《C語言深度剖析》對于兩者的說法在這里不適用蛤迎。
看了那么多,沒有足夠的基礎是很難知道我在講什么的含友,下面用一張圖進行說明替裆,希望可以解答你的疑惑。
希望你在看完這張圖之后窘问,再回過頭看看前面的那些話辆童,對你應該會有幫助的。
-------------------------------------------------------------------------------2018/12/06 Osprey