内存中的static、const实现形式

时间:2014-02-22 09:09:36   收藏:0   阅读:306

最近在考虑下半年找工作的事情,看了不少面试题目,其中还是蛮有收获的,把基础好好复习了一遍。比如这个题目,static、const现形式,static和const类型的变量在写程序的时候也写了很多,不过对编译器内部对其实现知之甚少。所以借这次机会好好百度谷歌了一番。

static实现形式

我们都知道,static变量只能初始化一次,这个是怎么实现的呢?小齐的网易博客里面作者写的很清楚: 代码如下:

bubuko.com,布布扣
 1 int main(){
 2     for (int i(10); i > 0; --i)
 3     {
 4         fun(i) ;
 5     }
 6 
 7     return 0;
 8 }
 9 
10 void fun(int i)
11 {
12     static int n = i ;
13     int *p = &n ;
14     cout << n << " " ;
15 
16     ++n ;   
17 }
bubuko.com,布布扣

因为static变量只能被初始化一次,所以第12行的初始化语句只会被执行一次,但是以后每次都会执行++n的操作,所以输出的结果是:

10 11 12 13 14 15 16 17 18 19

之后作者在VS下面对上述程序进行了DEBUG调试,发现第一次n被赋值之前内存如下:

0042E058  00 00 00 00  ....

0042E05C  00 00 00 00  .... // 中间这个为n的内存地址

0042E060  00 00 00 00  ....

当初始化语句执行完毕,内存内容如下:

0042E058  01 00 00 00  ....

0042E05C  0A 00 00 00  ....// n

0042E060  00 00 00 00  ....

作者继续执行,当for循环执行的时候,再次对static n初始化的时候,却发现n值不会等于i,而是继续保留原来的值。由此作者推断上面的那个0x01是不是就是标志n已经被初始化的标志位。即当要对n初始化的时候,就会检查上面的0042E058单元中对应的标志位是否是1,若是1,则说明已经初始化,若不是1,则进行初始化。

鉴于此,作者改进了fun函数,如下:

bubuko.com,布布扣
void fun(int i)
{
    static int n = i ;
    int *p = &n ;
    cout << n << endl ;
    ++n ;

    p--;
    *p=0;
}
bubuko.com,布布扣

即每次修改0042E058内容清零,使得可以反复对n初始化,做了上述改动之后,函数执行的结果如下:

10 9 8 7 6 5 4 3 2 1

得到证实了,即即当要对static初始化的时候,就会检查上一单元中对应的标志位是否是1,若是1,则说明已经初始化,若不是1,则进行初始化。

之后作者又做了实验,他设定了两个static变量:

bubuko.com,布布扣
void fun(int i)
{
    static int n1 = i ;
    static int n2 = i ;
    int *p = &n1 ;
    cout << n1 << endl ;
    ++n1 ;

    p--;
    *p=0;
}
bubuko.com,布布扣

观察单元发现,当执行static赋值之前,内存单元内容如下:

0042E058  00 00 00 00  ....

0042E05C  00 00 00 00  .... // n1

0042E060  00 00 00 00  .... // n2

当执行完static int n1 = i 语句之后,内存的值变成这样了:

0042E058  01 00 00 00  ....

0042E05C  0A 00 00 00  ....

0042E060  00 00 00 00  ....

接着我们再单步static int n2 = i,则执行内存的值变成这样:

0042E058  03 00 00 00  ....

0042E05C  0A 00 00 00  ....

0042E060  0A 00 00 00  ....

这样就很明显了,编译器分别用一位来表示一个static变量是否已经始化。

 

const实现形式就比较简单了,作者想使用地址的形式改变const常量的值,可是没有成功,作者查看汇编代码,原来是编译器直接将常量类型的换成对应的数值了。这样在执行的时候直接使用数值替换。

原文:http://www.cnblogs.com/havePassed/p/3559848.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!