C程序中变量存放方式介绍
棧
C語言中的局部變量都是通過棧存放的,在X86系統中,棧的增長方向是從高地址向低地址(對于8051單片機中,棧的增長方向是從低地址向高地址)。
下面的例子很好地證明了這一點
#include <stdio.h>int main() {char ch1;char ch2;short sh1;short sh2;int i1;int i2;printf("addr ch1 = %p\n", &ch1);printf("addr ch2 = %p\n", &ch2);printf("addr sh1 = %p\n", &sh1);printf("addr sh2 = %p\n", &sh2);printf("addr i1 = %p\n", &i1);printf("addr i2 = %p\n", &i2);return 0; }多字節變量
從上面的例子中也可以看到,多字節變量的地址其實是所占據存儲空間中的低地址。比如上例中的short類型變量sh1占據了0065FEAC~0065FEAD兩個字節空間,但是sh1的地址就是0065FEAC,是低地址。
將上面的地址分布畫下來,我相信讀者應該會有下面兩個疑惑。
1)0065FEA8~0065FEA9兩個字節為什么跳過去了呢?
2)既然有些變量占據多個地址空間,那么變量的高字節是占低地址空間還是高地址空間呢?
下面解答這兩個問題
1)這是因為編譯器為了提高程序執行效率,會對程序變量進行字節對齊。我們想一想啊。假如這個電腦是一個32位的系統,數據總線是32位的,也就是一次可以讀取4個字節。假如i1這個變量不是存儲在4個字節對齊的空間,那么CPU為了讀取i1這個變量,就需要讀取RAM兩次。編譯器為了提高代碼的執行效率都會對代碼進行字節對齊。
一般對齊的原則是,這個變量的大小是幾個字節,就是對齊幾個字節。對于char short int 就是1個字節對齊(不需要對齊)、2、4字節對齊。上面例子中的i1、i2變量是int類型的,因此需要對齊到4個字節,因此它們需要從地址末尾為0,4,8,C開始的存儲空間開始存儲。這就解釋了為什么上面有兩個字節會跳過了。
2)這個問題的結論就是高字節放到高地址空間,低字節放到低地址空間。下面的例子可以說明這個結論。
#include <stdio.h>int main() {short i;unsigned int addr;unsigned char ch1, ch2;printf("size short %d\n", sizeof(i));printf("address short %p\n", &i);i = 0x1234;addr = (unsigned int)(&i);ch1 = *(char *)(addr);ch2 = *(char *)(addr + 1);printf("i = %x\n", i);printf("ch1 = %x\n", ch1);printf("ch2 = %x\n", ch2);return 0; }這個例子中的變量ch1放的是short類型的變量i的低地址空間內容,ch2放的是高地址空間內容。i是0x1234,ch1=0x34,ch2=0x12。這就說明了變量的高字節放高地址空間的內容,低字節放低地址空間的內容。
順便說一下對于用C51進行8051單片機編程的同學,在8051中高字節放在低地址空間中,低字節放高地址空間中。由于8051的棧是從低地址開始向高地址延伸,似乎有一個規則,變量的高字節在棧中先存放,低字節后存放。這個規則對于x86和8051都適用,對于其他芯片是不是都成立,大家可以自己總結一下。
總結
以上是生活随笔為你收集整理的C程序中变量存放方式介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Visual Studio设置隐藏cm
- 下一篇: 获得程序运行结果的返回值