Menu

C# for Loop: Syntax, Counting Down, Nested Loops and Pitfalls

How the C# for loop works: the initializer, condition and iterator, counting down and stepping, several loop variables, looping over arrays by index, nested loops, for(;;), and the off-by-one and remove-while-iterating bugs.

This page includes runnable editors - edit, run, and see output instantly.

A for loop repeats a block while a condition is true, with the setup and the step written in the loop header. It is the loop to use when you count: a fixed number of repetitions, or every index of an array.

Output:

Lap 1 of 5
Lap 2 of 5
Lap 3 of 5
Lap 4 of 5
Lap 5 of 5

How the Three Parts Run

for (initializer; condition; iterator) executes in a fixed order:

  1. The initializer (int i = 1) runs once, before anything else.
  2. The condition (i <= 5) is checked. If it is false, the loop ends and the body never runs again.
  3. The body runs.
  4. The iterator (i++) runs, then control goes back to step 2.

Because the condition is checked before each iteration, a for loop can run zero times: for (int i = 10; i < 5; i++) never enters its body. The loop above behaves like this while loop:

int i = 1;
while (i <= 5)
{
    Console.WriteLine($"Lap {i} of 5");
    i++;
}

The two forms differ in one detail: continue inside a for body still runs the iterator, while in this while version it would jump over i++, so the loop would test the same i again and could spin forever. A variable declared in the initializer only exists inside the loop. If you need its final value afterwards, declare it before the loop: int i; for (i = 0; ...; i++) { }.

Counting Down and Stepping

The iterator can be any expression. Decrement to count down, add more than one to step, or multiply for a geometric sequence:

Output:

3... 2... 1... liftoff
 00 15 30 45
 1 10 100 1000

Make sure the iterator moves toward making the condition false. for (int i = 0; i < 10; i--) counts away from 10 and only stops when i wraps around after two billion iterations.

Looping Over an Array by Index

Arrays expose Length, lists expose Count, and valid indexes run from 0 to one less than that. The index gives you something foreach does not: access to the position, the neighbors, and the right to write back.

Output:

#1: 17.99
#2: 4.50
#3: 38.25
#4: 7.43
item 1 vs item 0: down
item 2 vs item 1: up
item 3 vs item 2: down

The last loop starts at 1 because it compares each element with the one before it. The arrays page covers creating, sorting and copying arrays themselves.

Several Loop Variables

The initializer can declare several variables of the same type, and the iterator can update several, separated by commas. The classic use is two indexes walking toward each other:

Output:

racecar is a palindrome: True
9, 1, 8, 3

Both variables must share one type in a single declaration: int left = 0, right = 10 works, int i = 0, string s = "" does not.

Nested Loops

A loop inside a loop runs its whole range once per iteration of the outer loop. Tables and grids are the typical case:

Output:

   1   2   3   4
   2   4   6   8
   3   6   9  12
   4   8  12  16

The inner body runs 16 times (4 × 4). Nesting multiplies work quickly: two nested loops over 10,000 items each is 100 million iterations. A break in the inner loop only leaves the inner loop; the break and continue page shows how to leave both.

Infinite Loops: for(;;)

All three parts of the header are optional. With no condition, the loop runs until something inside it leaves:

Output:

Month 1: 70 left
Month 2: 40 left
Month 3: 10 left
Overdrawn in month 4: -20

for (;;) and while (true) compile to the same thing; pick whichever your codebase uses.

Off-by-One Errors

The most common for bug is a condition that goes one step too far:

Output:

Ada
Grace
Linus
IndexOutOfRangeException at index 3

An array of 3 has indexes 0, 1 and 2, so i < names.Length is the right condition. The mirror bug is counting down with i > 0, which never visits index 0. On a List<T>, the same mistake throws ArgumentOutOfRangeException instead.

Removing Items While Looping

Removing from a List<T> inside a forward loop shifts every later element one position down, so the loop skips the element right after each removal:

Output:

forward:  5, 0, 3, 7
backward: 5, 3, 7

The forward loop left a 0 behind: after removing index 1, the second zero moved into index 1, but i++ had already moved on to index 2. Looping backwards avoids it because removals only shift elements you have already visited. For a one-line alternative, stock.RemoveAll(x => x == 0) does the same thing. A foreach loop does not allow removal at all; it throws InvalidOperationException.

Floating-Point Counters

Avoid double loop counters that test for equality. 0.1 has no exact binary representation, so adding it ten times does not produce exactly 1.0:

for (double x = 0; x != 1.0; x += 0.1)   // never ends: x skips past 1.0
{
}

Count with an integer and compute the value from it instead: for (int i = 0; i <= 10; i++) { double x = i / 10.0; }.

for Versus foreach

NeedUse
Read every element in orderforeach
The index, or neighbors (i - 1, i + 1)for
Assign into an array elementfor
Step by 2, go backwardsfor
Remove from a List while loopingfor, backwards
A collection without an indexer (HashSet, Dictionary, LINQ results)foreach
Repeat something N times, no collectionfor

On arrays, both loops compile to essentially the same code, so pick by readability, not speed.

Frequently Asked Questions

What is the syntax of a for loop in C#?

for (initializer; condition; iterator) { body }, for example for (int i = 0; i < 5; i++) { ... }. The initializer runs once, the condition is checked before every iteration, and the iterator runs after every iteration. The loop ends the first time the condition is false.

How do I loop backwards in C#?

Start at the last index and decrement: for (int i = items.Length - 1; i >= 0; i--). Note >= 0, not > 0, or the first element is skipped. Looping backwards is also the safe way to remove items from a List while iterating.

When should I use for instead of foreach in C#?

Use for when you need the index (to compare neighbors, write back into an array, or step by more than one), when you count rather than walk a collection, or when you remove items from a list. Use foreach to read every element in order; it is shorter and has no index to get wrong.

How do I write an infinite loop in C#?

for (;;) { ... } or while (true) { ... }. All three parts of a for header are optional, and a missing condition counts as true. Leave the loop with break or return when your exit condition is met.

Why do I get IndexOutOfRangeException in my for loop?

The condition lets the index reach the length: i <= array.Length visits array[array.Length], one past the last element. Valid indexes run from 0 to Length - 1, so the condition should be i < array.Length (or i < list.Count for a List, which throws ArgumentOutOfRangeException instead).

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED