zoukankan      html  css  js  c++  java
  • c# for 和 while的区别

    for 用来遍历,while 也用来遍历;看是功能相同的,但如果功能相同,为啥不剔除一个呢;(而且几乎所有编程语言都有这两个循环语句)

    因为他们有不一样的地方呀,(感觉好像废话,我们还是具体看代码吧)

    相同的地方;

          public static void TestLoop1()
            {
                int loopTimes = 4;
                int i;
                
                for(i = 0; i < loopTimes; i++)
                {
                    //0
                    //1
                    //2
                    //3
                    //最后一次进来是 index=3;
    
                    //出去的时候,index 还是3
                }
                //(累加=>停止循环的时候变成了4
                
                int index = 0;
                while (index < loopTimes)
                {
                    //0
                    //1
                    //2
                    //3
                    //最后一次进来 index=3;
                    index++;
                   //累加 然后出去,index=4; 然后不满足条件;退出循环;
                    
                }
                //眨眼一看,上面的写法没什么区别; BUT i 的叠加是在 {} 外部进行的,  index 的叠加是在 {} 内部进行的;
    }

    上面的写法,在开发中会遇到不同的问题,比如:

                //眨眼一看,上面的写法没什么区别; BUT i 的叠加是在 {} 外部进行的,  index 的叠加是在 {} 内部进行的;
                //这样会出现什么问题呢;
                Console.WriteLine("我们来遍历一次数组,就知道了");
                Console.WriteLine("for.......");
                var arr = new int[] {1,2,3,4};
                int len = arr.Length;
                for(int j = 0; j < len; j++)
                {
                    Console.WriteLine(arr[j]);
                    //这个数绝对安全的;
                }
    
                Console.WriteLine("while.....");
                int k = 0;
                while (k < len)
                {
                    //k++; 如果k++放在前面,无法比那里k=0 这个数组不说,还会发生数组越界的异常;
                    Console.WriteLine(arr[k]);
                    k++;
                    
                }
    
                Console.WriteLine("finall k index;"+k);  //最后这个index 会变成4 所以这样比那里数组是不安全的;
    
                //你以为区别就这一点吗? 太年轻了,接着看;

    不同的地方;

            static void ForVSWhile()
            {
    
                var arr=new []{ 1,2,4,5,6};
                int len = arr.Length;
                int target = 4;
                for (int i = 0; i < len; i++)
                {
                    if (arr[i] == target)
                    {
                        break;
                    }
                }
    
                //这个就相当于我们的while;
                int index = 0;
                while (arr[index] == target)  //找到我们想要的元素后,就立马停止;
                {
                    index++;
                }
    
            }

    不过,你也可以把他们写来一样,不过,感觉好别扭;

                var arr=new []{ 1,2,4,5,6};
                int len = arr.Length;
                int target = 4;
                for (int i = 0; i < len && arr[i] == target;  i++)
                {
                 
                }

    我们再来看一个容易出错的地方;

            /// <summary>
            /// 找出数组中小于target的值;
            /// 这个问题,我在快速排序的时候遇到的一个死循环;
            /// </summary>
            public static void TestLoop2()
            {
                var arr = new int[] { 1,2,1};
                int len = arr.Length;
                int target = 2;
                List<int> list = new List<int>(3); 
                List<int> list1 = new List<int>(3); 
    
    
                // 常规写法;
                for(int j = len-1; j>=0; j--)
                {
                    if (arr[j] < target)
                    {
                        list.Add(arr[j]);
                    }
                }
               
    
                Console.WriteLine("while写法的结果--------------:");  //index=2;
                int k = len-1;
                //因为 arr[1]=2   不满足条件,然后就退出了循环;并没有遍历我们的整个数组;
                //并没有把我们的数组遍历完;
                while (arr[k] < target) 
                {
                     list1.Add(arr[k]);
                      k--;
                }
            }

    其实,对这个问题的总结,来自我们的快速排序时,遇到的一个问题;

            static void TestLoop()
            {
                //在快速排序的过程中遇到一个问题;
                var arr = new[] { 5, 4,1 };
                int len = arr.Length;
                int high = len - 1;
                int low = 0;
                int middle = arr[1];
    
                while (low < high)
                {
                    while (arr[high] > middle  && low<high)
                    {
                        high--;
                    }
    
                    while (arr[low] < middle && low < high)
                    {
                        low++;
                    }
                }
    
               //高地址 middle=4 high=2; arr[2]=1 找到了小于 middle 的值; 这时候,我们的high=2;
               //底地址 middle=4 low=0;  arr[0]=5;找到了大于 middle 的值; 这时候  我们的low=0;
              // 这个时候,进行交换 arr[2] 和 arr [0]  数组变了 1 4 5
              // 但是 关键来了!!!!!!!!!!!!!!!
              // 进行寻址之后 我们的 high 和 low 没有 进行 递减 和 递增的操作, high还是2 low 还是 0
              //这样就形成了我们的死循环;窝草;
              //这样就被迫,我去思考一些基础性的问题;之前也遇到过 如 ++i 和 i++; 如 for 循环 和while 循环的区别;
            }

    然后,这里我们再来复习一个非常简单的额问题;i++; 和 ++i;

    i++; 先进行赋值,然后再进行累加;

    我们来看一个以此产生的死循环;

            /// <summary>
            /// 如果这样写,tad的就变成了死循环哈
            /// </summary>
            /// <param name="n"></param>
            static void TestRecursion(int n)
            {
                if (n > 0)
                {
                    Console.WriteLine(n);
                    TestRecursion(n--); //先将n进行函数赋值进行运算,然后再n--;如果这样搞就是死循环啊;
                }
            }

    fix(这样就好了)

            /// <summary>
            /// 如果这样写,tad的就变成了死循环哈
            /// </summary>
            /// <param name="n"></param>
            static void TestRecursion2(int n)
            {
                if (n > 0)
                {
                    Console.WriteLine(n);
                    TestRecursion2(--n); //先将n进行函数赋值进行运算,然后再n--;如果这样搞就是死循环啊;
                }
            }

    然后,我们再来看一个取值的问题;

            static void TestWhile()
            {
                var arr = new[] {1,2,3,4};
                int len = arr.Length;
                var newArr = new int[len];
                int index = 0;
    
                var newArr1 = new int[len];
                int index1 = 0;
    
    
                for (int i = 0; i < len; i++)
                {
                    if (arr[i] % 2 == 0)
                    {
                        
                        newArr[++index] = arr[i]; //从结果中可以看出,++i 是先累加,在赋值
                        newArr1[index1++] = arr[i]; //从结果中可以看出,i++ 是先赋值,在累加
    
                    }
                }
    
                //然后我们来看这两个的区别;
                Console.WriteLine("++index");
                foreach (int i in newArr)
                {
                    Console.WriteLine(i);
                }
    
                Console.WriteLine("index++");
                foreach (int i in newArr1)
                {
                    Console.WriteLine(i);
                }
    
    
            }

    结果:

    然后,我们看看,在while 中应用,主要是是在我们的快速排序中;也就是修复我们前面那个快速排序中的死循环;

            static void TestLoop()
            {
                //在快速排序的过程中遇到一个问题;
                var arr = new[] { 5, 4,1 };
                int len = arr.Length;
                int high = len - 1;
                int low = 0;
    
                //这里写个重负代码,主要为了,看得清楚一点;
                high = high + 1;
                low = low - 1;
    
                int middle = arr[1];
    
                while (low < high)
                {
                    while (arr[--high] > middle  && low<high)  //先尽心一次自减。再取值;
                    {
                        int xx = 0;
                    }
    
                    while (arr[++low] < middle && low < high) ////先尽心一次自加。再取值; //这样,保证,我们每一次遍历,都在前进;就想我们的for循环;知道low 遇到我们的i
                    {
                        int xx = 0;
                    }
    
    
                }

    然后,我们再来看一个具体的实例优化;找到元素应该插入的位置;如:target =2; 在 0 1 中,应该插入的位置就是2;如果用for来实现;则会出现如下的代码;

     /// <summary>
            /// 找到元素应该在的正确元素;
            /// 考虑下面三种情况;
            /// 1.数组长度就是1;
            /// 2.找完了,都没找到;
            /// 找到,应该插入的位置;。。。shit优化;
            /// </summary>
            public static int FindRightPostion(int [] arr,int target)
            {
                int len = arr.Length;
                int position =0;  //如果没有找到,就应该在第一个位置;最后一个步,却加了1,这样。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。、
                bool isFind = false;
                //正向寻找;
                for(int i = 0; i < len; i++)
                {
                    //最后一次没有进来;对,i就是我们的待插入的位置;不过,最后一次的条件没有进来;
                    if (arr[i]<target)  //最后一个找到,肯定是不满足条件的的;
                    {
                        position = i; //不满足条件的值,没有进入这个赋值;所以,最后合适的位置就是;position+1
                        isFind = true;
                    }
                    else
                    {
                        break;
                    }
                }
                if (isFind == false)
                    return position;
                else
                return position+1;
            }
    
            /// <summary>
            /// 这种方式也不错滴啊;
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="target"></param>
            /// <returns></returns>
            public static int FindRightPostion2(int[] arr, int target)
            {
                int len = arr.Length;
                int position = 0;  
                for (int i = 1; i < len; i++)
                {
                    if (arr[i] < target) 
                    {
                        position = i; 
                    }
                    else
                    {
                        break;
                    }
                }
                return position == 0 ? 0 : position + 1;
            }

    然后,如果用我们的while 来实现,这样的方式,代码,好了很多;(这样,就完美多了)

            /// <summary>
            /// 这样写,比较合适,出来的时候,pointer 恰好;执向的是下一个位置;
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="target"></param>
            /// <returns></returns>
            public static int FindeRightPostion(int [] arr,int target)
            {
                int len = arr.Length;
                int pointer = 0;
                while (pointer < len && arr[pointer] < target)
                {
                    pointer++;
                }
                return pointer;
    
            }

    总结:for 循环,更多用于一个完整的遍历; while 更多是带有终止条件的遍历;

  • 相关阅读:
    Git_创建版本库
    Git_安装Git
    Git_集中式vs分布式
    Git_git的诞生
    echartShow
    微信小程序红包开发 小程序发红包 开发过程中遇到的坑 微信小程序红包接口的
    vue2.0 $router和$route的区别
    vue移动端开发全家桶
    干货分享:vue2.0做移动端开发用到的相关插件和经验总结
    优秀的基于VUE移动端UI框架合集
  • 原文地址:https://www.cnblogs.com/mc67/p/8242504.html
Copyright © 2011-2022 走看看