#159 – A while Loop Might Execute Forever

If the boolean expression that controls a while loop never evaluates to false, the loop might continue to execute indefinitely.  This is known as an infinite loop.

You might create an infinite loop by design, or it might in fact be a programming error.  The only way to end an infinite loop is to kill the parent process.

In the following example, we just use the value of true for the loop expression, so that the loop will continue to execute indefinitely.

            uint digit = 1;

            while (true)
            {
                CalculateNthDigitOfPi(digit);
                RecordNthDigitOfPi(digit);
                digit++;
            }

In the example below, we intend for Sisyphus to roll his rock up the hill ten times.  We intend to decrement the numRolls variable, but mistakenly increment it.  This leads to an infinite loop, with Sisyphus doomed to roll his rock up the hill forever.

            uint numRolls = 10;

            while (numRolls > 0)
            {
                SisyphusRollRockUphill();
                numRolls++;
            }
Advertisements

#158 – A while Loop Expression Is Evaluated Before Executing the Loop

Because the expression used in a while loop is tested before the loop is executed, it’s possible that the loop won’t be executed at all.

In the following example, we count the number of leaves on our lawn and then only rake and bag if we see more than 50 leaves.  When done filling a bag, we count again and then go back to the top of the loop, where we’ll decide whether we should keep raking.  It’s possible, however, that the lawn is empty of leaves to start with and in that case, we wouldn’t execute the loop at all.

            numLeavesOnLawn = CountLeaves();
            while (numLeavesOnLawn > 50)
            {
                RakeLeaves();
                FillNextBag();
                numLeavesOnLawn = CountLeaves();
            }

#157 – Iterating Using the while Loop

The while loop allows you to execute a single statement or block of code 0 or more times, continuing to execute while a particular expression evaluates to true.  The expression can be a single boolean variable or a more complicated expression that evaluates to a boolean result.

Here’s an example.

            bool keepPlaying = true;

            // Display trivia until user wants to quit
            while (keepPlaying)
            {
                DisplaySomeTrivia();
                keepPlaying = AskUserIfTheyWantToContinue();
            }

The braces denote the block of code that will be executed repeatedly.  Since the keepPlaying variable starts out true, the code will be executed at least once.  AskUserIfTheyWantToContinue will ask the user if they want to continue and return a true or false value.  So the loop will execute until the user decides to stop.

Another example:

            int numTimesPrinted = 0;

            // Print something out 100 times
            while (numTimesPrinted < 100)
            {
                Console.WriteLine("I will not pull Sally's pigtails");
                numTimesPrinted++;
            }

#156 – Using break and continue in foreach Loops

When iterating through array elements using the foreach statement, you can use the break statement to break out of the loop–when break is encountered, control is transferred to the code immediately following the loop and no more array elements will be processed.

            foreach (Person p in folks)
            {
                Console.WriteLine("{0} {1}", p.FirstName, p.LastName);

                // If we find Elvis, stop the presses
                if (p.FirstName == "Elvis")
                    break;
            }

The continue statement, when encountered in a foreach loop, causes control to transfer back to the top of the loop and move on to the next element.

            foreach (Person p in folks)
            {
                // Don't print out info for any Adolfs; move to the next person
                if (p.FirstName == "Adolf")
                    continue;

                Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
            }

#155 – Iterating Through an Array Using the foreach Statement

You can write a loop–a block of code that is executed more than once–that executes once for each element in an array, using the C# foreach statement.

The foreach statement declares a variable local to the loop of the same type of the elements in the array.  This variable takes on the value of each element in the array.

            Person[] folks = new Person[4];
        	folks[0] = new Person("Bronte", "Emily");
	        folks[1] = new Person("Bronte", "Charlotte");
	        folks[2] = new Person("Tennyson", "Alfred");
	        folks[3] = new Person("Mailer", "Norman");

            string sLastNameList = "";

            // For each Person in array, dump out name and concatenate last name
            foreach (Person p in folks)
            {
                Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
                sLastNameList += p.LastName;
            }

#154 – Using an Invalid Array Index Causes an Exception to Be Thrown

If you try to reference an array element using an index that is outside the declared range of the array, an IndexOutOfRangeException exception will be thrown.

            int[] scores = { 88, 99, 79, 88};
            Console.WriteLine("5th element? - {0}", scores[4]);    // IndexOutOfRangeException

#153 – Returning a Subset of Array Elements Matching a Particular Criteria

Because System.Array implements the IEnumerable interface and because LINQ extends IEnumerable, you can use the IEnumerable.Where method on arrays to find a subset of elements that match a particular criteria.

The Where method accepts a delegate to a function that takes a single element of the same type as the array and returns a boolean value, indicating whether a match is found.  Where returns an IEnumerable collection, which can be iterated on to get the elements in the subset.

Here’s an example, finding the set of passing scores in a set of scores.

            int[] scores = { 89, 98, 72, 100, 68 };

            // Count number of passing grades
            int numPassed = scores.Where((Func<int,bool>)IsPassingGrade).Count();

Here’s the implementation of IsPassingGrade.

        static bool IsPassingGrade(int score)
        {
            return (score >= 75);
        }

You can avoid defining a separate function by using a lamba expression.

            int numPassed = scores.Where(s => s >= 75).Count();

Similar to Array.FindAll.