首页蓝耳朵|小小蓝耳朵广州图书馆外文室英语儿童读物资源介绍网佛教青年之友旧版收集永硕E盘Phonics Short Vowels Game 
在循环外定义变量和在循环内定义变量,在循环时间内速度和资源占用都没有区别
所属栏目:ASP.NET(webform)  时间:2010-08-04 15:44  作者:狼子

如题。。。

在循环外定义变量和在循环内定义变量,在循环时间内速度和资源占用都没有区别,这两种变量定义的位置,区别只在变量的生命周期,和循环体外占用的资源

所以,如果在循环体外需要使用变量,变量应该定义在循环外,如果变量只在循环体内用到,而且占用比较多的资源,应该在循环内定义


先说资源占用,我一直以为在循环内定义变量会占用更多的资源,就是,经过测试,发现在每一次循环里定义的变量,指向的内存单元都是相同的,如下图:

测试是在vs.net 2005下用winform项目进行的,在项目属性的生成标签里把“允许不安全代码”勾上就可以通过编译了,测试代码如下:

private void TestAddress()
        {
            //项目属性里,“生成”标签上勾上“允许不安全代码”
            TbResult.Text += "在循环外定义变量:" + Environment.NewLine;
            unsafe
            {
                int a;

                //定义指针接收变量的地址
                int* pa = &a;

                //给指针指向的地址设置值,相当于给对应的变量a赋值
                *pa = 100;

                //显示变量的内存地址和值
                TbResult.Text += "a的内存地址:" + Convert.ToString((int)pa) + ",";
                TbResult.Text += "这个地址内的值:" + *pa + ",";
                TbResult.Text += "变量a的值:" + a.ToString() + Environment.NewLine;


                TbResult.Text += Environment.NewLine + "在循环内定义变量:" + Environment.NewLine;
                //把指针定义在循环外面,最后可以用这个指针测试循环后是否还能访问该变量
                int* pb;
                //用a变量的地址址初始化指针变量,使这个变量可以在循环结束后继续用于测试
                pb = &a;
                for (int i = 0; i < 3; i++)
                {
                    //循环内定义变量
                    int b = i;
                   
                    //把变量的内存地址赋值给指针
                    pb = &b;

                    //显示每一次循环变量在内存里的地址和值
                    TbResult.Text += "第" + Convert.ToString(i + 1) + "次循环:";
                    TbResult.Text += "b的内存地址:" + Convert.ToString((int)pb) + ",";
                    TbResult.Text += "这个地址内的值:" + *pb + ",";
                    TbResult.Text += "变量b的值:" + b.ToString() + Environment.NewLine;
                }

                TbResult.Text += Environment.NewLine + "操作结束,测试访问两个指针内的值:" + Environment.NewLine;
                TbResult.Text += "指向变量a的指针对应地址内的值:" + *pa + Environment.NewLine;
                TbResult.Text += "指向变量b的指针对应地址内的值:" + *pb;
            }
        }

从这段代码的执行结果可以看出,每一次循环,变量b指向的内存地址完全相同,说明变量b没有占用更多的资源,就是,生命周期在循环结束后就结束了,循环结束后,不能再使用b引用那个内存单元的值,需要直接用内存地址引用,如果这时候内存紧张自动执行了垃圾回收,这个内存单元有可能会被回收


下面说执行速度,在循环内定义变量和在循环外定义变量

int a;
for (int i = 0; i < 3; i++)
{
    a = i;
}

for (int i = 0; i < 3; i++)
{
    int a = i;
}

区别只剩下声明语句和内存分配了,如果循环内定义的变量每一次都要声明变量并重新分配内存单元,那就是相当于程序要声明同名变量,而且这个变量每一次都要分配相同的内存单元,我觉得这个假设好怪。。。

在同一段代码里,类似for (int i = 0; i < 3; i++)这样子的语句是可以重复出现的,因为变量i的生命周期只在for循环内部,同名变量,但不同生命周期,所以我觉得,循环内定义的变量每一次循环都声明同名变量,应该也是允许的

测试。。。

代码很简单:

for (int i = 0; i < 3; i++)
{
    int a = i + 1;
}

用这一段代码执行逐语句执行(F11),执行过程如下:

第一次循环,刚刚进入执行int a = i;的时候,a的初始值就是C#里声明一个int型变量的初始值0


第一次执行结束后,赋值语句把a的值从默认的初始值转为1


这是第二次循环时,进入int a = i + 1;这个语句时,a的值

这时候的a,默认就是1,不是C#里给int型变量的默认初始值,是第一次循环结束后的值


第二次循环结束后,又一次执行了赋值语句,a的值为2

 

a在每一次循环,指向的内存单元是相同的,所以每一次循环,a对应的内存单元里的值,应该都是上一次循环的值

就是,int a = i;相当于声明和赋值两个语句:
int a;
a = i;
而第一句声明,C#默认是给Int型设置初始值为0的,所以,如果第二次循环里,有重复声明a变量,那这个变量指向的内存单元里的值应该是要被初始化为0的,不可能还是上一次循环结束时的值

所以,在循环内定义变量,不管循环多少次,变量只会在第一次循环时声明和分配内存,不会执行更多语句,也不会因为要声明更多的变量影响执行的时间


谁可以告诉我,怎么查看C#生成的最终代码啊?用调试里的汇编查到的东西,不是最终的代码。。。我想要知道这两段

int a;
for (int i = 0; i < 3; i++)
{
    a = i;
}

for (int i = 0; i < 3; i++)
{
    int a = i;
}

生成的最终代码是不是完全相同的。。。

小楼宝宝的涂鸦花花(Imitater)的博客起名称骨测字皖ICP备06000023号-17