C# For Loop

A for loop repeats a block of C# code while keeping the loop setup, stopping condition, and update in one compact line. It is most useful when you know the shape of the repetition before the loop starts: count from one number to another, visit each array index, or run a fixed number of attempts. A well-written for loop makes the loop’s progress easy to see.

Overview: How For Loops Work

C# executes statements from top to bottom, but a for loop redirects execution back to the same block until its condition becomes false. Unlike a while loop, which puts only the condition in the loop header, a for loop usually places three related pieces in the header: an initializer, a condition, and an iterator. This makes it a natural choice for counter-based repetition.

The initializer runs once before the first condition check. It often declares a loop variable, such as int i = 0. The condition is a bool expression checked before every iteration. If it is true, the loop body runs. After the body finishes, the iterator runs, commonly i++ or i += 2. Then C# checks the condition again.

A for loop is a pre-test loop, so its body can run zero times. For example, for (int i = 10; i < 5; i++) never enters the body because the condition is false from the start. This behavior is important when looping over arrays or lists that might be empty.

The loop variable declared in the initializer is scoped to the loop. In for (int i = 0; i < 3; i++), the name i exists in the loop header and body, but not after the loop ends. That narrow scope prevents accidental reuse later. If a value must be available after the loop, declare it before the loop.

Under the hood, the C# compiler turns a for loop into branching instructions in Intermediate Language. The CLR does not store all iterations or create hidden copies of the body. It runs the initializer once, branches to the condition, executes the body when the condition is true, runs the iterator, and jumps back. The loop is just controlled repetition, not a collection or a background process.

Syntax

for (int i = 0; i < 3; i++)
{
    // statements to repeat
}
Part Meaning
int i = 0 The initializer. It runs once before the loop starts and creates a counter.
i < 3 The condition. It is checked before each iteration, and the body runs only while it is true.
i++ The iterator. It runs after each completed iteration and moves the counter forward.
{ } The loop body. These statements repeat while the condition remains true.

All three header sections are optional, but the semicolons are required. For example, for (;;) is an infinite loop. In normal beginner and production code, include all three parts unless there is a clear reason not to.

Examples

Counting with a For Loop

using System;

class Program
{
    static void Main()
    {
        for (int number = 1; number <= 5; number++)
        {
            Console.WriteLine(number);
        }

        Console.WriteLine("Done");
    }
}

Output:

1
2
3
4
5
Done

The initializer creates number with the value 1. The condition allows the body to run while number <= 5. After each print, the iterator number++ increases the counter by one. When number becomes 6, the condition is false and execution continues after the loop.

Looping Through an Array by Index

using System;

class Program
{
    static void Main()
    {
        string[] names = { "Ava", "Ben", "Chloe" };

        for (int index = 0; index < names.Length; index++)
        {
            Console.WriteLine($"{index}: {names[index]}");
        }
    }
}

Output:

0: Ava
1: Ben
2: Chloe

Arrays use zero-based indexing, so the first element is at index 0 and the last element is at Length - 1. The condition index < names.Length is the standard safe boundary. A foreach loop is often simpler when you only need the values, but a for loop is appropriate when the index matters.

Calculating a Running Total

using System;

class Program
{
    static void Main()
    {
        int[] scores = { 82, 91, 77, 100 };
        int total = 0;

        for (int i = 0; i < scores.Length; i++)
        {
            total += scores[i];
            Console.WriteLine($"After score {i + 1}: {total}");
        }

        double average = (double)total / scores.Length;
        Console.WriteLine($"Average: {average:F1}");
    }
}

Output:

After score 1: 82
After score 2: 173
After score 3: 250
After score 4: 350
Average: 87.5

This example keeps state outside the loop in total. Each iteration reads one score and adds it to the running total. The cast (double)total makes the division produce a fractional result instead of integer division.

Nested For Loops

using System;

class Program
{
    static void Main()
    {
        for (int row = 1; row <= 3; row++)
        {
            for (int column = 1; column <= 4; column++)
            {
                Console.Write($"{row},{column} ");
            }

            Console.WriteLine();
        }
    }
}

Output:

1,1 1,2 1,3 1,4 
2,1 2,2 2,3 2,4 
3,1 3,2 3,3 3,4 

Nested loops are loops inside loops. For each value of row, the inner column loop runs from one through four. This pattern is common for tables, grids, coordinates, and two-dimensional arrays. Be aware that nested loops multiply work: three rows times four columns means twelve inner-body executions.

How For Works Step by Step

  1. The compiler checks the initializer, condition, iterator, and body for valid C# syntax and types.
  2. The initializer runs exactly once before the first iteration.
  3. The condition is evaluated. It must be a bool expression.
  4. If the condition is false, the body is skipped and the loop is finished.
  5. If the condition is true, the body runs from top to bottom unless control flow changes.
  6. After the body, the iterator expression runs.
  7. Execution jumps back to the condition, and the cycle repeats.

break exits the nearest loop immediately. continue skips the rest of the current body and moves to the iterator step, then the condition check. In nested loops, break and continue affect only the loop they are directly inside unless you use another control-flow technique such as return.

Because the iterator runs after the body, a continue in a for loop still performs the iterator. That is different from a poorly arranged while loop, where continue can accidentally skip the statement that updates the counter.

Common Mistakes

Using the Wrong Array Boundary

string[] names = { "Ava", "Ben", "Chloe" };

for (int i = 0; i <= names.Length; i++)
{
    Console.WriteLine(names[i]);
}

This code compiles, but it throws an IndexOutOfRangeException at runtime. The final valid index is names.Length - 1, so the condition must use <, not <=.

using System;

class Program
{
    static void Main()
    {
        string[] names = { "Ava", "Ben", "Chloe" };

        for (int i = 0; i < names.Length; i++)
        {
            Console.WriteLine(names[i]);
        }
    }
}

Output:

Ava
Ben
Chloe

Changing the Counter Inside the Body

for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
    i++;
}

This compiles, but it is easy to misunderstand because i changes in two places: once inside the body and once in the iterator. The result prints only every other value. Usually, let the loop header own the counter update.

using System;

class Program
{
    static void Main()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine(i);
        }
    }
}

Output:

0
1
2
3
4

Expecting the Loop Variable After the Loop

for (int i = 0; i < 3; i++)
{
    Console.WriteLine(i);
}

Console.WriteLine(i);

This does not compile because i was declared inside the for header and is out of scope after the loop. If you need a value afterward, declare the variable before the loop.

using System;

class Program
{
    static void Main()
    {
        int i;

        for (i = 0; i < 3; i++)
        {
            Console.WriteLine(i);
        }

        Console.WriteLine($"After loop: {i}");
    }
}

Output:

0
1
2
After loop: 3

Best Practices

  • Use for when the loop has a clear counter, range, or index.
  • Use foreach when you only need each item from a collection and do not need the index.
  • Use while when the number of iterations depends on a condition that is not naturally a counter.
  • Keep the initializer, condition, and iterator simple. Move complex setup outside the loop.
  • Prefer i < array.Length for zero-based arrays and lists. Avoid <= unless you are intentionally including the final numeric value of a range.
  • Do not update the loop counter in both the header and the body unless the algorithm truly requires it.
  • Use descriptive names such as row, column, or index when they clarify the loop’s purpose.
  • Be careful with nested loops over large data. Work grows quickly because the inner loop runs once for every outer iteration.
  • Prefer braces even for a one-statement body. They make later edits less error-prone.

Practice Exercises

  1. Write a program that uses a for loop to print the even numbers from 2 through 20.
  2. Create an array of five product prices and use a for loop to calculate and print the total.
  3. Use nested for loops to print a 5 by 5 multiplication table. Hint: multiply the row number by the column number.

Summary

  • A for loop groups initialization, condition checking, and iteration in one header.
  • The initializer runs once, the condition runs before each iteration, and the iterator runs after each completed body.
  • for loops are especially useful for numeric ranges and indexed access to arrays or lists.
  • Loop variables declared in the header are scoped to the loop.
  • Common problems include off-by-one boundaries, hidden counter changes, and assuming the loop variable exists after the loop.