内存分析

本文通过分析代码实例,详细解释了数组赋值与交换排序过程中出现的错误原因,并通过内存分析法解决了问题。强调了仔细阅读代码的重要性及避免数据重复赋值的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    这是一段代码:

public class TestArray
{
	public static void main(String[] args)
	{
		//声明一个长度和args数组一样的数组b
 		int[] b = new int[args.length];
	 	//交换数据用的临时变量
		int temp;

		//遍历
		for(int i=0;i<args.length;i++)
		{
			//将args数组中的数据依次赋给b[i]
			b[i]=Integer.parseInt(args[i]);     //出现问题是从这里开始的
			//遍历,从i+1开始遍历,
			for(int j=i+1;j<args.length;j++)
			{
				 //比较大小
				if(b[i]>b[j])
				{
					//不是从小到大,就交换顺序
 					temp=b[i];
 					b[i]=b[j];
 					b[j]=temp;
 				}
			}
			//将调整好顺序的数组b依次打印出来
			System.out.print(b[i]+" ");
		}
	}

}

运行效果如下:

 

          奇怪,不对啊,我要的效果应该是输出2 3 4 5.怎么变成0 0 0 3了?

       从头到尾看一遍代码,声明变量略过,从遍历开始,运行将5 2 4 3赋到b[]上,所以b[0]=5,b[1]=2;b[2]=4;b[3]=3;然后比较b[0]和b[1],b[2],b[3];第一轮由于b[0]>b[1],所以交换b[0]=2,b[1]=5;然后b[0]=2,就比b[2],b[3]小了,就不用交换,照这样下去,可以得到结果的啊,为什么出了0 0 0 3这种结果?

      在这段代码中间加上System.out.print打印出来,

temp=b[i];
b[i]=b[j];
b[j]=temp;

变成这样

System.out.println("b[j]=" + b[j]);
System.out.println("b[i]=" + b[i]);
temp=b[i];
System.out.println("temp=" + temp);
b[i]=b[j];
System.out.println("b[i]=" + b[i]);
b[j]=temp;
System.out.println("b[j]=" + b[j]);
System.out.println("");

 

    发现b[j]从最开始的时候就一直都是0.为什么b[j]没有赋上值呢?一想循环的时候,第一轮循环i=0,只给了b[0]赋值,b[1]还没有赋值.所以修改代码变为

//遍历,从i+1开始遍历,
for(int j=i+1;j<args.length;j++)
{
        //将args数组中的数据依次赋给b[j]
        b[j]=Integer.parseInt(args[j]);   //添加这条语句
        //比较大小
        if(b[i]>b[j])
        {
                //不是从小到大,就交换顺序
                temp=b[i];
                b[i]=b[j];
                b[j]=temp;
        }

}

      然后运行效果就是这个样子了,

    还是不对.问题出在了哪?没想通,试着用内存分析来解决这个问题.

    输入还是5 2 4 3,这是第一轮循环结束的样子.第一轮挺正常的

    一开始的时候args数组是有5 2 4 3,这几个值的;但是b数组最开始是全为0的.然后执行遍历中的这条语句,

           b[i]=Integer.parseInt(args[i]);

    将args[0]中的值赋值到了b[0]中,所以b[0]=5了,而执行这条语句

           b[j]=Integer.parseInt(args[j]),b[1]=2;

    比较b[0],b[1],交换,所以b[0]变成2,而b[1]变成5;后面由于b[0]=2<4,2<3;不用执行.

    这是第二轮结束的样子.问题出现了

    由于这两条语句,

     b[i]=Integer.parseInt(args[i]);

     b[j]=Integer.parseInt(args[j]),所以

     b[1]=args[1]=2;b[2]=args[2]=4;

                    b[3]=args[3]=3;

     由于2<4,2<3,所以不用交换.其中b[1]重新指向了args[1]变成了2,而实际我要的应该是上一轮调整好的b[1]=5才对.

    从这里发现,不应该再执行一次b[i]=Integer.parseInt(args[i]),b[1]=args[1]=2,b数组中的数据应该是已经赋值好了,然后直接进行比较即可.

    所以代码变为这样,有两次for循环,第一次将args上的数据全都赋值到b数组上,这样就不会再被args赋值一次.所以b[j]=Integer.parseInt(args[j])这条语句也是多余的,不能让b中的值再被args覆盖掉.

//遍历args,将所有的值依次赋值到b上
for(int i=0;i<args.length;i++)
{
        b[i]=Integer.parseInt(args[i]);   //差不多就是修改了这里
}

//遍历
for(int i=0;i<args.length;i++)
{
        //遍历,从i+1开始遍历,
        for(int j=i+1;j<args.length;j++)
        {
                //比较大小
                if(b[i]>b[j])
                {
                        //不是从小到大,就交换顺序
                        temp=b[j];
                        b[j]=b[i];
                        b[i]=temp;
                }
        }
        //将调整好顺序的数组b依次打印出来
        System.out.print(b[i]+" ");
}

最后的运行效果:

 

     最后,以前这些代码我总是不敲,看完就觉得自己会了.可是实际上自己敲,就会出现一些很奇怪的问题.就像这段代码,语句基本都是对的,但是for循环没整明白.

    在这里,比如执行这条语句,b[i]=Integer.parseInt(args[i]),我发现我会想当然的以为args数组上的所有数据都依次赋值上去了.但实际他每一次for循环执行一次,后面的根本还没赋上值.所以我只看代码,始终也没发现代码有什么问题.

    所以出现问题,静下心来,用用内存分析的法子,也许就能清楚明白问题在哪了,那么问题也就能迎刃而解了.   

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值