深入理解C系列:不同类型变量的变量名和内存间的关系
有了前面兩篇的基礎,下面正式開扒變量名和內存的關系,先看一段大家很熟悉的代碼:
int?i;scanf_s("%d",?&i);int i;,在這一句就為i分配了內存(但尚未對這塊內存進行初始化),所以可以通過&i直接使用這塊內存。賦值就更不用說啦,i = 3;。
變量名i,是為方便編程人員使用,是這塊內存的別名,指代到塊內存,對編程人員i代表這塊內存中存儲的值(實際上是i指到這個內存,然后取值)。通常我們都是通過變量名來使用已知的內存的。
i代表取(這塊內存中存儲的)值,而&i代表取(這塊內存的)址。程序本身是不為i這個變量名分配空間的。在最終的機器代碼中,是不會出現變量名的,這一點在分析反匯編語言時可以看出(命令:dumpbin /disasm xx.obj >xx_disasm.asm可以查看反匯編語言)。那么編譯器是如何處理變量名的呢,變量名會存儲在符號表中,并將符號表中的索引對應到實際物理空間(地址)上去,當調用這個變量時,查找符號表就可以找到對應的地址并取值了。
?
上面分析的是基本數據類型(如int、char等)的變量名。C中除了變量名之外,還有函數名、常量名、指針名、數組名、結構名等。和變量名不同,這些標識符都是直接對應著地址的。基本數據類型的變量,和地址的對應關系需要取址符&才能得到地址,而其余的這些,名字本身就對應著地址。
例如char *pc = “se”;,就是將字符串常量”se”的首地址(位于常量存儲區)賦值給了字符指針pc。這也就解釋了為什么不需要為pc分配地址就可以為其賦值,而不會遇到類似下面代碼所帶來的野指針問題:
int?*pi;*pi?=?1;int *pi句,是為pi分配空間,而不是開辟pi所指向的空間。
?
下面分別來看不同類型變量的變量名和內存見的關系:
先看C中的常量:
C對常量是怎么處理的呢?比如上面的i = 3;中的常量3,存儲常量3的地址并不是隨機分配的,是在程序中的數據段中(.data?這個我也還不是很確定,希望知道的前輩們給個指導),也就是程序本身并不為3分配內存,而是直接寫入指令。3是數字常量,對于字符常量和字符串常量,又分別是怎么處理的呢?
字符常量和數字常量是一樣的處理方式,都是類似匯編中的立即數,直接寫入指令;
而字符串常量,則是存儲在常量存儲區,可以使用&(“string”)取得具體地址。也就是字符串常量名字本身指代著地址,只是不能直接操作(和int i中的i相同)。
?
再看各種類型的變量名,c中的數據類型除常量之外大致有5種:
基本數據類型:int、float、double、char等:
對各基本數據類型的變量名及其聲明時的處理方式都是一樣的,聲明時即分配內存,并使用變量名直接操作這段內存;使用取地址符號&取得地址的數字表示,至于聲明時要不要做初始化,要看是不是全局變量或者 static變量了。
這類變量名指向一個地址空間,但不能直接當做地址使用,而是通過取址符&操作其地址。
http://www.cnblogs.com/czl-sy/archive/2013/04/08/3008959.html
轉載于:https://blog.51cto.com/frankch/1767969
總結
以上是生活随笔為你收集整理的深入理解C系列:不同类型变量的变量名和内存间的关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx加入linux系统服务
- 下一篇: 《高性能MySQL》の复制